diff --git a/[refs] b/[refs] index 7c48ff04444b..83aebf80a1e4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ff0972c26bbf209da6f6d244cce60e695df863f6 +refs/heads/master: 9455e4c9abf76fa02170743859b2ddbb484e7fdf diff --git a/trunk/Documentation/HOWTO b/trunk/Documentation/HOWTO index 1d6560413cc5..915ae8c986c6 100644 --- a/trunk/Documentation/HOWTO +++ b/trunk/Documentation/HOWTO @@ -358,8 +358,7 @@ Here is a list of some of the different kernel trees available: quilt trees: - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ - - x86-64, partly i386, Andi Kleen - ftp.firstfloor.org:/pub/ak/x86_64/quilt/ + Bug Reporting ------------- diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index bf56b20652b0..611acc32fdf5 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -217,6 +217,14 @@ Who: Nick Piggin --------------------------- +What: Support for the MIPS EV96100 evaluation board +When: September 2006 +Why: Does no longer build since at least November 15, 2003, apparently + no userbase left. +Who: Ralf Baechle + +--------------------------- + What: Support for the Momentum / PMC-Sierra Jaguar ATX evaluation board When: September 2006 Why: Does no longer build since quite some time, and was never popular, diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index 7db71d6fba82..99902ae6804e 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -1124,15 +1124,11 @@ debugging information is displayed on console. NMI switch that most IA32 servers have fires unknown NMI up, for example. If a system hangs up, try pressing the NMI switch. -nmi_watchdog ------------- - -Enables/Disables the NMI watchdog on x86 systems. When the value is non-zero -the NMI watchdog is enabled and will continuously test all online cpus to -determine whether or not they are still functioning properly. - -Because the NMI watchdog shares registers with oprofile, by disabling the NMI -watchdog, oprofile may have more registers to utilize. +[NOTE] + This function and oprofile share a NMI callback. Therefore this function + cannot be enabled when oprofile is activated. + And NMI watchdog will be disabled when the value in this file is set to + non-zero. 2.4 /proc/sys/vm - The virtual memory subsystem diff --git a/trunk/Documentation/kbuild/makefiles.txt b/trunk/Documentation/kbuild/makefiles.txt index e2cbd59cf2d0..b7d6abb501a6 100644 --- a/trunk/Documentation/kbuild/makefiles.txt +++ b/trunk/Documentation/kbuild/makefiles.txt @@ -421,11 +421,6 @@ more details, with real examples. The second argument is optional, and if supplied will be used if first argument is not supported. - as-instr - as-instr checks if the assembler reports a specific instruction - and then outputs either option1 or option2 - C escapes are supported in the test instruction - cc-option cc-option is used to check if $(CC) supports a given option, and not supported to use an optional second option. diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 255ec535bba8..766abdab94e7 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -573,6 +573,8 @@ running once the system is up. gscd= [HW,CD] Format: + gt96100eth= [NET] MIPS GT96100 Advanced Communication Controller + gus= [HW,OSS] Format: ,,, @@ -1238,11 +1240,7 @@ running once the system is up. bootloader. This is currently used on IXP2000 systems where the bus has to be configured a certain way for adjunct CPUs. - noearly [X86] Don't do any early type 1 scanning. - This might help on some broken boards which - machine check when some devices' config space - is read. But various workarounds are disabled - and some IOMMU drivers will not work. + pcmv= [HW,PCMCIA] BadgePAD 4 pd. [PARIDE] diff --git a/trunk/Documentation/pcieaer-howto.txt b/trunk/Documentation/pcieaer-howto.txt deleted file mode 100644 index 16c251230c82..000000000000 --- a/trunk/Documentation/pcieaer-howto.txt +++ /dev/null @@ -1,253 +0,0 @@ - The PCI Express Advanced Error Reporting Driver Guide HOWTO - T. Long Nguyen - Yanmin Zhang - 07/29/2006 - - -1. Overview - -1.1 About this guide - -This guide describes the basics of the PCI Express Advanced Error -Reporting (AER) driver and provides information on how to use it, as -well as how to enable the drivers of endpoint devices to conform with -PCI Express AER driver. - -1.2 Copyright © Intel Corporation 2006. - -1.3 What is the PCI Express AER Driver? - -PCI Express error signaling can occur on the PCI Express link itself -or on behalf of transactions initiated on the link. PCI Express -defines two error reporting paradigms: the baseline capability and -the Advanced Error Reporting capability. The baseline capability is -required of all PCI Express components providing a minimum defined -set of error reporting requirements. Advanced Error Reporting -capability is implemented with a PCI Express advanced error reporting -extended capability structure providing more robust error reporting. - -The PCI Express AER driver provides the infrastructure to support PCI -Express Advanced Error Reporting capability. The PCI Express AER -driver provides three basic functions: - -- Gathers the comprehensive error information if errors occurred. -- Reports error to the users. -- Performs error recovery actions. - -AER driver only attaches root ports which support PCI-Express AER -capability. - - -2. User Guide - -2.1 Include the PCI Express AER Root Driver into the Linux Kernel - -The PCI Express AER Root driver is a Root Port service driver attached -to the PCI Express Port Bus driver. If a user wants to use it, the driver -has to be compiled. Option CONFIG_PCIEAER supports this capability. It -depends on CONFIG_PCIEPORTBUS, so pls. set CONFIG_PCIEPORTBUS=y and -CONFIG_PCIEAER = y. - -2.2 Load PCI Express AER Root Driver -There is a case where a system has AER support in BIOS. Enabling the AER -Root driver and having AER support in BIOS may result unpredictable -behavior. To avoid this conflict, a successful load of the AER Root driver -requires ACPI _OSC support in the BIOS to allow the AER Root driver to -request for native control of AER. See the PCI FW 3.0 Specification for -details regarding OSC usage. Currently, lots of firmwares don't provide -_OSC support while they use PCI Express. To support such firmwares, -forceload, a parameter of type bool, could enable AER to continue to -be initiated although firmwares have no _OSC support. To enable the -walkaround, pls. add aerdriver.forceload=y to kernel boot parameter line -when booting kernel. Note that forceload=n by default. - -2.3 AER error output -When a PCI-E AER error is captured, an error message will be outputed to -console. If it's a correctable error, it is outputed as a warning. -Otherwise, it is printed as an error. So users could choose different -log level to filter out correctable error messages. - -Below shows an example. -+------ PCI-Express Device Error -----+ -Error Severity : Uncorrected (Fatal) -PCIE Bus Error type : Transaction Layer -Unsupported Request : First -Requester ID : 0500 -VendorID=8086h, DeviceID=0329h, Bus=05h, Device=00h, Function=00h -TLB Header: -04000001 00200a03 05010000 00050100 - -In the example, 'Requester ID' means the ID of the device who sends -the error message to root port. Pls. refer to pci express specs for -other fields. - - -3. Developer Guide - -To enable AER aware support requires a software driver to configure -the AER capability structure within its device and to provide callbacks. - -To support AER better, developers need understand how AER does work -firstly. - -PCI Express errors are classified into two types: correctable errors -and uncorrectable errors. This classification is based on the impacts -of those errors, which may result in degraded performance or function -failure. - -Correctable errors pose no impacts on the functionality of the -interface. The PCI Express protocol can recover without any software -intervention or any loss of data. These errors are detected and -corrected by hardware. Unlike correctable errors, uncorrectable -errors impact functionality of the interface. Uncorrectable errors -can cause a particular transaction or a particular PCI Express link -to be unreliable. Depending on those error conditions, uncorrectable -errors are further classified into non-fatal errors and fatal errors. -Non-fatal errors cause the particular transaction to be unreliable, -but the PCI Express link itself is fully functional. Fatal errors, on -the other hand, cause the link to be unreliable. - -When AER is enabled, a PCI Express device will automatically send an -error message to the PCIE root port above it when the device captures -an error. The Root Port, upon receiving an error reporting message, -internally processes and logs the error message in its PCI Express -capability structure. Error information being logged includes storing -the error reporting agent's requestor ID into the Error Source -Identification Registers and setting the error bits of the Root Error -Status Register accordingly. If AER error reporting is enabled in Root -Error Command Register, the Root Port generates an interrupt if an -error is detected. - -Note that the errors as described above are related to the PCI Express -hierarchy and links. These errors do not include any device specific -errors because device specific errors will still get sent directly to -the device driver. - -3.1 Configure the AER capability structure - -AER aware drivers of PCI Express component need change the device -control registers to enable AER. They also could change AER registers, -including mask and severity registers. Helper function -pci_enable_pcie_error_reporting could be used to enable AER. See -section 3.3. - -3.2. Provide callbacks - -3.2.1 callback reset_link to reset pci express link - -This callback is used to reset the pci express physical link when a -fatal error happens. The root port aer service driver provides a -default reset_link function, but different upstream ports might -have different specifications to reset pci express link, so all -upstream ports should provide their own reset_link functions. - -In struct pcie_port_service_driver, a new pointer, reset_link, is -added. - -pci_ers_result_t (*reset_link) (struct pci_dev *dev); - -Section 3.2.2.2 provides more detailed info on when to call -reset_link. - -3.2.2 PCI error-recovery callbacks - -The PCI Express AER Root driver uses error callbacks to coordinate -with downstream device drivers associated with a hierarchy in question -when performing error recovery actions. - -Data struct pci_driver has a pointer, err_handler, to point to -pci_error_handlers who consists of a couple of callback function -pointers. AER driver follows the rules defined in -pci-error-recovery.txt except pci express specific parts (e.g. -reset_link). Pls. refer to pci-error-recovery.txt for detailed -definitions of the callbacks. - -Below sections specify when to call the error callback functions. - -3.2.2.1 Correctable errors - -Correctable errors pose no impacts on the functionality of -the interface. The PCI Express protocol can recover without any -software intervention or any loss of data. These errors do not -require any recovery actions. The AER driver clears the device's -correctable error status register accordingly and logs these errors. - -3.2.2.2 Non-correctable (non-fatal and fatal) errors - -If an error message indicates a non-fatal error, performing link reset -at upstream is not required. The AER driver calls error_detected(dev, -pci_channel_io_normal) to all drivers associated within a hierarchy in -question. for example, -EndPoint<==>DownstreamPort B<==>UpstreamPort A<==>RootPort. -If Upstream port A captures an AER error, the hierarchy consists of -Downstream port B and EndPoint. - -A driver may return PCI_ERS_RESULT_CAN_RECOVER, -PCI_ERS_RESULT_DISCONNECT, or PCI_ERS_RESULT_NEED_RESET, depending on -whether it can recover or the AER driver calls mmio_enabled as next. - -If an error message indicates a fatal error, kernel will broadcast -error_detected(dev, pci_channel_io_frozen) to all drivers within -a hierarchy in question. Then, performing link reset at upstream is -necessary. As different kinds of devices might use different approaches -to reset link, AER port service driver is required to provide the -function to reset link. Firstly, kernel looks for if the upstream -component has an aer driver. If it has, kernel uses the reset_link -callback of the aer driver. If the upstream component has no aer driver -and the port is downstream port, we will use the aer driver of the -root port who reports the AER error. As for upstream ports, -they should provide their own aer service drivers with reset_link -function. If error_detected returns PCI_ERS_RESULT_CAN_RECOVER and -reset_link returns PCI_ERS_RESULT_RECOVERED, the error handling goes -to mmio_enabled. - -3.3 helper functions - -3.3.1 int pci_find_aer_capability(struct pci_dev *dev); -pci_find_aer_capability locates the PCI Express AER capability -in the device configuration space. If the device doesn't support -PCI-Express AER, the function returns 0. - -3.3.2 int pci_enable_pcie_error_reporting(struct pci_dev *dev); -pci_enable_pcie_error_reporting enables the device to send error -messages to root port when an error is detected. Note that devices -don't enable the error reporting by default, so device drivers need -call this function to enable it. - -3.3.3 int pci_disable_pcie_error_reporting(struct pci_dev *dev); -pci_disable_pcie_error_reporting disables the device to send error -messages to root port when an error is detected. - -3.3.4 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); -pci_cleanup_aer_uncorrect_error_status cleanups the uncorrectable -error status register. - -3.4 Frequent Asked Questions - -Q: What happens if a PCI Express device driver does not provide an -error recovery handler (pci_driver->err_handler is equal to NULL)? - -A: The devices attached with the driver won't be recovered. If the -error is fatal, kernel will print out warning messages. Please refer -to section 3 for more information. - -Q: What happens if an upstream port service driver does not provide -callback reset_link? - -A: Fatal error recovery will fail if the errors are reported by the -upstream ports who are attached by the service driver. - -Q: How does this infrastructure deal with driver that is not PCI -Express aware? - -A: This infrastructure calls the error callback functions of the -driver when an error happens. But if the driver is not aware of -PCI Express, the device might not report its own errors to root -port. - -Q: What modifications will that driver need to make it compatible -with the PCI Express AER Root driver? - -A: It could call the helper functions to enable AER in devices and -cleanup uncorrectable status register. Pls. refer to section 3.3. - diff --git a/trunk/Documentation/x86_64/boot-options.txt b/trunk/Documentation/x86_64/boot-options.txt index 4303e0c12476..6da24e7a56cb 100644 --- a/trunk/Documentation/x86_64/boot-options.txt +++ b/trunk/Documentation/x86_64/boot-options.txt @@ -245,13 +245,6 @@ Debugging newfallback: use new unwinder but fall back to old if it gets stuck (default) - call_trace=[old|both|newfallback|new] - old: use old inexact backtracer - new: use new exact dwarf2 unwinder - both: print entries from both - newfallback: use new unwinder but fall back to old if it gets - stuck (default) - Misc noreplacement Don't replace instructions with more appropriate ones diff --git a/trunk/Documentation/x86_64/kernel-stacks b/trunk/Documentation/x86_64/kernel-stacks deleted file mode 100644 index bddfddd466ab..000000000000 --- a/trunk/Documentation/x86_64/kernel-stacks +++ /dev/null @@ -1,99 +0,0 @@ -Most of the text from Keith Owens, hacked by AK - -x86_64 page size (PAGE_SIZE) is 4K. - -Like all other architectures, x86_64 has a kernel stack for every -active thread. These thread stacks are THREAD_SIZE (2*PAGE_SIZE) big. -These stacks contain useful data as long as a thread is alive or a -zombie. While the thread is in user space the kernel stack is empty -except for the thread_info structure at the bottom. - -In addition to the per thread stacks, there are specialized stacks -associated with each cpu. These stacks are only used while the kernel -is in control on that cpu, when a cpu returns to user space the -specialized stacks contain no useful data. The main cpu stacks is - -* Interrupt stack. IRQSTACKSIZE - - Used for external hardware interrupts. If this is the first external - hardware interrupt (i.e. not a nested hardware interrupt) then the - kernel switches from the current task to the interrupt stack. Like - the split thread and interrupt stacks on i386 (with CONFIG_4KSTACKS), - this gives more room for kernel interrupt processing without having - to increase the size of every per thread stack. - - The interrupt stack is also used when processing a softirq. - -Switching to the kernel interrupt stack is done by software based on a -per CPU interrupt nest counter. This is needed because x86-64 "IST" -hardware stacks cannot nest without races. - -x86_64 also has a feature which is not available on i386, the ability -to automatically switch to a new stack for designated events such as -double fault or NMI, which makes it easier to handle these unusual -events on x86_64. This feature is called the Interrupt Stack Table -(IST). There can be up to 7 IST entries per cpu. The IST code is an -index into the Task State Segment (TSS), the IST entries in the TSS -point to dedicated stacks, each stack can be a different size. - -An IST is selected by an non-zero value in the IST field of an -interrupt-gate descriptor. When an interrupt occurs and the hardware -loads such a descriptor, the hardware automatically sets the new stack -pointer based on the IST value, then invokes the interrupt handler. If -software wants to allow nested IST interrupts then the handler must -adjust the IST values on entry to and exit from the interrupt handler. -(this is occasionally done, e.g. for debug exceptions) - -Events with different IST codes (i.e. with different stacks) can be -nested. For example, a debug interrupt can safely be interrupted by an -NMI. arch/x86_64/kernel/entry.S::paranoidentry adjusts the stack -pointers on entry to and exit from all IST events, in theory allowing -IST events with the same code to be nested. However in most cases, the -stack size allocated to an IST assumes no nesting for the same code. -If that assumption is ever broken then the stacks will become corrupt. - -The currently assigned IST stacks are :- - -* STACKFAULT_STACK. EXCEPTION_STKSZ (PAGE_SIZE). - - Used for interrupt 12 - Stack Fault Exception (#SS). - - This allows to recover from invalid stack segments. Rarely - happens. - -* DOUBLEFAULT_STACK. EXCEPTION_STKSZ (PAGE_SIZE). - - Used for interrupt 8 - Double Fault Exception (#DF). - - Invoked when handling a exception causes another exception. Happens - when the kernel is very confused (e.g. kernel stack pointer corrupt) - Using a separate stack allows to recover from it well enough in many - cases to still output an oops. - -* NMI_STACK. EXCEPTION_STKSZ (PAGE_SIZE). - - Used for non-maskable interrupts (NMI). - - NMI can be delivered at any time, including when the kernel is in the - middle of switching stacks. Using IST for NMI events avoids making - assumptions about the previous state of the kernel stack. - -* DEBUG_STACK. DEBUG_STKSZ - - Used for hardware debug interrupts (interrupt 1) and for software - debug interrupts (INT3). - - When debugging a kernel, debug interrupts (both hardware and - software) can occur at any time. Using IST for these interrupts - avoids making assumptions about the previous state of the kernel - stack. - -* MCE_STACK. EXCEPTION_STKSZ (PAGE_SIZE). - - Used for interrupt 18 - Machine Check Exception (#MC). - - MCE can be delivered at any time, including when the kernel is in the - middle of switching stacks. Using IST for MCE events avoids making - assumptions about the previous state of the kernel stack. - -For more details see the Intel IA32 or AMD AMD64 architecture manuals. diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index 758044f5e718..6189b0c28d6f 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -166,6 +166,7 @@ config X86_VISWS config X86_GENERICARCH bool "Generic architecture (Summit, bigsmp, ES7000, default)" + depends on SMP help This option compiles in the Summit, bigsmp, ES7000, default subarchitectures. It is intended for a generic binary kernel. @@ -262,7 +263,7 @@ source "kernel/Kconfig.preempt" config X86_UP_APIC bool "Local APIC support on uniprocessors" - depends on !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH) + depends on !SMP && !(X86_VISWS || X86_VOYAGER) help A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU @@ -287,12 +288,12 @@ config X86_UP_IOAPIC config X86_LOCAL_APIC bool - depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH + depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) default y config X86_IO_APIC bool - depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH + depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) default y config X86_VISWS_APIC @@ -740,7 +741,8 @@ config SECCOMP source kernel/Kconfig.hz config KEXEC - bool "kexec system call" + bool "kexec system call (EXPERIMENTAL)" + depends on EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -761,13 +763,6 @@ config CRASH_DUMP depends on HIGHMEM help Generate crash dump after being started by kexec. - This should be normally only set in special crash dump kernels - which are loaded in the main kernel with kexec-tools into - a specially reserved region and then later executed after - a crash by kdump/kexec. The crash dump kernel must be compiled - to a memory address not used by the main kernel or BIOS using - PHYSICAL_START. - For more details see Documentation/kdump/kdump.txt config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) diff --git a/trunk/arch/i386/Makefile b/trunk/arch/i386/Makefile index 7cc0b189b82b..3e4adb1e2244 100644 --- a/trunk/arch/i386/Makefile +++ b/trunk/arch/i386/Makefile @@ -46,14 +46,6 @@ cflags-y += -ffreestanding # a lot more stack due to the lack of sharing of stacklots: CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) -# do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) - -# is .cfi_signal_frame supported too? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) - CFLAGS += $(cflags-y) # Default subarch .c files diff --git a/trunk/arch/i386/boot/edd.S b/trunk/arch/i386/boot/edd.S index 34321368011a..4b84ea216f2b 100644 --- a/trunk/arch/i386/boot/edd.S +++ b/trunk/arch/i386/boot/edd.S @@ -15,95 +15,42 @@ #include #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) - -# It is assumed that %ds == INITSEG here - movb $0, (EDD_MBR_SIG_NR_BUF) movb $0, (EDDNR) -# Check the command line for options: +# Check the command line for two options: # edd=of disables EDD completely (edd=off) # edd=sk skips the MBR test (edd=skipmbr) -# edd=on re-enables EDD (edd=on) - pushl %esi - movw $edd_mbr_sig_start, %di # Default to edd=on - - movl %cs:(cmd_line_ptr), %esi - andl %esi, %esi - jz old_cl # Old boot protocol? - -# Convert to a real-mode pointer in fs:si - movl %esi, %eax - shrl $4, %eax - movw %ax, %fs - andw $0xf, %si - jmp have_cl_pointer - -# Old-style boot protocol? -old_cl: - push %ds # aka INITSEG - pop %fs - - cmpw $0xa33f, (0x20) - jne done_cl # No command line at all? - movw (0x22), %si # Pointer relative to INITSEG - -# fs:si has the pointer to the command line now -have_cl_pointer: - -# Loop through kernel command line one byte at a time. Just in -# case the loader is buggy and failed to null-terminate the command line -# terminate if we get close enough to the end of the segment that we -# cannot fit "edd=XX"... -cl_atspace: - cmpw $-5, %si # Watch for segment wraparound - jae done_cl - movl %fs:(%si), %eax - andb %al, %al # End of line? + cmpl $0, %cs:cmd_line_ptr jz done_cl - cmpl $EDD_CL_EQUALS, %eax + movl %cs:(cmd_line_ptr), %esi +# ds:esi has the pointer to the command line now + movl $(COMMAND_LINE_SIZE-7), %ecx +# loop through kernel command line one byte at a time +cl_loop: + cmpl $EDD_CL_EQUALS, (%si) jz found_edd_equals - cmpb $0x20, %al # <= space consider whitespace - ja cl_skipword - incw %si - jmp cl_atspace - -cl_skipword: - cmpw $-5, %si # Watch for segment wraparound - jae done_cl - movb %fs:(%si), %al # End of string? - andb %al, %al - jz done_cl - cmpb $0x20, %al - jbe cl_atspace - incw %si - jmp cl_skipword - + incl %esi + loop cl_loop + jmp done_cl found_edd_equals: # only looking at first two characters after equals -# late overrides early on the command line, so keep going after finding something - movw %fs:4(%si), %ax - cmpw $EDD_CL_OFF, %ax # edd=of - je do_edd_off - cmpw $EDD_CL_SKIP, %ax # edd=sk - je do_edd_skipmbr - cmpw $EDD_CL_ON, %ax # edd=on - je do_edd_on - jmp cl_skipword + addl $4, %esi + cmpw $EDD_CL_OFF, (%si) # edd=of + jz do_edd_off + cmpw $EDD_CL_SKIP, (%si) # edd=sk + jz do_edd_skipmbr + jmp done_cl do_edd_skipmbr: - movw $edd_start, %di - jmp cl_skipword + popl %esi + jmp edd_start do_edd_off: - movw $edd_done, %di - jmp cl_skipword -do_edd_on: - movw $edd_mbr_sig_start, %di - jmp cl_skipword - + popl %esi + jmp edd_done done_cl: popl %esi - jmpw *%di + # Read the first sector of each BIOS disk device and store the 4-byte signature edd_mbr_sig_start: diff --git a/trunk/arch/i386/boot/setup.S b/trunk/arch/i386/boot/setup.S index 3aec4538a113..d2b684cd620a 100644 --- a/trunk/arch/i386/boot/setup.S +++ b/trunk/arch/i386/boot/setup.S @@ -494,12 +494,12 @@ no_voyager: movw %cs, %ax # aka SETUPSEG subw $DELTA_INITSEG, %ax # aka INITSEG movw %ax, %ds - movb $0, (0x1ff) # default is no pointing device + movw $0, (0x1ff) # default is no pointing device int $0x11 # int 0x11: equipment list testb $0x04, %al # check if mouse installed jz no_psmouse - movb $0xAA, (0x1ff) # device present + movw $0xAA, (0x1ff) # device present no_psmouse: #if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) diff --git a/trunk/arch/i386/defconfig b/trunk/arch/i386/defconfig index 1a29bfa26d0c..89ebb7a316ab 100644 --- a/trunk/arch/i386/defconfig +++ b/trunk/arch/i386/defconfig @@ -1,51 +1,41 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-git5 -# Tue Sep 26 09:30:47 2006 # CONFIG_X86_32=y -CONFIG_GENERIC_TIME=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_X86=y CONFIG_MMU=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_DMI=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y +CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y +# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -# CONFIG_CPUSETS is not set -# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_VM86=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set -CONFIG_UID16=y -CONFIG_SYSCTL=y CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -55,9 +45,11 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -68,45 +60,41 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_KMOD is not set -CONFIG_STOP_MACHINE=y # # Block layer # -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBD is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" # # Processor type and features # -CONFIG_SMP=y -# CONFIG_X86_PC is not set +CONFIG_X86_PC=y # CONFIG_X86_ELAN is not set # CONFIG_X86_VOYAGER is not set # CONFIG_X86_NUMAQ is not set # CONFIG_X86_SUMMIT is not set # CONFIG_X86_BIGSMP is not set # CONFIG_X86_VISWS is not set -CONFIG_X86_GENERICARCH=y +# CONFIG_X86_GENERICARCH is not set # CONFIG_X86_ES7000 is not set -CONFIG_X86_CYCLONE_TIMER=y # CONFIG_M386 is not set # CONFIG_M486 is not set # CONFIG_M586 is not set @@ -114,11 +102,11 @@ CONFIG_X86_CYCLONE_TIMER=y # CONFIG_M586MMX is not set # CONFIG_M686 is not set # CONFIG_MPENTIUMII is not set -CONFIG_MPENTIUMIII=y +# CONFIG_MPENTIUMIII is not set # CONFIG_MPENTIUMM is not set # CONFIG_MPENTIUM4 is not set # CONFIG_MK6 is not set -# CONFIG_MK7 is not set +CONFIG_MK7=y # CONFIG_MK8 is not set # CONFIG_MCRUSOE is not set # CONFIG_MEFFICEON is not set @@ -129,10 +117,10 @@ CONFIG_MPENTIUMIII=y # CONFIG_MGEODE_LX is not set # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set -CONFIG_X86_GENERIC=y +# CONFIG_X86_GENERIC is not set CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y -CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_L1_CACHE_SHIFT=6 CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_X86_WP_WORKS_OK=y @@ -143,28 +131,26 @@ CONFIG_X86_CMPXCHG64=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_INTEL_USERCOPY=y CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_USE_3DNOW=y CONFIG_X86_TSC=y -CONFIG_HPET_TIMER=y -CONFIG_HPET_EMULATE_RTC=y -CONFIG_NR_CPUS=32 -CONFIG_SCHED_SMT=y -CONFIG_SCHED_MC=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_HPET_TIMER is not set +# CONFIG_SMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_PREEMPT_BKL=y +CONFIG_X86_UP_APIC=y +CONFIG_X86_UP_IOAPIC=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y CONFIG_X86_MCE=y CONFIG_X86_MCE_NONFATAL=y -CONFIG_X86_MCE_P4THERMAL=y -CONFIG_VM86=y +# CONFIG_X86_MCE_P4THERMAL is not set # CONFIG_TOSHIBA is not set # CONFIG_I8K is not set # CONFIG_X86_REBOOTFIXUPS is not set -CONFIG_MICROCODE=y -CONFIG_X86_MSR=y -CONFIG_X86_CPUID=y +# CONFIG_MICROCODE is not set +# CONFIG_X86_MSR is not set +# CONFIG_X86_CPUID is not set # # Firmware Drivers @@ -172,67 +158,68 @@ CONFIG_X86_CPUID=y # CONFIG_EDD is not set # CONFIG_DELL_RBU is not set # CONFIG_DCDBAS is not set -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM4G=y +CONFIG_NOHIGHMEM=y +# CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_STATIC=y CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y -# CONFIG_HIGHPTE is not set # CONFIG_MATH_EMULATION is not set CONFIG_MTRR=y # CONFIG_EFI is not set -# CONFIG_IRQBALANCE is not set CONFIG_REGPARM=y -CONFIG_SECCOMP=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y +# CONFIG_SECCOMP is not set +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set # CONFIG_HZ_1000 is not set -CONFIG_HZ=250 +CONFIG_HZ=100 # CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x100000 -# CONFIG_HOTPLUG_CPU is not set -CONFIG_COMPAT_VDSO=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_DOUBLEFAULT=y # # Power management options (ACPI, APM) # CONFIG_PM=y -CONFIG_PM_LEGACY=y +# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_PM_STD_PARTITION="" # # ACPI (Advanced Configuration and Power Interface) Support # CONFIG_ACPI=y -CONFIG_ACPI_AC=y -CONFIG_ACPI_BATTERY=y -CONFIG_ACPI_BUTTON=y +# CONFIG_ACPI_SLEEP is not set +# CONFIG_ACPI_AC is not set +# CONFIG_ACPI_BATTERY is not set +# CONFIG_ACPI_BUTTON is not set # CONFIG_ACPI_VIDEO is not set # CONFIG_ACPI_HOTKEY is not set -CONFIG_ACPI_FAN=y -# CONFIG_ACPI_DOCK is not set -CONFIG_ACPI_PROCESSOR=y -CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_FAN is not set +# CONFIG_ACPI_PROCESSOR is not set # CONFIG_ACPI_ASUS is not set # CONFIG_ACPI_IBM is not set # CONFIG_ACPI_TOSHIBA is not set -CONFIG_ACPI_BLACKLIST_YEAR=2001 -CONFIG_ACPI_DEBUG=y +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_EC=y CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y -CONFIG_X86_PM_TIMER=y +# CONFIG_X86_PM_TIMER is not set # CONFIG_ACPI_CONTAINER is not set # @@ -243,41 +230,7 @@ CONFIG_X86_PM_TIMER=y # # CPU Frequency scaling # -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -CONFIG_CPU_FREQ_DEBUG=y -CONFIG_CPU_FREQ_STAT=y -# CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set - -# -# CPUFreq processor drivers -# -CONFIG_X86_ACPI_CPUFREQ=y -# CONFIG_X86_POWERNOW_K6 is not set -# CONFIG_X86_POWERNOW_K7 is not set -CONFIG_X86_POWERNOW_K8=y -CONFIG_X86_POWERNOW_K8_ACPI=y -# CONFIG_X86_GX_SUSPMOD is not set -# CONFIG_X86_SPEEDSTEP_CENTRINO is not set -# CONFIG_X86_SPEEDSTEP_ICH is not set -# CONFIG_X86_SPEEDSTEP_SMI is not set -# CONFIG_X86_P4_CLOCKMOD is not set -# CONFIG_X86_CPUFREQ_NFORCE2 is not set -# CONFIG_X86_LONGRUN is not set -# CONFIG_X86_LONGHAUL is not set - -# -# shared options -# -CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y -# CONFIG_X86_SPEEDSTEP_LIB is not set +# CONFIG_CPU_FREQ is not set # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -291,13 +244,12 @@ CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y # CONFIG_PCIEPORTBUS is not set -CONFIG_PCI_MSI=y -# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_MSI is not set +# CONFIG_PCI_LEGACY_PROC is not set CONFIG_ISA_DMA_API=y # CONFIG_ISA is not set # CONFIG_MCA is not set # CONFIG_SCx200 is not set -CONFIG_K8_NB=y # # PCCARD (PCMCIA/CardBus) support @@ -326,54 +278,93 @@ CONFIG_NET=y # # CONFIG_NETDEBUG is not set CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set +CONFIG_PACKET_MMAP=y CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y -CONFIG_IP_MULTICAST=y +# CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +CONFIG_NETFILTER_XTABLES=y +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=y +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +# CONFIG_IP_NF_CT_ACCT is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=y +# CONFIG_IP_NF_IRC is not set +# CONFIG_IP_NF_NETBIOS_NS is not set +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=y +# CONFIG_IP_NF_MATCH_IPRANGE is not set +# CONFIG_IP_NF_MATCH_MULTIPORT is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +CONFIG_IP_NF_FILTER=y +# CONFIG_IP_NF_TARGET_REJECT is not set +CONFIG_IP_NF_TARGET_LOG=y +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_IP_NF_TARGET_TCPMSS is not set +# CONFIG_IP_NF_NAT is not set +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set # # DCCP Configuration (EXPERIMENTAL) @@ -398,6 +389,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -410,7 +402,6 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_TCPPROBE is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set @@ -425,9 +416,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_FW_LOADER is not set # # Connector - unified userspace <-> kernelspace linker @@ -442,7 +431,13 @@ CONFIG_FW_LOADER=y # # Parallel port support # -# CONFIG_PARPORT is not set +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y # # Plug and Play support @@ -452,7 +447,8 @@ CONFIG_FW_LOADER=y # # Block devices # -CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -463,11 +459,8 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y +# CONFIG_BLK_DEV_RAM is not set CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -483,7 +476,7 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDE_SATA is not set # CONFIG_BLK_DEV_HD_IDE is not set CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_MULTI_MODE is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -493,10 +486,10 @@ CONFIG_BLK_DEV_IDECD=y # # IDE chipset support/bugfixes # -CONFIG_IDE_GENERIC=y +# CONFIG_IDE_GENERIC is not set # CONFIG_BLK_DEV_CMD640 is not set CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_GENERIC is not set # CONFIG_BLK_DEV_OPTI621 is not set @@ -507,7 +500,7 @@ CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y +# CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_BLK_DEV_ATIIXP is not set # CONFIG_BLK_DEV_CMD64X is not set # CONFIG_BLK_DEV_TRIFLEX is not set @@ -518,7 +511,7 @@ CONFIG_BLK_DEV_AMD74XX=y # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set -CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set @@ -528,7 +521,7 @@ CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_VIA82CXXX=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set @@ -540,7 +533,6 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y # CONFIG_SCSI_PROC_FS is not set # @@ -549,9 +541,8 @@ CONFIG_SCSI_NETLINK=y CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=y +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set # @@ -562,44 +553,29 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SCSI_FC_ATTRS=y +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers # # CONFIG_ISCSI_TCP is not set -CONFIG_BLK_DEV_3W_XXXX_RAID=y +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=32 -CONFIG_AIC7XXX_RESET_DELAY_MS=5000 -CONFIG_AIC7XXX_DEBUG_ENABLE=y -CONFIG_AIC7XXX_DEBUG_MASK=0 -CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +# CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set -CONFIG_SCSI_AIC79XX=y -CONFIG_AIC79XX_CMDS_PER_DEVICE=32 -CONFIG_AIC79XX_RESET_DELAY_MS=4000 -# CONFIG_AIC79XX_ENABLE_RD_STRM is not set -# CONFIG_AIC79XX_DEBUG_ENABLE is not set -CONFIG_AIC79XX_DEBUG_MASK=0 -# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set -# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set @@ -608,9 +584,11 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set # CONFIG_SCSI_LPFC is not set @@ -619,115 +597,23 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_SATA_SVW=y -CONFIG_ATA_PIIX=y -# CONFIG_SATA_MV is not set -CONFIG_SATA_NV=y -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -CONFIG_SATA_SIL=y -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -CONFIG_SATA_VIA=y -# CONFIG_SATA_VITESSE is not set -CONFIG_SATA_INTEL_COMBINED=y -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CS5535 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_LEGACY is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_QDI is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set - # # Multi-device support (RAID and LVM) # -CONFIG_MD=y -# CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_CRYPT is not set -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set +# CONFIG_MD is not set # # Fusion MPT device support # -CONFIG_FUSION=y -CONFIG_FUSION_SPI=y +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set # CONFIG_FUSION_FC is not set # CONFIG_FUSION_SAS is not set -CONFIG_FUSION_MAX_SGE=128 -# CONFIG_FUSION_CTL is not set # # IEEE 1394 (FireWire) support # -CONFIG_IEEE1394=y - -# -# Subsystem Options -# -# CONFIG_IEEE1394_VERBOSEDEBUG is not set -# CONFIG_IEEE1394_OUI_DB is not set -# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set -# CONFIG_IEEE1394_EXPORT_FULL_API is not set - -# -# Device Drivers -# - -# -# Texas Instruments PCILynx requires I2C -# -CONFIG_IEEE1394_OHCI1394=y - -# -# Protocol Drivers -# -# CONFIG_IEEE1394_VIDEO1394 is not set -# CONFIG_IEEE1394_SBP2 is not set -# CONFIG_IEEE1394_ETH1394 is not set -# CONFIG_IEEE1394_DV1394 is not set -CONFIG_IEEE1394_RAWIO=y +# CONFIG_IEEE1394 is not set # # I2O device support @@ -766,63 +652,46 @@ CONFIG_MII=y # # Tulip family network device support # -CONFIG_NET_TULIP=y -# CONFIG_DE2104X is not set -CONFIG_TULIP=y -# CONFIG_TULIP_MWI is not set -# CONFIG_TULIP_MMIO is not set -# CONFIG_TULIP_NAPI is not set -# CONFIG_DE4X5 is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_DM9102 is not set -# CONFIG_ULI526X is not set +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set -CONFIG_B44=y -CONFIG_FORCEDETH=y -# CONFIG_FORCEDETH_NAPI is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set -CONFIG_8139CP=y -CONFIG_8139TOO=y -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -CONFIG_E1000=y -# CONFIG_E1000_NAPI is not set -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_E1000 is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set -CONFIG_R8169=y -# CONFIG_R8169_NAPI is not set +# CONFIG_R8169 is not set # CONFIG_SIS190 is not set # CONFIG_SKGE is not set -CONFIG_SKY2=y +# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set -CONFIG_TIGON3=y -CONFIG_BNX2=y -# CONFIG_QLA3XXX is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -830,7 +699,6 @@ CONFIG_BNX2=y # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -848,15 +716,14 @@ CONFIG_BNX2=y # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set +# CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set -CONFIG_NETCONSOLE=y -CONFIG_NETPOLL=y -# CONFIG_NETPOLL_RX is not set -# CONFIG_NETPOLL_TRAP is not set -CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -878,8 +745,8 @@ CONFIG_INPUT=y # CONFIG_INPUT_MOUSEDEV=y CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024 # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=y @@ -909,6 +776,7 @@ CONFIG_SERIO=y CONFIG_SERIO_I8042=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set @@ -920,15 +788,14 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # # Serial drivers # CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_ACPI is not set CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -937,11 +804,14 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # Non-8250 serial port support # CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set # # IPMI @@ -952,12 +822,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_INTEL=y -CONFIG_HW_RANDOM_AMD=y -CONFIG_HW_RANDOM_GEODE=y -CONFIG_HW_RANDOM_VIA=y -# CONFIG_NVRAM is not set +# CONFIG_HW_RANDOM is not set +CONFIG_NVRAM=y CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -967,28 +833,31 @@ CONFIG_RTC=y # # Ftape, the floppy tape device driver # +# CONFIG_FTAPE is not set CONFIG_AGP=y # CONFIG_AGP_ALI is not set # CONFIG_AGP_ATI is not set # CONFIG_AGP_AMD is not set -CONFIG_AGP_AMD64=y -CONFIG_AGP_INTEL=y +# CONFIG_AGP_AMD64 is not set +# CONFIG_AGP_INTEL is not set # CONFIG_AGP_NVIDIA is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_SWORKS is not set -# CONFIG_AGP_VIA is not set +CONFIG_AGP_VIA=y # CONFIG_AGP_EFFICEON is not set -# CONFIG_DRM is not set +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=y +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set # CONFIG_MWAVE is not set -# CONFIG_PC8736x_GPIO is not set -# CONFIG_NSC_GPIO is not set # CONFIG_CS5535_GPIO is not set -CONFIG_RAW_DRIVER=y -CONFIG_MAX_RAW_DEVS=256 -CONFIG_HPET=y -# CONFIG_HPET_RTC_IRQ is not set -CONFIG_HPET_MMAP=y -CONFIG_HANGCHECK_TIMER=y +# CONFIG_RAW_DRIVER is not set +# CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set # # TPM devices @@ -999,7 +868,59 @@ CONFIG_HANGCHECK_TIMER=y # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_ISA=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +CONFIG_I2C_VIAPRO=y +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # # SPI support @@ -1010,44 +931,169 @@ CONFIG_HANGCHECK_TIMER=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support # -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set +CONFIG_HWMON=y +CONFIG_HWMON_VID=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +CONFIG_SENSORS_IT87=y +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices # # CONFIG_IBM_ASM is not set +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # -# CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_DEV=y + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +CONFIG_VIDEO_SAA7134=y +# CONFIG_VIDEO_SAA7134_ALSA is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_OVCAMCHIP is not set +# CONFIG_VIDEO_AUDIO_DECODER is not set +# CONFIG_VIDEO_DECODER is not set + +# +# Radio Adapters +# +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set +CONFIG_VIDEO_TUNER=y +CONFIG_VIDEO_BUF=y +CONFIG_VIDEO_IR=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB is not set +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VESA is not set +CONFIG_VIDEO_SELECT=y +# CONFIG_FB_HGA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I810 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_CYBLA is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_GEODE is not set +# CONFIG_FB_VIRTUAL is not set # # Console display driver support # CONFIG_VGA_CONSOLE=y -CONFIG_VGACON_SOFT_SCROLLBACK=y -CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128 -CONFIG_VIDEO_SELECT=y CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +# CONFIG_LOGO is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1058,30 +1104,97 @@ CONFIG_SOUND=y # # Advanced Linux Sound Architecture # -# CONFIG_SND is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_RAWMIDI=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_RTCTIMER=y +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=y +CONFIG_SND_AC97_CODEC=y +CONFIG_SND_AC97_BUS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_VIA82XX=y +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_USX2Y is not set # # Open Sound System # -CONFIG_SOUND_PRIME=y -CONFIG_OSS_OBSOLETE_DRIVER=y -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_ES1371 is not set -CONFIG_SOUND_ICH=y -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_PRIME is not set # # USB support # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -1100,19 +1213,17 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OHCI_HCD is not set CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set # # USB Device Class drivers # +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set # CONFIG_USB_ACM is not set -CONFIG_USB_PRINTER=y +# CONFIG_USB_PRINTER is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -1137,17 +1248,21 @@ CONFIG_USB_STORAGE=y # # USB Input Devices # -CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1161,6 +1276,21 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_PWC is not set + # # USB Network Adapters # @@ -1169,11 +1299,12 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y +# CONFIG_USB_MON is not set # # USB port drivers # +# CONFIG_USB_USS720 is not set # # USB Serial Converter support @@ -1190,12 +1321,10 @@ CONFIG_USB_MON=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1214,97 +1343,57 @@ CONFIG_USB_MON=y # # CONFIG_MMC is not set -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - # # InfiniBand support # # CONFIG_INFINIBAND is not set # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# -# CONFIG_EDAC is not set - -# -# Real Time Clock +# SN Devices # -# CONFIG_RTC_CLASS is not set # -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices +# EDAC - error detection and reporting (RAS) # +# CONFIG_EDAC is not set # # File systems # CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=y -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -# CONFIG_REISERFS_FS_SECURITY is not set +# CONFIG_EXT3_FS is not set +# CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y +# CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y # CONFIG_UDF_FS is not set # # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +# CONFIG_MSDOS_FS is not set CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_CODEPAGE=850 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set @@ -1315,9 +1404,10 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y CONFIG_TMPFS=y -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -1340,26 +1430,13 @@ CONFIG_RAMFS=y # # Network File Systems # -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set # CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set +CONFIG_CIFS=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1368,18 +1445,33 @@ CONFIG_SUNRPC=y # # Partition Types # -# CONFIG_PARTITION_ADVANCED is not set +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set # # Native Language Support # CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_DEFAULT="iso8859-15" +# CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set +CONFIG_NLS_CODEPAGE_850=y # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set @@ -1399,7 +1491,7 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y +# CONFIG_NLS_ASCII is not set CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -1418,50 +1510,20 @@ CONFIG_NLS_UTF8=y # # Instrumentation Support # -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -CONFIG_KPROBES=y +# CONFIG_PROFILING is not set +# CONFIG_KPROBES is not set # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y -CONFIG_UNUSED_SYMBOLS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=18 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_FRAME_POINTER is not set -CONFIG_UNWIND_INFO=y -CONFIG_STACK_UNWIND=y -# CONFIG_FORCED_INLINING is not set -# CONFIG_RCU_TORTURE_TEST is not set CONFIG_EARLY_PRINTK=y -CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_RODATA is not set -# CONFIG_4KSTACKS is not set CONFIG_X86_FIND_SMP_CONFIG=y CONFIG_X86_MPPARSE=y -CONFIG_DOUBLEFAULT=y # # Security options @@ -1474,6 +1536,10 @@ CONFIG_DOUBLEFAULT=y # # CONFIG_CRYPTO is not set +# +# Hardware crypto devices +# + # # Library routines # @@ -1482,12 +1548,7 @@ CONFIG_DOUBLEFAULT=y CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_PENDING_IRQ=y -CONFIG_X86_SMP=y -CONFIG_X86_HT=y CONFIG_X86_BIOS_REBOOT=y -CONFIG_X86_TRAMPOLINE=y CONFIG_KTIME_SCALAR=y diff --git a/trunk/arch/i386/kernel/Makefile b/trunk/arch/i386/kernel/Makefile index 1a884b6e6e5c..5427a842e841 100644 --- a/trunk/arch/i386/kernel/Makefile +++ b/trunk/arch/i386/kernel/Makefile @@ -4,7 +4,7 @@ extra-y := head.o init_task.o vmlinux.lds -obj-y := process.o signal.o entry.o traps.o irq.o \ +obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ pci-dma.o i386_ksyms.o i387.o bootflag.o \ quirks.o i8237.o topology.o alternative.o i8253.o tsc.o @@ -81,5 +81,4 @@ $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \ $(call if_changed,syscall) k8-y += ../../x86_64/kernel/k8.o -stacktrace-y += ../../x86_64/kernel/stacktrace.o diff --git a/trunk/arch/i386/kernel/acpi/Makefile b/trunk/arch/i386/kernel/acpi/Makefile index 7f7be01f44e6..7e9ac99354f4 100644 --- a/trunk/arch/i386/kernel/acpi/Makefile +++ b/trunk/arch/i386/kernel/acpi/Makefile @@ -1,7 +1,5 @@ obj-$(CONFIG_ACPI) += boot.o -ifneq ($(CONFIG_PCI),) obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o -endif obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o ifneq ($(CONFIG_ACPI_PROCESSOR),) diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index 1aaea6ab8c46..ee003bc0e8b1 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -26,12 +26,9 @@ #include #include #include -#include #include #include #include -#include -#include #include #include @@ -39,17 +36,11 @@ #include #include -static int __initdata acpi_force = 0; - -#ifdef CONFIG_ACPI -int acpi_disabled = 0; -#else -int acpi_disabled = 1; -#endif -EXPORT_SYMBOL(acpi_disabled); - #ifdef CONFIG_X86_64 +extern void __init clustered_apic_check(void); + +extern int gsi_irq_sharing(int gsi); #include static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } @@ -515,76 +506,16 @@ EXPORT_SYMBOL(acpi_register_gsi); #ifdef CONFIG_ACPI_HOTPLUG_CPU int acpi_map_lsapic(acpi_handle handle, int *pcpu) { - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_table_lapic *lapic; - cpumask_t tmp_map, new_map; - u8 physid; - int cpu; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - return -EINVAL; - - if (!buffer.length || !buffer.pointer) - return -EINVAL; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER || - obj->buffer.length < sizeof(*lapic)) { - kfree(buffer.pointer); - return -EINVAL; - } - - lapic = (struct acpi_table_lapic *)obj->buffer.pointer; - - if ((lapic->header.type != ACPI_MADT_LAPIC) || - (!lapic->flags.enabled)) { - kfree(buffer.pointer); - return -EINVAL; - } - - physid = lapic->id; - - kfree(buffer.pointer); - buffer.length = ACPI_ALLOCATE_BUFFER; - buffer.pointer = NULL; - - tmp_map = cpu_present_map; - mp_register_lapic(physid, lapic->flags.enabled); - - /* - * If mp_register_lapic successfully generates a new logical cpu - * number, then the following will get us exactly what was mapped - */ - cpus_andnot(new_map, cpu_present_map, tmp_map); - if (cpus_empty(new_map)) { - printk ("Unable to map lapic to logical cpu number\n"); - return -EINVAL; - } - - cpu = first_cpu(new_map); - - *pcpu = cpu; - return 0; + /* TBD */ + return -EINVAL; } EXPORT_SYMBOL(acpi_map_lsapic); int acpi_unmap_lsapic(int cpu) { - int i; - - for_each_possible_cpu(i) { - if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu]) { - x86_acpiid_to_apicid[i] = -1; - break; - } - } - x86_cpu_to_apicid[cpu] = -1; - cpu_clear(cpu, cpu_present_map); - num_processors--; - - return (0); + /* TBD */ + return -EINVAL; } EXPORT_SYMBOL(acpi_unmap_lsapic); @@ -648,8 +579,6 @@ static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) { struct acpi_table_hpet *hpet_tbl; - struct resource *hpet_res; - resource_size_t res_start; if (!phys || !size) return -EINVAL; @@ -665,26 +594,12 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) "memory.\n"); return -1; } - -#define HPET_RESOURCE_NAME_SIZE 9 - hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE); - if (hpet_res) { - memset(hpet_res, 0, sizeof(*hpet_res)); - hpet_res->name = (void *)&hpet_res[1]; - hpet_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, - "HPET %u", hpet_tbl->number); - hpet_res->end = (1 * 1024) - 1; - } - #ifdef CONFIG_X86_64 vxtime.hpet_address = hpet_tbl->addr.addrl | ((long)hpet_tbl->addr.addrh << 32); printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", hpet_tbl->id, vxtime.hpet_address); - - res_start = vxtime.hpet_address; #else /* X86 */ { extern unsigned long hpet_address; @@ -692,17 +607,9 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) hpet_address = hpet_tbl->addr.addrl; printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address); - - res_start = hpet_address; } #endif /* X86 */ - if (hpet_res) { - hpet_res->start = res_start; - hpet_res->end += res_start; - insert_resource(&iomem_resource, hpet_res); - } - return 0; } #else @@ -953,6 +860,8 @@ static void __init acpi_process_madt(void) return; } +extern int acpi_force; + #ifdef __i386__ static int __init disable_acpi_irq(struct dmi_system_id *d) @@ -1254,75 +1163,3 @@ int __init acpi_boot_init(void) return 0; } - -static int __init parse_acpi(char *arg) -{ - if (!arg) - return -EINVAL; - - /* "acpi=off" disables both ACPI table parsing and interpreter */ - if (strcmp(arg, "off") == 0) { - disable_acpi(); - } - /* acpi=force to over-ride black-list */ - else if (strcmp(arg, "force") == 0) { - acpi_force = 1; - acpi_ht = 1; - acpi_disabled = 0; - } - /* acpi=strict disables out-of-spec workarounds */ - else if (strcmp(arg, "strict") == 0) { - acpi_strict = 1; - } - /* Limit ACPI just to boot-time to enable HT */ - else if (strcmp(arg, "ht") == 0) { - if (!acpi_force) - disable_acpi(); - acpi_ht = 1; - } - /* "acpi=noirq" disables ACPI interrupt routing */ - else if (strcmp(arg, "noirq") == 0) { - acpi_noirq_set(); - } else { - /* Core will printk when we return error. */ - return -EINVAL; - } - return 0; -} -early_param("acpi", parse_acpi); - -/* FIXME: Using pci= for an ACPI parameter is a travesty. */ -static int __init parse_pci(char *arg) -{ - if (arg && strcmp(arg, "noacpi") == 0) - acpi_disable_pci(); - return 0; -} -early_param("pci", parse_pci); - -#ifdef CONFIG_X86_IO_APIC -static int __init parse_acpi_skip_timer_override(char *arg) -{ - acpi_skip_timer_override = 1; - return 0; -} -early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override); -#endif /* CONFIG_X86_IO_APIC */ - -static int __init setup_acpi_sci(char *s) -{ - if (!s) - return -EINVAL; - if (!strcmp(s, "edge")) - acpi_sci_flags.trigger = 1; - else if (!strcmp(s, "level")) - acpi_sci_flags.trigger = 3; - else if (!strcmp(s, "high")) - acpi_sci_flags.polarity = 1; - else if (!strcmp(s, "low")) - acpi_sci_flags.polarity = 3; - else - return -EINVAL; - return 0; -} -early_param("acpi_sci", setup_acpi_sci); diff --git a/trunk/arch/i386/kernel/acpi/earlyquirk.c b/trunk/arch/i386/kernel/acpi/earlyquirk.c index fe799b11ac0a..1649a175a206 100644 --- a/trunk/arch/i386/kernel/acpi/earlyquirk.c +++ b/trunk/arch/i386/kernel/acpi/earlyquirk.c @@ -48,11 +48,7 @@ void __init check_acpi_pci(void) int num, slot, func; /* Assume the machine supports type 1. If not it will - always read ffffffff and should not have any side effect. - Actually a few buggy systems can machine check. Allow the user - to disable it by command line option at least -AK */ - if (!early_pci_allowed()) - return; + always read ffffffff and should not have any side effect. */ /* Poor man's PCI discovery */ for (num = 0; num < 32; num++) { diff --git a/trunk/arch/i386/kernel/apic.c b/trunk/arch/i386/kernel/apic.c index 90faae5c5d30..8c844d07862f 100644 --- a/trunk/arch/i386/kernel/apic.c +++ b/trunk/arch/i386/kernel/apic.c @@ -52,18 +52,7 @@ static cpumask_t timer_bcast_ipi; /* * Knob to control our willingness to enable the local APIC. */ -static int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ - -static inline void lapic_disable(void) -{ - enable_local_apic = -1; - clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); -} - -static inline void lapic_enable(void) -{ - enable_local_apic = 1; -} +int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ /* * Debug level @@ -597,7 +586,8 @@ void __devinit setup_local_APIC(void) printk("No ESR for 82489DX.\n"); } - setup_apic_nmi_watchdog(NULL); + if (nmi_watchdog == NMI_LOCAL_APIC) + setup_apic_nmi_watchdog(); apic_pm_activate(); } @@ -1383,18 +1373,3 @@ int __init APIC_init_uniprocessor (void) return 0; } - -static int __init parse_lapic(char *arg) -{ - lapic_enable(); - return 0; -} -early_param("lapic", parse_lapic); - -static int __init parse_nolapic(char *arg) -{ - lapic_disable(); - return 0; -} -early_param("nolapic", parse_nolapic); - diff --git a/trunk/arch/i386/kernel/cpu/amd.c b/trunk/arch/i386/kernel/cpu/amd.c index e4758095d87a..e6a2d6b80cda 100644 --- a/trunk/arch/i386/kernel/cpu/amd.c +++ b/trunk/arch/i386/kernel/cpu/amd.c @@ -22,7 +22,7 @@ extern void vide(void); __asm__(".align 4\nvide: ret"); -static void __cpuinit init_amd(struct cpuinfo_x86 *c) +static void __init init_amd(struct cpuinfo_x86 *c) { u32 l, h; int mbytes = num_physpages >> (20-PAGE_SHIFT); @@ -246,7 +246,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) num_cache_leaves = 3; } -static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) +static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) { /* AMD errata T13 (order #21922) */ if ((c->x86 == 6)) { @@ -259,7 +259,7 @@ static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned in return size; } -static struct cpu_dev amd_cpu_dev __cpuinitdata = { +static struct cpu_dev amd_cpu_dev __initdata = { .c_vendor = "AMD", .c_ident = { "AuthenticAMD" }, .c_models = { @@ -275,6 +275,7 @@ static struct cpu_dev amd_cpu_dev __cpuinitdata = { }, }, .c_init = init_amd, + .c_identify = generic_identify, .c_size_cache = amd_size_cache, }; diff --git a/trunk/arch/i386/kernel/cpu/centaur.c b/trunk/arch/i386/kernel/cpu/centaur.c index 8c25047975c0..bd75629dd262 100644 --- a/trunk/arch/i386/kernel/cpu/centaur.c +++ b/trunk/arch/i386/kernel/cpu/centaur.c @@ -9,7 +9,7 @@ #ifdef CONFIG_X86_OOSTORE -static u32 __cpuinit power2(u32 x) +static u32 __init power2(u32 x) { u32 s=1; while(s<=x) @@ -22,7 +22,7 @@ static u32 __cpuinit power2(u32 x) * Set up an actual MCR */ -static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key) +static void __init centaur_mcr_insert(int reg, u32 base, u32 size, int key) { u32 lo, hi; @@ -40,7 +40,7 @@ static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key) * Shortcut: We know you can't put 4Gig of RAM on a winchip */ -static u32 __cpuinit ramtop(void) /* 16388 */ +static u32 __init ramtop(void) /* 16388 */ { int i; u32 top = 0; @@ -91,7 +91,7 @@ static u32 __cpuinit ramtop(void) /* 16388 */ * Compute a set of MCR's to give maximum coverage */ -static int __cpuinit centaur_mcr_compute(int nr, int key) +static int __init centaur_mcr_compute(int nr, int key) { u32 mem = ramtop(); u32 root = power2(mem); @@ -166,7 +166,7 @@ static int __cpuinit centaur_mcr_compute(int nr, int key) return ct; } -static void __cpuinit centaur_create_optimal_mcr(void) +static void __init centaur_create_optimal_mcr(void) { int i; /* @@ -189,7 +189,7 @@ static void __cpuinit centaur_create_optimal_mcr(void) wrmsr(MSR_IDT_MCR0+i, 0, 0); } -static void __cpuinit winchip2_create_optimal_mcr(void) +static void __init winchip2_create_optimal_mcr(void) { u32 lo, hi; int i; @@ -227,7 +227,7 @@ static void __cpuinit winchip2_create_optimal_mcr(void) * Handle the MCR key on the Winchip 2. */ -static void __cpuinit winchip2_unprotect_mcr(void) +static void __init winchip2_unprotect_mcr(void) { u32 lo, hi; u32 key; @@ -239,7 +239,7 @@ static void __cpuinit winchip2_unprotect_mcr(void) wrmsr(MSR_IDT_MCR_CTRL, lo, hi); } -static void __cpuinit winchip2_protect_mcr(void) +static void __init winchip2_protect_mcr(void) { u32 lo, hi; @@ -257,7 +257,7 @@ static void __cpuinit winchip2_protect_mcr(void) #define RNG_ENABLED (1 << 3) #define RNG_ENABLE (1 << 6) /* MSR_VIA_RNG */ -static void __cpuinit init_c3(struct cpuinfo_x86 *c) +static void __init init_c3(struct cpuinfo_x86 *c) { u32 lo, hi; @@ -303,7 +303,7 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c) display_cacheinfo(c); } -static void __cpuinit init_centaur(struct cpuinfo_x86 *c) +static void __init init_centaur(struct cpuinfo_x86 *c) { enum { ECX8=1<<1, @@ -442,7 +442,7 @@ static void __cpuinit init_centaur(struct cpuinfo_x86 *c) } } -static unsigned int __cpuinit centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size) +static unsigned int centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size) { /* VIA C3 CPUs (670-68F) need further shifting. */ if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8))) @@ -457,7 +457,7 @@ static unsigned int __cpuinit centaur_size_cache(struct cpuinfo_x86 * c, unsigne return size; } -static struct cpu_dev centaur_cpu_dev __cpuinitdata = { +static struct cpu_dev centaur_cpu_dev __initdata = { .c_vendor = "Centaur", .c_ident = { "CentaurHauls" }, .c_init = init_centaur, diff --git a/trunk/arch/i386/kernel/cpu/common.c b/trunk/arch/i386/kernel/cpu/common.c index 2799baaadf45..70c87de582c7 100644 --- a/trunk/arch/i386/kernel/cpu/common.c +++ b/trunk/arch/i386/kernel/cpu/common.c @@ -36,7 +36,7 @@ struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; extern int disable_pse; -static void __cpuinit default_init(struct cpuinfo_x86 * c) +static void default_init(struct cpuinfo_x86 * c) { /* Not much we can do here... */ /* Check if at least it has cpuid */ @@ -49,7 +49,7 @@ static void __cpuinit default_init(struct cpuinfo_x86 * c) } } -static struct cpu_dev __cpuinitdata default_cpu = { +static struct cpu_dev default_cpu = { .c_init = default_init, .c_vendor = "Unknown", }; @@ -265,7 +265,7 @@ static void __init early_cpu_detect(void) } } -static void __cpuinit generic_identify(struct cpuinfo_x86 * c) +void __cpuinit generic_identify(struct cpuinfo_x86 * c) { u32 tfms, xlvl; int ebx; @@ -675,7 +675,7 @@ void __cpuinit cpu_init(void) #endif /* Clear %fs and %gs. */ - asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r" (0)); + asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); /* Clear all 6 debug registers: */ set_debugreg(0, 0); diff --git a/trunk/arch/i386/kernel/cpu/cpu.h b/trunk/arch/i386/kernel/cpu/cpu.h index 2f6432cef6ff..5a1d4f163e84 100644 --- a/trunk/arch/i386/kernel/cpu/cpu.h +++ b/trunk/arch/i386/kernel/cpu/cpu.h @@ -24,5 +24,7 @@ extern struct cpu_dev * cpu_devs [X86_VENDOR_NUM]; extern int get_model_name(struct cpuinfo_x86 *c); extern void display_cacheinfo(struct cpuinfo_x86 *c); +extern void generic_identify(struct cpuinfo_x86 * c); + extern void early_intel_workaround(struct cpuinfo_x86 *c); diff --git a/trunk/arch/i386/kernel/cpu/cyrix.c b/trunk/arch/i386/kernel/cpu/cyrix.c index c0c3b59de32c..f03b7f94c304 100644 --- a/trunk/arch/i386/kernel/cpu/cyrix.c +++ b/trunk/arch/i386/kernel/cpu/cyrix.c @@ -12,7 +12,7 @@ /* * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU */ -static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) +static void __init do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) { unsigned char ccr2, ccr3; unsigned long flags; @@ -52,25 +52,25 @@ static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) * Actually since bugs.h doesn't even reference this perhaps someone should * fix the documentation ??? */ -static unsigned char Cx86_dir0_msb __cpuinitdata = 0; +static unsigned char Cx86_dir0_msb __initdata = 0; -static char Cx86_model[][9] __cpuinitdata = { +static char Cx86_model[][9] __initdata = { "Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ", "M II ", "Unknown" }; -static char Cx486_name[][5] __cpuinitdata = { +static char Cx486_name[][5] __initdata = { "SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx", "SRx2", "DRx2" }; -static char Cx486S_name[][4] __cpuinitdata = { +static char Cx486S_name[][4] __initdata = { "S", "S2", "Se", "S2e" }; -static char Cx486D_name[][4] __cpuinitdata = { +static char Cx486D_name[][4] __initdata = { "DX", "DX2", "?", "?", "?", "DX4" }; -static char Cx86_cb[] __cpuinitdata = "?.5x Core/Bus Clock"; -static char cyrix_model_mult1[] __cpuinitdata = "12??43"; -static char cyrix_model_mult2[] __cpuinitdata = "12233445"; +static char Cx86_cb[] __initdata = "?.5x Core/Bus Clock"; +static char cyrix_model_mult1[] __initdata = "12??43"; +static char cyrix_model_mult2[] __initdata = "12233445"; /* * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old @@ -82,7 +82,7 @@ static char cyrix_model_mult2[] __cpuinitdata = "12233445"; extern void calibrate_delay(void) __init; -static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c) +static void __init check_cx686_slop(struct cpuinfo_x86 *c) { unsigned long flags; @@ -107,7 +107,7 @@ static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c) } -static void __cpuinit set_cx86_reorder(void) +static void __init set_cx86_reorder(void) { u8 ccr3; @@ -122,7 +122,7 @@ static void __cpuinit set_cx86_reorder(void) setCx86(CX86_CCR3, ccr3); } -static void __cpuinit set_cx86_memwb(void) +static void __init set_cx86_memwb(void) { u32 cr0; @@ -137,7 +137,7 @@ static void __cpuinit set_cx86_memwb(void) setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 ); } -static void __cpuinit set_cx86_inc(void) +static void __init set_cx86_inc(void) { unsigned char ccr3; @@ -158,7 +158,7 @@ static void __cpuinit set_cx86_inc(void) * Configure later MediaGX and/or Geode processor. */ -static void __cpuinit geode_configure(void) +static void __init geode_configure(void) { unsigned long flags; u8 ccr3, ccr4; @@ -184,14 +184,14 @@ static void __cpuinit geode_configure(void) #ifdef CONFIG_PCI -static struct pci_device_id __cpuinitdata cyrix_55x0[] = { +static struct pci_device_id __initdata cyrix_55x0[] = { { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) }, { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) }, { }, }; #endif -static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) +static void __init init_cyrix(struct cpuinfo_x86 *c) { unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0; char *buf = c->x86_model_id; @@ -346,7 +346,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) /* * Handle National Semiconductor branded processors */ -static void __cpuinit init_nsc(struct cpuinfo_x86 *c) +static void __init init_nsc(struct cpuinfo_x86 *c) { /* There may be GX1 processors in the wild that are branded * NSC and not Cyrix. @@ -394,7 +394,7 @@ static inline int test_cyrix_52div(void) return (unsigned char) (test >> 8) == 0x02; } -static void __cpuinit cyrix_identify(struct cpuinfo_x86 * c) +static void cyrix_identify(struct cpuinfo_x86 * c) { /* Detect Cyrix with disabled CPUID */ if ( c->x86 == 4 && test_cyrix_52div() ) { @@ -427,9 +427,10 @@ static void __cpuinit cyrix_identify(struct cpuinfo_x86 * c) local_irq_restore(flags); } } + generic_identify(c); } -static struct cpu_dev cyrix_cpu_dev __cpuinitdata = { +static struct cpu_dev cyrix_cpu_dev __initdata = { .c_vendor = "Cyrix", .c_ident = { "CyrixInstead" }, .c_init = init_cyrix, @@ -452,10 +453,11 @@ static int __init cyrix_exit_cpu(void) late_initcall(cyrix_exit_cpu); -static struct cpu_dev nsc_cpu_dev __cpuinitdata = { +static struct cpu_dev nsc_cpu_dev __initdata = { .c_vendor = "NSC", .c_ident = { "Geode by NSC" }, .c_init = init_nsc, + .c_identify = generic_identify, }; int __init nsc_init_cpu(void) diff --git a/trunk/arch/i386/kernel/cpu/intel.c b/trunk/arch/i386/kernel/cpu/intel.c index 94a95aa5227e..5a2e270924b1 100644 --- a/trunk/arch/i386/kernel/cpu/intel.c +++ b/trunk/arch/i386/kernel/cpu/intel.c @@ -198,7 +198,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) } -static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) +static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) { /* Intel PIII Tualatin. This comes in two flavours. * One has 256kb of cache, the other 512. We have no way @@ -263,6 +263,7 @@ static struct cpu_dev intel_cpu_dev __cpuinitdata = { }, }, .c_init = init_intel, + .c_identify = generic_identify, .c_size_cache = intel_size_cache, }; diff --git a/trunk/arch/i386/kernel/cpu/mcheck/Makefile b/trunk/arch/i386/kernel/cpu/mcheck/Makefile index f1ebe1c1c17a..30808f3d6715 100644 --- a/trunk/arch/i386/kernel/cpu/mcheck/Makefile +++ b/trunk/arch/i386/kernel/cpu/mcheck/Makefile @@ -1,2 +1,2 @@ -obj-y = mce.o k7.o p4.o p5.o p6.o winchip.o therm_throt.o +obj-y = mce.o k7.o p4.o p5.o p6.o winchip.o obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o diff --git a/trunk/arch/i386/kernel/cpu/mcheck/p4.c b/trunk/arch/i386/kernel/cpu/mcheck/p4.c index 504434a46011..b95f1b3d53aa 100644 --- a/trunk/arch/i386/kernel/cpu/mcheck/p4.c +++ b/trunk/arch/i386/kernel/cpu/mcheck/p4.c @@ -13,8 +13,6 @@ #include #include -#include - #include "mce.h" /* as supported by the P4/Xeon family */ @@ -46,12 +44,25 @@ static void unexpected_thermal_interrupt(struct pt_regs *regs) /* P4/Xeon Thermal transition interrupt handler */ static void intel_thermal_interrupt(struct pt_regs *regs) { - __u64 msr_val; + u32 l, h; + unsigned int cpu = smp_processor_id(); + static unsigned long next[NR_CPUS]; ack_APIC_irq(); - rdmsrl(MSR_IA32_THERM_STATUS, msr_val); - therm_throt_process(msr_val & 0x1); + if (time_after(next[cpu], jiffies)) + return; + + next[cpu] = jiffies + HZ*5; + rdmsr(MSR_IA32_THERM_STATUS, l, h); + if (l & 0x1) { + printk(KERN_EMERG "CPU%d: Temperature above threshold\n", cpu); + printk(KERN_EMERG "CPU%d: Running in modulated clock mode\n", + cpu); + add_taint(TAINT_MACHINE_CHECK); + } else { + printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu); + } } /* Thermal interrupt handler for this CPU setup */ @@ -111,13 +122,10 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) rdmsr (MSR_IA32_MISC_ENABLE, l, h); wrmsr (MSR_IA32_MISC_ENABLE, l | (1<<3), h); - + l = apic_read (APIC_LVTTHMR); apic_write_around (APIC_LVTTHMR, l & ~APIC_LVT_MASKED); printk (KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu); - - /* enable thermal throttle processing */ - atomic_set(&therm_throt_en, 1); return; } #endif /* CONFIG_X86_MCE_P4THERMAL */ diff --git a/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c b/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c deleted file mode 100644 index 4f43047de406..000000000000 --- a/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * linux/arch/i386/kerne/cpu/mcheck/therm_throt.c - * - * Thermal throttle event support code (such as syslog messaging and rate - * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c). - * This allows consistent reporting of CPU thermal throttle events. - * - * Maintains a counter in /sys that keeps track of the number of thermal - * events, such that the user knows how bad the thermal problem might be - * (since the logging to syslog and mcelog is rate limited). - * - * Author: Dmitriy Zavin (dmitriyz@google.com) - * - * Credits: Adapted from Zwane Mwaikambo's original code in mce_intel.c. - * Inspired by Ross Biro's and Al Borchers' counter code. - */ - -#include -#include -#include -#include -#include -#include - -/* How long to wait between reporting thermal events */ -#define CHECK_INTERVAL (300 * HZ) - -static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES; -static DEFINE_PER_CPU(unsigned long, thermal_throttle_count); -atomic_t therm_throt_en = ATOMIC_INIT(0); - -#ifdef CONFIG_SYSFS -#define define_therm_throt_sysdev_one_ro(_name) \ - static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL) - -#define define_therm_throt_sysdev_show_func(name) \ -static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \ - char *buf) \ -{ \ - unsigned int cpu = dev->id; \ - ssize_t ret; \ - \ - preempt_disable(); /* CPU hotplug */ \ - if (cpu_online(cpu)) \ - ret = sprintf(buf, "%lu\n", \ - per_cpu(thermal_throttle_##name, cpu)); \ - else \ - ret = 0; \ - preempt_enable(); \ - \ - return ret; \ -} - -define_therm_throt_sysdev_show_func(count); -define_therm_throt_sysdev_one_ro(count); - -static struct attribute *thermal_throttle_attrs[] = { - &attr_count.attr, - NULL -}; - -static struct attribute_group thermal_throttle_attr_group = { - .attrs = thermal_throttle_attrs, - .name = "thermal_throttle" -}; -#endif /* CONFIG_SYSFS */ - -/*** - * therm_throt_process - Process thermal throttling event from interrupt - * @curr: Whether the condition is current or not (boolean), since the - * thermal interrupt normally gets called both when the thermal - * event begins and once the event has ended. - * - * This function is called by the thermal interrupt after the - * IRQ has been acknowledged. - * - * It will take care of rate limiting and printing messages to the syslog. - * - * Returns: 0 : Event should NOT be further logged, i.e. still in - * "timeout" from previous log message. - * 1 : Event should be logged further, and a message has been - * printed to the syslog. - */ -int therm_throt_process(int curr) -{ - unsigned int cpu = smp_processor_id(); - __u64 tmp_jiffs = get_jiffies_64(); - - if (curr) - __get_cpu_var(thermal_throttle_count)++; - - if (time_before64(tmp_jiffs, __get_cpu_var(next_check))) - return 0; - - __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL; - - /* if we just entered the thermal event */ - if (curr) { - printk(KERN_CRIT "CPU%d: Temperature above threshold, " - "cpu clock throttled (total events = %lu)\n", cpu, - __get_cpu_var(thermal_throttle_count)); - - add_taint(TAINT_MACHINE_CHECK); - } else { - printk(KERN_CRIT "CPU%d: Temperature/speed normal\n", cpu); - } - - return 1; -} - -#ifdef CONFIG_SYSFS -/* Add/Remove thermal_throttle interface for CPU device */ -static __cpuinit int thermal_throttle_add_dev(struct sys_device * sys_dev) -{ - sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group); - return 0; -} - -#ifdef CONFIG_HOTPLUG_CPU -static __cpuinit int thermal_throttle_remove_dev(struct sys_device * sys_dev) -{ - sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); - return 0; -} - -/* Mutex protecting device creation against CPU hotplug */ -static DEFINE_MUTEX(therm_cpu_lock); - -/* Get notified when a cpu comes on/off. Be hotplug friendly. */ -static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, - unsigned long action, - void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct sys_device *sys_dev; - - sys_dev = get_cpu_sysdev(cpu); - mutex_lock(&therm_cpu_lock); - switch (action) { - case CPU_ONLINE: - thermal_throttle_add_dev(sys_dev); - break; - case CPU_DEAD: - thermal_throttle_remove_dev(sys_dev); - break; - } - mutex_unlock(&therm_cpu_lock); - return NOTIFY_OK; -} - -static struct notifier_block thermal_throttle_cpu_notifier = -{ - .notifier_call = thermal_throttle_cpu_callback, -}; -#endif /* CONFIG_HOTPLUG_CPU */ - -static __init int thermal_throttle_init_device(void) -{ - unsigned int cpu = 0; - - if (!atomic_read(&therm_throt_en)) - return 0; - - register_hotcpu_notifier(&thermal_throttle_cpu_notifier); - -#ifdef CONFIG_HOTPLUG_CPU - mutex_lock(&therm_cpu_lock); -#endif - /* connect live CPUs to sysfs */ - for_each_online_cpu(cpu) - thermal_throttle_add_dev(get_cpu_sysdev(cpu)); -#ifdef CONFIG_HOTPLUG_CPU - mutex_unlock(&therm_cpu_lock); -#endif - - return 0; -} - -device_initcall(thermal_throttle_init_device); -#endif /* CONFIG_SYSFS */ diff --git a/trunk/arch/i386/kernel/cpu/nexgen.c b/trunk/arch/i386/kernel/cpu/nexgen.c index 8bf23cc80c63..ad87fa58058d 100644 --- a/trunk/arch/i386/kernel/cpu/nexgen.c +++ b/trunk/arch/i386/kernel/cpu/nexgen.c @@ -10,7 +10,7 @@ * to have CPUID. (Thanks to Herbert Oppmann) */ -static int __cpuinit deep_magic_nexgen_probe(void) +static int __init deep_magic_nexgen_probe(void) { int ret; @@ -27,20 +27,21 @@ static int __cpuinit deep_magic_nexgen_probe(void) return ret; } -static void __cpuinit init_nexgen(struct cpuinfo_x86 * c) +static void __init init_nexgen(struct cpuinfo_x86 * c) { c->x86_cache_size = 256; /* A few had 1 MB... */ } -static void __cpuinit nexgen_identify(struct cpuinfo_x86 * c) +static void __init nexgen_identify(struct cpuinfo_x86 * c) { /* Detect NexGen with old hypercode */ if ( deep_magic_nexgen_probe() ) { strcpy(c->x86_vendor_id, "NexGenDriven"); } + generic_identify(c); } -static struct cpu_dev nexgen_cpu_dev __cpuinitdata = { +static struct cpu_dev nexgen_cpu_dev __initdata = { .c_vendor = "Nexgen", .c_ident = { "NexGenDriven" }, .c_models = { diff --git a/trunk/arch/i386/kernel/cpu/proc.c b/trunk/arch/i386/kernel/cpu/proc.c index 76aac088a323..f54a15268ed7 100644 --- a/trunk/arch/i386/kernel/cpu/proc.c +++ b/trunk/arch/i386/kernel/cpu/proc.c @@ -46,8 +46,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* Intel-defined (#2) */ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", - "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, - NULL, NULL, "dca", NULL, NULL, NULL, NULL, NULL, + "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* VIA/Cyrix/Centaur-defined */ diff --git a/trunk/arch/i386/kernel/cpu/rise.c b/trunk/arch/i386/kernel/cpu/rise.c index 9317f7414989..d08d5a2811c8 100644 --- a/trunk/arch/i386/kernel/cpu/rise.c +++ b/trunk/arch/i386/kernel/cpu/rise.c @@ -5,7 +5,7 @@ #include "cpu.h" -static void __cpuinit init_rise(struct cpuinfo_x86 *c) +static void __init init_rise(struct cpuinfo_x86 *c) { printk("CPU: Rise iDragon"); if (c->x86_model > 2) @@ -28,7 +28,7 @@ static void __cpuinit init_rise(struct cpuinfo_x86 *c) set_bit(X86_FEATURE_CX8, c->x86_capability); } -static struct cpu_dev rise_cpu_dev __cpuinitdata = { +static struct cpu_dev rise_cpu_dev __initdata = { .c_vendor = "Rise", .c_ident = { "RiseRiseRise" }, .c_models = { diff --git a/trunk/arch/i386/kernel/cpu/transmeta.c b/trunk/arch/i386/kernel/cpu/transmeta.c index 4056fb7d2cdf..7214c9b577ab 100644 --- a/trunk/arch/i386/kernel/cpu/transmeta.c +++ b/trunk/arch/i386/kernel/cpu/transmeta.c @@ -5,7 +5,7 @@ #include #include "cpu.h" -static void __cpuinit init_transmeta(struct cpuinfo_x86 *c) +static void __init init_transmeta(struct cpuinfo_x86 *c) { unsigned int cap_mask, uk, max, dummy; unsigned int cms_rev1, cms_rev2; @@ -85,9 +85,10 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c) #endif } -static void __cpuinit transmeta_identify(struct cpuinfo_x86 * c) +static void __init transmeta_identify(struct cpuinfo_x86 * c) { u32 xlvl; + generic_identify(c); /* Transmeta-defined flags: level 0x80860001 */ xlvl = cpuid_eax(0x80860000); @@ -97,7 +98,7 @@ static void __cpuinit transmeta_identify(struct cpuinfo_x86 * c) } } -static struct cpu_dev transmeta_cpu_dev __cpuinitdata = { +static struct cpu_dev transmeta_cpu_dev __initdata = { .c_vendor = "Transmeta", .c_ident = { "GenuineTMx86", "TransmetaCPU" }, .c_init = init_transmeta, diff --git a/trunk/arch/i386/kernel/cpu/umc.c b/trunk/arch/i386/kernel/cpu/umc.c index 1bf3f87e9c5b..2cd988f6dc55 100644 --- a/trunk/arch/i386/kernel/cpu/umc.c +++ b/trunk/arch/i386/kernel/cpu/umc.c @@ -5,8 +5,12 @@ /* UMC chips appear to be only either 386 or 486, so no special init takes place. */ +static void __init init_umc(struct cpuinfo_x86 * c) +{ + +} -static struct cpu_dev umc_cpu_dev __cpuinitdata = { +static struct cpu_dev umc_cpu_dev __initdata = { .c_vendor = "UMC", .c_ident = { "UMC UMC UMC" }, .c_models = { @@ -17,6 +21,7 @@ static struct cpu_dev umc_cpu_dev __cpuinitdata = { } }, }, + .c_init = init_umc, }; int __init umc_init_cpu(void) diff --git a/trunk/arch/i386/kernel/crash.c b/trunk/arch/i386/kernel/crash.c index 67d297dc1003..5b96f038367f 100644 --- a/trunk/arch/i386/kernel/crash.c +++ b/trunk/arch/i386/kernel/crash.c @@ -22,8 +22,6 @@ #include #include #include -#include - #include @@ -95,25 +93,16 @@ static void crash_save_self(struct pt_regs *regs) #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) static atomic_t waiting_for_crash_ipi; -static int crash_nmi_callback(struct notifier_block *self, - unsigned long val, void *data) +static int crash_nmi_callback(struct pt_regs *regs, int cpu) { - struct pt_regs *regs; struct pt_regs fixed_regs; - int cpu; - - if (val != DIE_NMI_IPI) - return NOTIFY_OK; - - regs = ((struct die_args *)data)->regs; - cpu = raw_smp_processor_id(); /* Don't do anything if this handler is invoked on crashing cpu. * Otherwise, system will completely hang. Crashing cpu can get * an NMI if system was initially booted with nmi_watchdog parameter. */ if (cpu == crashing_cpu) - return NOTIFY_STOP; + return 1; local_irq_disable(); if (!user_mode_vm(regs)) { @@ -136,18 +125,13 @@ static void smp_send_nmi_allbutself(void) send_IPI_allbutself(NMI_VECTOR); } -static struct notifier_block crash_nmi_nb = { - .notifier_call = crash_nmi_callback, -}; - static void nmi_shootdown_cpus(void) { unsigned long msecs; atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); /* Would it be better to replace the trap vector here? */ - if (register_die_notifier(&crash_nmi_nb)) - return; /* return what? */ + set_nmi_callback(crash_nmi_callback); /* Ensure the new callback function is set before sending * out the NMI */ diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S index 5a63d6fdb70e..87f9f60b803b 100644 --- a/trunk/arch/i386/kernel/entry.S +++ b/trunk/arch/i386/kernel/entry.S @@ -76,15 +76,8 @@ DF_MASK = 0x00000400 NT_MASK = 0x00004000 VM_MASK = 0x00020000 -/* These are replaces for paravirtualization */ -#define DISABLE_INTERRUPTS cli -#define ENABLE_INTERRUPTS sti -#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit -#define INTERRUPT_RETURN iret -#define GET_CR0_INTO_EAX movl %cr0, %eax - #ifdef CONFIG_PREEMPT -#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF +#define preempt_stop cli; TRACE_IRQS_OFF #else #define preempt_stop #define resume_kernel restore_nocheck @@ -183,21 +176,18 @@ VM_MASK = 0x00020000 #define RING0_INT_FRAME \ CFI_STARTPROC simple;\ - CFI_SIGNAL_FRAME;\ CFI_DEF_CFA esp, 3*4;\ /*CFI_OFFSET cs, -2*4;*/\ CFI_OFFSET eip, -3*4 #define RING0_EC_FRAME \ CFI_STARTPROC simple;\ - CFI_SIGNAL_FRAME;\ CFI_DEF_CFA esp, 4*4;\ /*CFI_OFFSET cs, -2*4;*/\ CFI_OFFSET eip, -3*4 #define RING0_PTREGS_FRAME \ CFI_STARTPROC simple;\ - CFI_SIGNAL_FRAME;\ CFI_DEF_CFA esp, OLDESP-EBX;\ /*CFI_OFFSET cs, CS-OLDESP;*/\ CFI_OFFSET eip, EIP-OLDESP;\ @@ -243,11 +233,10 @@ ret_from_intr: check_userspace: movl EFLAGS(%esp), %eax # mix EFLAGS and CS movb CS(%esp), %al - andl $(VM_MASK | SEGMENT_RPL_MASK), %eax - cmpl $USER_RPL, %eax - jb resume_kernel # not returning to v8086 or userspace + testl $(VM_MASK | 3), %eax + jz resume_kernel ENTRY(resume_userspace) - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + cli # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx @@ -258,7 +247,7 @@ ENTRY(resume_userspace) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) - DISABLE_INTERRUPTS + cli cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? jnz restore_nocheck need_resched: @@ -278,7 +267,6 @@ need_resched: # sysenter call handler stub ENTRY(sysenter_entry) CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA esp, 0 CFI_REGISTER esp, ebp movl TSS_sysenter_esp0(%esp),%esp @@ -287,7 +275,7 @@ sysenter_past_esp: * No need to follow this irqs on/off section: the syscall * disabled irqs and here we enable it straight after entry: */ - ENABLE_INTERRUPTS + sti pushl $(__USER_DS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET ss, 0*/ @@ -332,7 +320,7 @@ sysenter_past_esp: jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) - DISABLE_INTERRUPTS + cli TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx @@ -342,7 +330,8 @@ sysenter_past_esp: movl OLDESP(%esp), %ecx xorl %ebp,%ebp TRACE_IRQS_ON - ENABLE_INTERRUPTS_SYSEXIT + sti + sysexit CFI_ENDPROC @@ -367,7 +356,7 @@ syscall_call: call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) # store the return value syscall_exit: - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + cli # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -382,8 +371,8 @@ restore_all: # See comments in process.c:copy_thread() for details. movb OLDSS(%esp), %ah movb CS(%esp), %al - andl $(VM_MASK | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax - cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax + andl $(VM_MASK | (4 << 8) | 3), %eax + cmpl $((4 << 8) | 3), %eax CFI_REMEMBER_STATE je ldt_ss # returning to user-space with LDT SS restore_nocheck: @@ -392,11 +381,11 @@ restore_nocheck_notrace: RESTORE_REGS addl $4, %esp CFI_ADJUST_CFA_OFFSET -4 -1: INTERRUPT_RETURN +1: iret .section .fixup,"ax" iret_exc: TRACE_IRQS_ON - ENABLE_INTERRUPTS + sti pushl $0 # no error code pushl $do_iret_error jmp error_code @@ -420,7 +409,7 @@ ldt_ss: * dosemu and wine happy. */ subl $8, %esp # reserve space for switch16 pointer CFI_ADJUST_CFA_OFFSET 8 - DISABLE_INTERRUPTS + cli TRACE_IRQS_OFF movl %esp, %eax /* Set up the 16bit stack frame with switch32 pointer on top, @@ -430,7 +419,7 @@ ldt_ss: TRACE_IRQS_IRET RESTORE_REGS lss 20+4(%esp), %esp # switch to 16bit stack -1: INTERRUPT_RETURN +1: iret .section __ex_table,"a" .align 4 .long 1b,iret_exc @@ -445,7 +434,7 @@ work_pending: jz work_notifysig work_resched: call schedule - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + cli # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -501,7 +490,7 @@ syscall_exit_work: testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl jz work_pending TRACE_IRQS_ON - ENABLE_INTERRUPTS # could let do_syscall_trace() call + sti # could let do_syscall_trace() call # schedule() instead movl %esp, %eax movl $1, %edx @@ -602,9 +591,11 @@ ENTRY(name) \ /* The include is where all of the SMP etc. interrupts come from */ #include "entry_arch.h" -KPROBE_ENTRY(page_fault) - RING0_EC_FRAME - pushl $do_page_fault +ENTRY(divide_error) + RING0_INT_FRAME + pushl $0 # no error code + CFI_ADJUST_CFA_OFFSET 4 + pushl $do_divide_error CFI_ADJUST_CFA_OFFSET 4 ALIGN error_code: @@ -654,7 +645,6 @@ error_code: call *%edi jmp ret_from_exception CFI_ENDPROC -KPROBE_END(page_fault) ENTRY(coprocessor_error) RING0_INT_FRAME @@ -679,7 +669,7 @@ ENTRY(device_not_available) pushl $-1 # mark this as an int CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL - GET_CR0_INTO_EAX + movl %cr0, %eax testl $0x4, %eax # EM (math emulation bit) jne device_not_available_emulate preempt_stop @@ -712,15 +702,9 @@ device_not_available_emulate: jne ok; \ label: \ movl TSS_sysenter_esp0+offset(%esp),%esp; \ - CFI_DEF_CFA esp, 0; \ - CFI_UNDEFINED eip; \ pushfl; \ - CFI_ADJUST_CFA_OFFSET 4; \ pushl $__KERNEL_CS; \ - CFI_ADJUST_CFA_OFFSET 4; \ - pushl $sysenter_past_esp; \ - CFI_ADJUST_CFA_OFFSET 4; \ - CFI_REL_OFFSET eip, 0 + pushl $sysenter_past_esp KPROBE_ENTRY(debug) RING0_INT_FRAME @@ -736,8 +720,7 @@ debug_stack_correct: call do_debug jmp ret_from_exception CFI_ENDPROC -KPROBE_END(debug) - + .previous .text /* * NMI is doubly nasty. It can happen _while_ we're handling * a debug fault, and the debug fault hasn't yet been able to @@ -746,7 +729,7 @@ KPROBE_END(debug) * check whether we got an NMI on the debug path where the debug * fault happened on the sysenter path. */ -KPROBE_ENTRY(nmi) +ENTRY(nmi) RING0_INT_FRAME pushl %eax CFI_ADJUST_CFA_OFFSET 4 @@ -771,7 +754,6 @@ KPROBE_ENTRY(nmi) cmpl $sysenter_entry,12(%esp) je nmi_debug_stack_check nmi_stack_correct: - /* We have a RING0_INT_FRAME here */ pushl %eax CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL @@ -782,12 +764,9 @@ nmi_stack_correct: CFI_ENDPROC nmi_stack_fixup: - RING0_INT_FRAME FIX_STACK(12,nmi_stack_correct, 1) jmp nmi_stack_correct - nmi_debug_stack_check: - /* We have a RING0_INT_FRAME here */ cmpw $__KERNEL_CS,16(%esp) jne nmi_stack_correct cmpl $debug,(%esp) @@ -798,10 +777,8 @@ nmi_debug_stack_check: jmp nmi_stack_correct nmi_16bit_stack: - /* We have a RING0_INT_FRAME here. - * - * create the pointer to lss back - */ + RING0_INT_FRAME + /* create the pointer to lss back */ pushl %ss CFI_ADJUST_CFA_OFFSET 4 pushl %esp @@ -822,13 +799,12 @@ nmi_16bit_stack: call do_nmi RESTORE_REGS lss 12+4(%esp), %esp # back to 16bit stack -1: INTERRUPT_RETURN +1: iret CFI_ENDPROC .section __ex_table,"a" .align 4 .long 1b,iret_exc .previous -KPROBE_END(nmi) KPROBE_ENTRY(int3) RING0_INT_FRAME @@ -840,7 +816,7 @@ KPROBE_ENTRY(int3) call do_int3 jmp ret_from_exception CFI_ENDPROC -KPROBE_END(int3) + .previous .text ENTRY(overflow) RING0_INT_FRAME @@ -905,7 +881,7 @@ KPROBE_ENTRY(general_protection) CFI_ADJUST_CFA_OFFSET 4 jmp error_code CFI_ENDPROC -KPROBE_END(general_protection) + .previous .text ENTRY(alignment_check) RING0_EC_FRAME @@ -914,14 +890,13 @@ ENTRY(alignment_check) jmp error_code CFI_ENDPROC -ENTRY(divide_error) - RING0_INT_FRAME - pushl $0 # no error code - CFI_ADJUST_CFA_OFFSET 4 - pushl $do_divide_error +KPROBE_ENTRY(page_fault) + RING0_EC_FRAME + pushl $do_page_fault CFI_ADJUST_CFA_OFFSET 4 jmp error_code CFI_ENDPROC + .previous .text #ifdef CONFIG_X86_MCE ENTRY(machine_check) @@ -974,19 +949,6 @@ ENTRY(arch_unwind_init_running) ENDPROC(arch_unwind_init_running) #endif -ENTRY(kernel_thread_helper) - pushl $0 # fake return address for unwinder - CFI_STARTPROC - movl %edx,%eax - push %edx - CFI_ADJUST_CFA_OFFSET 4 - call *%ebx - push %eax - CFI_ADJUST_CFA_OFFSET 4 - call do_exit - CFI_ENDPROC -ENDPROC(kernel_thread_helper) - .section .rodata,"a" #include "syscall_table.S" diff --git a/trunk/arch/i386/kernel/head.S b/trunk/arch/i386/kernel/head.S index be9d883c62ce..a6b8bd89aa27 100644 --- a/trunk/arch/i386/kernel/head.S +++ b/trunk/arch/i386/kernel/head.S @@ -371,65 +371,8 @@ rp_sidt: addl $8,%edi dec %ecx jne rp_sidt - -.macro set_early_handler handler,trapno - lea \handler,%edx - movl $(__KERNEL_CS << 16),%eax - movw %dx,%ax - movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ - lea idt_table,%edi - movl %eax,8*\trapno(%edi) - movl %edx,8*\trapno+4(%edi) -.endm - - set_early_handler handler=early_divide_err,trapno=0 - set_early_handler handler=early_illegal_opcode,trapno=6 - set_early_handler handler=early_protection_fault,trapno=13 - set_early_handler handler=early_page_fault,trapno=14 - ret -early_divide_err: - xor %edx,%edx - pushl $0 /* fake errcode */ - jmp early_fault - -early_illegal_opcode: - movl $6,%edx - pushl $0 /* fake errcode */ - jmp early_fault - -early_protection_fault: - movl $13,%edx - jmp early_fault - -early_page_fault: - movl $14,%edx - jmp early_fault - -early_fault: - cld -#ifdef CONFIG_PRINTK - movl $(__KERNEL_DS),%eax - movl %eax,%ds - movl %eax,%es - cmpl $2,early_recursion_flag - je hlt_loop - incl early_recursion_flag - movl %cr2,%eax - pushl %eax - pushl %edx /* trapno */ - pushl $fault_msg -#ifdef CONFIG_EARLY_PRINTK - call early_printk -#else - call printk -#endif -#endif -hlt_loop: - hlt - jmp hlt_loop - /* This is the default interrupt "handler" :-) */ ALIGN ignore_int: @@ -443,9 +386,6 @@ ignore_int: movl $(__KERNEL_DS),%eax movl %eax,%ds movl %eax,%es - cmpl $2,early_recursion_flag - je hlt_loop - incl early_recursion_flag pushl 16(%esp) pushl 24(%esp) pushl 32(%esp) @@ -491,16 +431,9 @@ ENTRY(stack_start) ready: .byte 0 -early_recursion_flag: - .long 0 - int_msg: .asciz "Unknown interrupt or fault at EIP %p %p %p\n" -fault_msg: - .ascii "Int %d: CR2 %p err %p EIP %p CS %p flags %p\n" - .asciz "Stack: %p %p %p %p %p %p %p %p\n" - /* * The IDT and GDT 'descriptors' are a strange 48-bit object * only used by the lidt and lgdt instructions. They are not diff --git a/trunk/arch/i386/kernel/i8259.c b/trunk/arch/i386/kernel/i8259.c index ea5f4e7958d8..d4756d154f47 100644 --- a/trunk/arch/i386/kernel/i8259.c +++ b/trunk/arch/i386/kernel/i8259.c @@ -45,8 +45,6 @@ static void end_8259A_irq (unsigned int irq) #define shutdown_8259A_irq disable_8259A_irq -static int i8259A_auto_eoi; - static void mask_and_ack_8259A(unsigned int); unsigned int startup_8259A_irq(unsigned int irq) @@ -255,7 +253,7 @@ static void save_ELCR(char *trigger) static int i8259A_resume(struct sys_device *dev) { - init_8259A(i8259A_auto_eoi); + init_8259A(0); restore_ELCR(irq_trigger); return 0; } @@ -303,8 +301,6 @@ void init_8259A(int auto_eoi) { unsigned long flags; - i8259A_auto_eoi = auto_eoi; - spin_lock_irqsave(&i8259A_lock, flags); outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index fd0df75cfbda..4fb32c551fe0 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -40,7 +40,6 @@ #include #include -#include #include "io_ports.h" @@ -66,7 +65,7 @@ int sis_apic_bug = -1; */ int nr_ioapic_registers[MAX_IO_APICS]; -static int disable_timer_pin_1 __initdata; +int disable_timer_pin_1 __initdata; /* * Rough estimation of how many shared IRQs there are, can @@ -94,34 +93,6 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; #define vector_to_irq(vector) (vector) #endif - -union entry_union { - struct { u32 w1, w2; }; - struct IO_APIC_route_entry entry; -}; - -static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) -{ - union entry_union eu; - unsigned long flags; - spin_lock_irqsave(&ioapic_lock, flags); - eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); - eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); - spin_unlock_irqrestore(&ioapic_lock, flags); - return eu.entry; -} - -static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) -{ - unsigned long flags; - union entry_union eu; - eu.entry = e; - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x10 + 2*pin, eu.w1); - io_apic_write(apic, 0x11 + 2*pin, eu.w2); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - /* * The common case is 1:1 IRQ<->pin mappings. Sometimes there are * shared ISA-space IRQs, so we have to support them. We are super @@ -229,9 +200,13 @@ static void unmask_IO_APIC_irq (unsigned int irq) static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) { struct IO_APIC_route_entry entry; + unsigned long flags; /* Check delivery_mode to be sure we're not clearing an SMI pin */ - entry = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); if (entry.delivery_mode == dest_SMI) return; @@ -240,7 +215,10 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) */ memset(&entry, 0, sizeof(entry)); entry.mask = 1; - ioapic_write_entry(apic, pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0)); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1)); + spin_unlock_irqrestore(&ioapic_lock, flags); } static void clear_IO_APIC (void) @@ -1305,8 +1283,9 @@ static void __init setup_IO_APIC_irqs(void) if (!apic && (irq < 16)) disable_8259A_irq(irq); } - ioapic_write_entry(apic, pin, entry); spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); set_native_irq_info(irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -1322,6 +1301,7 @@ static void __init setup_IO_APIC_irqs(void) static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector) { struct IO_APIC_route_entry entry; + unsigned long flags; memset(&entry,0,sizeof(entry)); @@ -1351,7 +1331,10 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in /* * Add it to the IO-APIC irq-routing table: */ - ioapic_write_entry(apic, pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); + spin_unlock_irqrestore(&ioapic_lock, flags); enable_8259A_irq(0); } @@ -1461,7 +1444,10 @@ void __init print_IO_APIC(void) for (i = 0; i <= reg_01.bits.entries; i++) { struct IO_APIC_route_entry entry; - entry = ioapic_read_entry(apic, i); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2); + *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2); + spin_unlock_irqrestore(&ioapic_lock, flags); printk(KERN_DEBUG " %02x %03X %02X ", i, @@ -1680,7 +1666,10 @@ static void __init enable_IO_APIC(void) /* See if any of the pins is in ExtINT mode */ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { struct IO_APIC_route_entry entry; - entry = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); /* If the interrupt line is enabled and in ExtInt mode @@ -1737,6 +1726,7 @@ void disable_IO_APIC(void) */ if (ioapic_i8259.pin != -1) { struct IO_APIC_route_entry entry; + unsigned long flags; memset(&entry, 0, sizeof(entry)); entry.mask = 0; /* Enabled */ @@ -1753,7 +1743,12 @@ void disable_IO_APIC(void) /* * Add it to the IO-APIC irq-routing table: */ - ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin, + *(((int *)&entry)+1)); + io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin, + *(((int *)&entry)+0)); + spin_unlock_irqrestore(&ioapic_lock, flags); } disconnect_bsp_APIC(ioapic_i8259.pin != -1); } @@ -2218,13 +2213,17 @@ static inline void unlock_ExtINT_logic(void) int apic, pin, i; struct IO_APIC_route_entry entry0, entry1; unsigned char save_control, save_freq_select; + unsigned long flags; pin = find_isa_irq_pin(8, mp_INT); apic = find_isa_irq_apic(8, mp_INT); if (pin == -1) return; - entry0 = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); clear_IO_APIC_pin(apic, pin); memset(&entry1, 0, sizeof(entry1)); @@ -2237,7 +2236,10 @@ static inline void unlock_ExtINT_logic(void) entry1.trigger = 0; entry1.vector = 0; - ioapic_write_entry(apic, pin, entry1); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1)); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0)); + spin_unlock_irqrestore(&ioapic_lock, flags); save_control = CMOS_READ(RTC_CONTROL); save_freq_select = CMOS_READ(RTC_FREQ_SELECT); @@ -2256,7 +2258,10 @@ static inline void unlock_ExtINT_logic(void) CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); clear_IO_APIC_pin(apic, pin); - ioapic_write_entry(apic, pin, entry0); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1)); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0)); + spin_unlock_irqrestore(&ioapic_lock, flags); } int timer_uses_ioapic_pin_0; @@ -2456,12 +2461,17 @@ static int ioapic_suspend(struct sys_device *dev, pm_message_t state) { struct IO_APIC_route_entry *entry; struct sysfs_ioapic_data *data; + unsigned long flags; int i; data = container_of(dev, struct sysfs_ioapic_data, dev); entry = data->entry; - for (i = 0; i < nr_ioapic_registers[dev->id]; i ++) - entry[i] = ioapic_read_entry(dev->id, i); + spin_lock_irqsave(&ioapic_lock, flags); + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i); + *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i); + } + spin_unlock_irqrestore(&ioapic_lock, flags); return 0; } @@ -2483,9 +2493,11 @@ static int ioapic_resume(struct sys_device *dev) reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; io_apic_write(dev->id, 0, reg_00.raw); } + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1)); + io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0)); + } spin_unlock_irqrestore(&ioapic_lock, flags); - for (i = 0; i < nr_ioapic_registers[dev->id]; i ++) - ioapic_write_entry(dev->id, i, entry[i]); return 0; } @@ -2682,8 +2694,9 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a if (!ioapic && (irq < 16)) disable_8259A_irq(irq); - ioapic_write_entry(ioapic, pin, entry); spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); @@ -2691,25 +2704,3 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a } #endif /* CONFIG_ACPI */ - -static int __init parse_disable_timer_pin_1(char *arg) -{ - disable_timer_pin_1 = 1; - return 0; -} -early_param("disable_timer_pin_1", parse_disable_timer_pin_1); - -static int __init parse_enable_timer_pin_1(char *arg) -{ - disable_timer_pin_1 = -1; - return 0; -} -early_param("enable_timer_pin_1", parse_enable_timer_pin_1); - -static int __init parse_noapic(char *arg) -{ - /* disable IO-APIC */ - disable_ioapic_setup(); - return 0; -} -early_param("noapic", parse_noapic); diff --git a/trunk/arch/i386/kernel/machine_kexec.c b/trunk/arch/i386/kernel/machine_kexec.c index 91966bafb3dc..6b1ae6ba76f0 100644 --- a/trunk/arch/i386/kernel/machine_kexec.c +++ b/trunk/arch/i386/kernel/machine_kexec.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -21,13 +20,70 @@ #include #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) -static u32 kexec_pgd[1024] PAGE_ALIGNED; -#ifdef CONFIG_X86_PAE -static u32 kexec_pmd0[1024] PAGE_ALIGNED; -static u32 kexec_pmd1[1024] PAGE_ALIGNED; + +#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) +#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) +#define L2_ATTR (_PAGE_PRESENT) + +#define LEVEL0_SIZE (1UL << 12UL) + +#ifndef CONFIG_X86_PAE +#define LEVEL1_SIZE (1UL << 22UL) +static u32 pgtable_level1[1024] PAGE_ALIGNED; + +static void identity_map_page(unsigned long address) +{ + unsigned long level1_index, level2_index; + u32 *pgtable_level2; + + /* Find the current page table */ + pgtable_level2 = __va(read_cr3()); + + /* Find the indexes of the physical address to identity map */ + level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; + level2_index = address / LEVEL1_SIZE; + + /* Identity map the page table entry */ + pgtable_level1[level1_index] = address | L0_ATTR; + pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; + + /* Flush the tlb so the new mapping takes effect. + * Global tlb entries are not flushed but that is not an issue. + */ + load_cr3(pgtable_level2); +} + +#else +#define LEVEL1_SIZE (1UL << 21UL) +#define LEVEL2_SIZE (1UL << 30UL) +static u64 pgtable_level1[512] PAGE_ALIGNED; +static u64 pgtable_level2[512] PAGE_ALIGNED; + +static void identity_map_page(unsigned long address) +{ + unsigned long level1_index, level2_index, level3_index; + u64 *pgtable_level3; + + /* Find the current page table */ + pgtable_level3 = __va(read_cr3()); + + /* Find the indexes of the physical address to identity map */ + level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; + level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE; + level3_index = address / LEVEL2_SIZE; + + /* Identity map the page table entry */ + pgtable_level1[level1_index] = address | L0_ATTR; + pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; + set_64bit(&pgtable_level3[level3_index], + __pa(pgtable_level2) | L2_ATTR); + + /* Flush the tlb so the new mapping takes effect. + * Global tlb entries are not flushed but that is not an issue. + */ + load_cr3(pgtable_level3); +} #endif -static u32 kexec_pte0[1024] PAGE_ALIGNED; -static u32 kexec_pte1[1024] PAGE_ALIGNED; static void set_idt(void *newidt, __u16 limit) { @@ -71,6 +127,16 @@ static void load_segments(void) #undef __STR } +typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( + unsigned long indirection_page, + unsigned long reboot_code_buffer, + unsigned long start_address, + unsigned int has_pae) ATTRIB_NORET; + +extern const unsigned char relocate_new_kernel[]; +extern void relocate_new_kernel_end(void); +extern const unsigned int relocate_new_kernel_size; + /* * A architecture hook called to validate the * proposed image and prepare the control pages @@ -103,29 +169,25 @@ void machine_kexec_cleanup(struct kimage *image) */ NORET_TYPE void machine_kexec(struct kimage *image) { - unsigned long page_list[PAGES_NR]; - void *control_page; + unsigned long page_list; + unsigned long reboot_code_buffer; + + relocate_new_kernel_t rnk; /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); - control_page = page_address(image->control_code_page); - memcpy(control_page, relocate_kernel, PAGE_SIZE); - - page_list[PA_CONTROL_PAGE] = __pa(control_page); - page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; - page_list[PA_PGD] = __pa(kexec_pgd); - page_list[VA_PGD] = (unsigned long)kexec_pgd; -#ifdef CONFIG_X86_PAE - page_list[PA_PMD_0] = __pa(kexec_pmd0); - page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; - page_list[PA_PMD_1] = __pa(kexec_pmd1); - page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; -#endif - page_list[PA_PTE_0] = __pa(kexec_pte0); - page_list[VA_PTE_0] = (unsigned long)kexec_pte0; - page_list[PA_PTE_1] = __pa(kexec_pte1); - page_list[VA_PTE_1] = (unsigned long)kexec_pte1; + /* Compute some offsets */ + reboot_code_buffer = page_to_pfn(image->control_code_page) + << PAGE_SHIFT; + page_list = image->head; + + /* Set up an identity mapping for the reboot_code_buffer */ + identity_map_page(reboot_code_buffer); + + /* copy it out */ + memcpy((void *)reboot_code_buffer, relocate_new_kernel, + relocate_new_kernel_size); /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is @@ -144,28 +206,6 @@ NORET_TYPE void machine_kexec(struct kimage *image) set_idt(phys_to_virt(0),0); /* now call it */ - relocate_kernel((unsigned long)image->head, (unsigned long)page_list, - image->start, cpu_has_pae); -} - -/* crashkernel=size@addr specifies the location to reserve for - * a crash kernel. By reserving this memory we guarantee - * that linux never sets it up as a DMA target. - * Useful for holding code to do something appropriate - * after a kernel panic. - */ -static int __init parse_crashkernel(char *arg) -{ - unsigned long size, base; - size = memparse(arg, &arg); - if (*arg == '@') { - base = memparse(arg+1, &arg); - /* FIXME: Do I want a sanity check - * to validate the memory range? - */ - crashk_res.start = base; - crashk_res.end = base + size - 1; - } - return 0; + rnk = (relocate_new_kernel_t) reboot_code_buffer; + (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae); } -early_param("crashkernel", parse_crashkernel); diff --git a/trunk/arch/i386/kernel/mca.c b/trunk/arch/i386/kernel/mca.c index eb57a851789d..cd5456f14af4 100644 --- a/trunk/arch/i386/kernel/mca.c +++ b/trunk/arch/i386/kernel/mca.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -415,8 +414,7 @@ subsys_initcall(mca_init); /*--------------------------------------------------------------------*/ -static __kprobes void -mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) +static void mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) { int slot = mca_dev->slot; @@ -446,7 +444,7 @@ mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) /*--------------------------------------------------------------------*/ -static int __kprobes mca_handle_nmi_callback(struct device *dev, void *data) +static int mca_handle_nmi_callback(struct device *dev, void *data) { struct mca_device *mca_dev = to_mca_device(dev); unsigned char pos5; @@ -464,7 +462,7 @@ static int __kprobes mca_handle_nmi_callback(struct device *dev, void *data) return 0; } -void __kprobes mca_handle_nmi(void) +void mca_handle_nmi(void) { /* First try - scan the various adapters and see if a specific * adapter was responsible for the error. diff --git a/trunk/arch/i386/kernel/mpparse.c b/trunk/arch/i386/kernel/mpparse.c index 442aaf8c77eb..a70b5fa0ef06 100644 --- a/trunk/arch/i386/kernel/mpparse.c +++ b/trunk/arch/i386/kernel/mpparse.c @@ -30,7 +30,6 @@ #include #include -#include #include #include @@ -69,7 +68,7 @@ unsigned int def_to_bigsmp = 0; /* Processor that is doing the boot up */ unsigned int boot_cpu_physical_apicid = -1U; /* Internal processor count */ -unsigned int __cpuinitdata num_processors; +static unsigned int __devinitdata num_processors; /* Bitmask of physically existing CPUs */ physid_mask_t phys_cpu_present_map; @@ -229,14 +228,12 @@ static void __init MP_bus_info (struct mpc_config_bus *m) mpc_oem_bus_info(m, str, translation_table[mpc_record]); -#if MAX_MP_BUSSES < 256 if (m->mpc_busid >= MAX_MP_BUSSES) { printk(KERN_WARNING "MP table busid value (%d) for bustype %s " " is too large, max. supported is %d\n", m->mpc_busid, str, MAX_MP_BUSSES - 1); return; } -#endif if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; @@ -296,6 +293,19 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m) m->mpc_irqtype, m->mpc_irqflag & 3, (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid, m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); + /* + * Well it seems all SMP boards in existence + * use ExtINT/LVT1 == LINT0 and + * NMI/LVT2 == LINT1 - the following check + * will show us if this assumptions is false. + * Until then we do not have to add baggage. + */ + if ((m->mpc_irqtype == mp_ExtINT) && + (m->mpc_destapiclint != 0)) + BUG(); + if ((m->mpc_irqtype == mp_NMI) && + (m->mpc_destapiclint != 1)) + BUG(); } #ifdef CONFIG_X86_NUMAQ @@ -812,7 +822,8 @@ int es7000_plat; #ifdef CONFIG_ACPI -void __init mp_register_lapic_address(u64 address) +void __init mp_register_lapic_address ( + u64 address) { mp_lapic_addr = (unsigned long) address; @@ -824,10 +835,13 @@ void __init mp_register_lapic_address(u64 address) Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); } -void __devinit mp_register_lapic (u8 id, u8 enabled) + +void __devinit mp_register_lapic ( + u8 id, + u8 enabled) { struct mpc_config_processor processor; - int boot_cpu = 0; + int boot_cpu = 0; if (MAX_APICS - id <= 0) { printk(KERN_WARNING "Processor #%d invalid (max %d)\n", @@ -864,9 +878,11 @@ static struct mp_ioapic_routing { u32 pin_programmed[4]; } mp_ioapic_routing[MAX_IO_APICS]; -static int mp_find_ioapic (int gsi) + +static int mp_find_ioapic ( + int gsi) { - int i = 0; + int i = 0; /* Find the IOAPIC that manages this GSI. */ for (i = 0; i < nr_ioapics; i++) { @@ -879,11 +895,15 @@ static int mp_find_ioapic (int gsi) return -1; } + -void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) +void __init mp_register_ioapic ( + u8 id, + u32 address, + u32 gsi_base) { - int idx = 0; - int tmpid; + int idx = 0; + int tmpid; if (nr_ioapics >= MAX_IO_APICS) { printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " @@ -929,10 +949,16 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end); + + return; } -void __init -mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) + +void __init mp_override_legacy_irq ( + u8 bus_irq, + u8 polarity, + u8 trigger, + u32 gsi) { struct mpc_config_intsrc intsrc; int ioapic = -1; @@ -970,13 +996,15 @@ mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) mp_irqs[mp_irq_entries] = intsrc; if (++mp_irq_entries == MAX_IRQ_SOURCES) panic("Max # of irq sources exceeded!\n"); + + return; } void __init mp_config_acpi_legacy_irqs (void) { struct mpc_config_intsrc intsrc; - int i = 0; - int ioapic = -1; + int i = 0; + int ioapic = -1; /* * Fabricate the legacy ISA bus (bus #31). @@ -1045,12 +1073,12 @@ void __init mp_config_acpi_legacy_irqs (void) #define MAX_GSI_NUM 4096 -int mp_register_gsi(u32 gsi, int triggering, int polarity) +int mp_register_gsi (u32 gsi, int triggering, int polarity) { - int ioapic = -1; - int ioapic_pin = 0; - int idx, bit = 0; - static int pci_irq = 16; + int ioapic = -1; + int ioapic_pin = 0; + int idx, bit = 0; + static int pci_irq = 16; /* * Mapping between Global System Interrups, which * represent all possible interrupts, and IRQs diff --git a/trunk/arch/i386/kernel/nmi.c b/trunk/arch/i386/kernel/nmi.c index dbda706fdd14..acb351478e42 100644 --- a/trunk/arch/i386/kernel/nmi.c +++ b/trunk/arch/i386/kernel/nmi.c @@ -21,174 +21,83 @@ #include #include #include -#include -#include #include #include -#include #include #include "mach_traps.h" -/* perfctr_nmi_owner tracks the ownership of the perfctr registers: - * evtsel_nmi_owner tracks the ownership of the event selection - * - different performance counters/ event selection may be reserved for - * different subsystems this reservation system just tries to coordinate - * things a little - */ -static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner); -static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]); +unsigned int nmi_watchdog = NMI_NONE; +extern int unknown_nmi_panic; +static unsigned int nmi_hz = HZ; +static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ +static unsigned int nmi_p4_cccr_val; +extern void show_registers(struct pt_regs *regs); -/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's - * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) +/* + * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: + * - it may be reserved by some other driver, or not + * - when not reserved by some other driver, it may be used for + * the NMI watchdog, or not + * + * This is maintained separately from nmi_active because the NMI + * watchdog may also be driven from the I/O APIC timer. */ -#define NMI_MAX_COUNTER_BITS 66 +static DEFINE_SPINLOCK(lapic_nmi_owner_lock); +static unsigned int lapic_nmi_owner; +#define LAPIC_NMI_WATCHDOG (1<<0) +#define LAPIC_NMI_RESERVED (1<<1) /* nmi_active: - * >0: the lapic NMI watchdog is active, but can be disabled - * <0: the lapic NMI watchdog has not been set up, and cannot + * +1: the lapic NMI watchdog is active, but can be disabled + * 0: the lapic NMI watchdog has not been set up, and cannot * be enabled - * 0: the lapic NMI watchdog is disabled, but can be enabled + * -1: the lapic NMI watchdog is disabled, but can be enabled */ -atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ - -unsigned int nmi_watchdog = NMI_DEFAULT; -static unsigned int nmi_hz = HZ; - -struct nmi_watchdog_ctlblk { - int enabled; - u64 check_bit; - unsigned int cccr_msr; - unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ - unsigned int evntsel_msr; /* the MSR to select the events to handle */ -}; -static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); - -/* local prototypes */ -static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); - -extern void show_registers(struct pt_regs *regs); -extern int unknown_nmi_panic; - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the performance counter register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_PERFCTR0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_PERFCTR0); - - switch (boot_cpu_data.x86) { - case 6: - return (msr - MSR_P6_PERFCTR0); - case 15: - return (msr - MSR_P4_BPU_PERFCTR0); - } - } - return 0; -} - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the event selection register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_EVNTSEL0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_EVENTSEL0); - - switch (boot_cpu_data.x86) { - case 6: - return (msr - MSR_P6_EVNTSEL0); - case 15: - return (msr - MSR_P4_BSU_ESCR0); - } - } - return 0; -} - -/* checks for a bit availability (hack for oprofile) */ -int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) -{ - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); -} - -/* checks the an msr for availability */ -int avail_to_resrv_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); -} - -int reserve_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner))) - return 1; - return 0; -} - -void release_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner)); -} - -int reserve_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); +int nmi_active; - if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0])) - return 1; - return 0; -} - -void release_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; +#define K7_EVNTSEL_ENABLE (1 << 22) +#define K7_EVNTSEL_INT (1 << 20) +#define K7_EVNTSEL_OS (1 << 17) +#define K7_EVNTSEL_USR (1 << 16) +#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 +#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); +#define P6_EVNTSEL0_ENABLE (1 << 22) +#define P6_EVNTSEL_INT (1 << 20) +#define P6_EVNTSEL_OS (1 << 17) +#define P6_EVNTSEL_USR (1 << 16) +#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 +#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED - clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]); -} +#define MSR_P4_MISC_ENABLE 0x1A0 +#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) +#define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12) +#define MSR_P4_PERFCTR0 0x300 +#define MSR_P4_CCCR0 0x360 +#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) +#define P4_ESCR_OS (1<<3) +#define P4_ESCR_USR (1<<2) +#define P4_CCCR_OVF_PMI0 (1<<26) +#define P4_CCCR_OVF_PMI1 (1<<27) +#define P4_CCCR_THRESHOLD(N) ((N)<<20) +#define P4_CCCR_COMPLEMENT (1<<19) +#define P4_CCCR_COMPARE (1<<18) +#define P4_CCCR_REQUIRED (3<<16) +#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) +#define P4_CCCR_ENABLE (1<<12) +/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter + CRU_ESCR0 (with any non-null event selector) through a complemented + max threshold. [IA32-Vol3, Section 14.9.9] */ +#define MSR_P4_IQ_COUNTER0 0x30C +#define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR) +#define P4_NMI_IQ_CCCR0 \ + (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ + P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) -static __cpuinit inline int nmi_known_cpu(void) -{ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6)); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return 1; - else - return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6)); - } - return 0; -} +#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL +#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK #ifdef CONFIG_SMP /* The performance counters used by NMI_LOCAL_APIC don't trigger when @@ -216,18 +125,7 @@ static int __init check_nmi_watchdog(void) unsigned int *prev_nmi_count; int cpu; - /* Enable NMI watchdog for newer systems. - Actually it should be safe for most systems before 2004 too except - for some IBM systems that corrupt registers when NMI happens - during SMM. Unfortunately we don't have more exact information - on these and use this coarse check. */ - if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004) - nmi_watchdog = NMI_LOCAL_APIC; - - if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) - return 0; - - if (!atomic_read(&nmi_active)) + if (nmi_watchdog == NMI_NONE) return 0; prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); @@ -251,45 +149,25 @@ static int __init check_nmi_watchdog(void) if (!cpu_isset(cpu, cpu_callin_map)) continue; #endif - if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled) - continue; if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) { + endflag = 1; printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", cpu, prev_nmi_count[cpu], nmi_count(cpu)); - per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0; - atomic_dec(&nmi_active); + nmi_active = 0; + lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; + kfree(prev_nmi_count); + return -1; } } - if (!atomic_read(&nmi_active)) { - kfree(prev_nmi_count); - atomic_set(&nmi_active, -1); - return -1; - } endflag = 1; printk("OK.\n"); /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ - if (nmi_watchdog == NMI_LOCAL_APIC) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - + if (nmi_watchdog == NMI_LOCAL_APIC) nmi_hz = 1; - /* - * On Intel CPUs with ARCH_PERFMON only 32 bits in the counter - * are writable, with higher bits sign extending from bit 31. - * So, we can only program the counter with 31 bit values and - * 32nd bit should be 1, for 33.. to be 1. - * Find the appropriate nmi_hz - */ - if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0 && - ((u64)cpu_khz * 1000) > 0x7fffffffULL) { - u64 count = (u64)cpu_khz * 1000; - do_div(count, 0x7fffffffUL); - nmi_hz = count + 1; - } - } kfree(prev_nmi_count); return 0; @@ -303,70 +181,124 @@ static int __init setup_nmi_watchdog(char *str) get_option(&str, &nmi); - if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE)) + if (nmi >= NMI_INVALID) return 0; + if (nmi == NMI_NONE) + nmi_watchdog = nmi; /* * If any other x86 CPU has a local APIC, then * please test the NMI stuff there and send me the * missing bits. Right now Intel P6/P4 and AMD K7 only. */ - if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0)) - return 0; /* no lapic support */ - nmi_watchdog = nmi; + if ((nmi == NMI_LOCAL_APIC) && + (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && + (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15)) + nmi_watchdog = nmi; + if ((nmi == NMI_LOCAL_APIC) && + (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && + (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15)) + nmi_watchdog = nmi; + /* + * We can enable the IO-APIC watchdog + * unconditionally. + */ + if (nmi == NMI_IO_APIC) { + nmi_active = 1; + nmi_watchdog = nmi; + } return 1; } __setup("nmi_watchdog=", setup_nmi_watchdog); +static void disable_intel_arch_watchdog(void); + static void disable_lapic_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - if (atomic_read(&nmi_active) <= 0) + if (nmi_active <= 0) return; + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + wrmsr(MSR_K7_EVNTSEL0, 0, 0); + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + disable_intel_arch_watchdog(); + break; + } + switch (boot_cpu_data.x86) { + case 6: + if (boot_cpu_data.x86_model > 0xd) + break; - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); + wrmsr(MSR_P6_EVNTSEL0, 0, 0); + break; + case 15: + if (boot_cpu_data.x86_model > 0x4) + break; - BUG_ON(atomic_read(&nmi_active) != 0); + wrmsr(MSR_P4_IQ_CCCR0, 0, 0); + wrmsr(MSR_P4_CRU_ESCR0, 0, 0); + break; + } + break; + } + nmi_active = -1; + /* tell do_nmi() and others that we're not active any more */ + nmi_watchdog = 0; } static void enable_lapic_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + if (nmi_active < 0) { + nmi_watchdog = NMI_LOCAL_APIC; + setup_apic_nmi_watchdog(); + } +} - /* are we already enabled */ - if (atomic_read(&nmi_active) != 0) - return; +int reserve_lapic_nmi(void) +{ + unsigned int old_owner; - /* are we lapic aware */ - if (nmi_known_cpu() <= 0) - return; + spin_lock(&lapic_nmi_owner_lock); + old_owner = lapic_nmi_owner; + lapic_nmi_owner |= LAPIC_NMI_RESERVED; + spin_unlock(&lapic_nmi_owner_lock); + if (old_owner & LAPIC_NMI_RESERVED) + return -EBUSY; + if (old_owner & LAPIC_NMI_WATCHDOG) + disable_lapic_nmi_watchdog(); + return 0; +} - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - touch_nmi_watchdog(); +void release_lapic_nmi(void) +{ + unsigned int new_owner; + + spin_lock(&lapic_nmi_owner_lock); + new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED; + lapic_nmi_owner = new_owner; + spin_unlock(&lapic_nmi_owner_lock); + if (new_owner & LAPIC_NMI_WATCHDOG) + enable_lapic_nmi_watchdog(); } void disable_timer_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) <= 0) + if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0)) return; - disable_irq(0); - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); + unset_nmi_callback(); + nmi_active = -1; + nmi_watchdog = NMI_NONE; } void enable_timer_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) == 0) { + if (nmi_active < 0) { + nmi_watchdog = NMI_IO_APIC; touch_nmi_watchdog(); - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - enable_irq(0); + nmi_active = 1; } } @@ -376,20 +308,15 @@ static int nmi_pm_active; /* nmi_active before suspend */ static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) { - /* only CPU0 goes here, other CPUs should be offline */ - nmi_pm_active = atomic_read(&nmi_active); - stop_apic_nmi_watchdog(NULL); - BUG_ON(atomic_read(&nmi_active) != 0); + nmi_pm_active = nmi_active; + disable_lapic_nmi_watchdog(); return 0; } static int lapic_nmi_resume(struct sys_device *dev) { - /* only CPU0 goes here, other CPUs should be offline */ - if (nmi_pm_active > 0) { - setup_apic_nmi_watchdog(NULL); - touch_nmi_watchdog(); - } + if (nmi_pm_active > 0) + enable_lapic_nmi_watchdog(); return 0; } @@ -409,13 +336,7 @@ static int __init init_lapic_nmi_sysfs(void) { int error; - /* should really be a BUG_ON but b/c this is an - * init call, it just doesn't work. -dcz - */ - if (nmi_watchdog != NMI_LOCAL_APIC) - return 0; - - if ( atomic_read(&nmi_active) < 0 ) + if (nmi_active == 0 || nmi_watchdog != NMI_LOCAL_APIC) return 0; error = sysdev_class_register(&nmi_sysclass); @@ -433,269 +354,138 @@ late_initcall(init_lapic_nmi_sysfs); * Original code written by Keith Owens. */ -static void write_watchdog_counter(unsigned int perfctr_msr, const char *descr) +static void clear_msr_range(unsigned int base, unsigned int n) +{ + unsigned int i; + + for(i = 0; i < n; ++i) + wrmsr(base+i, 0, 0); +} + +static void write_watchdog_counter(const char *descr) { u64 count = (u64)cpu_khz * 1000; do_div(count, nmi_hz); if(descr) Dprintk("setting %s to -0x%08Lx\n", descr, count); - wrmsrl(perfctr_msr, 0 - count); + wrmsrl(nmi_perfctr_msr, 0 - count); } -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define K7_EVNTSEL_ENABLE (1 << 22) -#define K7_EVNTSEL_INT (1 << 20) -#define K7_EVNTSEL_OS (1 << 17) -#define K7_EVNTSEL_USR (1 << 16) -#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 -#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING - -static int setup_k7_watchdog(void) +static void setup_k7_watchdog(void) { - unsigned int perfctr_msr, evntsel_msr; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_K7_PERFCTR0; - evntsel_msr = MSR_K7_EVNTSEL0; - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_K7_PERFCTR0; - wrmsrl(perfctr_msr, 0UL); + clear_msr_range(MSR_K7_EVNTSEL0, 4); + clear_msr_range(MSR_K7_PERFCTR0, 4); evntsel = K7_EVNTSEL_INT | K7_EVNTSEL_OS | K7_EVNTSEL_USR | K7_NMI_EVENT; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - write_watchdog_counter(perfctr_msr, "K7_PERFCTR0"); + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); + write_watchdog_counter("K7_PERFCTR0"); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= K7_EVNTSEL_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL<<63; - return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; -} - -static void stop_k7_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); - - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); } -#define P6_EVNTSEL0_ENABLE (1 << 22) -#define P6_EVNTSEL_INT (1 << 20) -#define P6_EVNTSEL_OS (1 << 17) -#define P6_EVNTSEL_USR (1 << 16) -#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 -#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED - -static int setup_p6_watchdog(void) +static void setup_p6_watchdog(void) { - unsigned int perfctr_msr, evntsel_msr; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_P6_PERFCTR0; - evntsel_msr = MSR_P6_EVNTSEL0; - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_P6_PERFCTR0; - wrmsrl(perfctr_msr, 0UL); + clear_msr_range(MSR_P6_EVNTSEL0, 2); + clear_msr_range(MSR_P6_PERFCTR0, 2); evntsel = P6_EVNTSEL_INT | P6_EVNTSEL_OS | P6_EVNTSEL_USR | P6_NMI_EVENT; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - write_watchdog_counter(perfctr_msr, "P6_PERFCTR0"); + wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); + write_watchdog_counter("P6_PERFCTR0"); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= P6_EVNTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL<<39; - return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; -} - -static void stop_p6_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); - - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); } -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) -#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) -#define P4_ESCR_OS (1<<3) -#define P4_ESCR_USR (1<<2) -#define P4_CCCR_OVF_PMI0 (1<<26) -#define P4_CCCR_OVF_PMI1 (1<<27) -#define P4_CCCR_THRESHOLD(N) ((N)<<20) -#define P4_CCCR_COMPLEMENT (1<<19) -#define P4_CCCR_COMPARE (1<<18) -#define P4_CCCR_REQUIRED (3<<16) -#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) -#define P4_CCCR_ENABLE (1<<12) -#define P4_CCCR_OVF (1<<31) -/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter - CRU_ESCR0 (with any non-null event selector) through a complemented - max threshold. [IA32-Vol3, Section 14.9.9] */ - static int setup_p4_watchdog(void) { - unsigned int perfctr_msr, evntsel_msr, cccr_msr; - unsigned int evntsel, cccr_val; unsigned int misc_enable, dummy; - unsigned int ht_num; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); + rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy); if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) return 0; + nmi_perfctr_msr = MSR_P4_IQ_COUNTER0; + nmi_p4_cccr_val = P4_NMI_IQ_CCCR0; #ifdef CONFIG_SMP - /* detect which hyperthread we are on */ - if (smp_num_siblings == 2) { - unsigned int ebx, apicid; - - ebx = cpuid_ebx(1); - apicid = (ebx >> 24) & 0xff; - ht_num = apicid & 1; - } else + if (smp_num_siblings == 2) + nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1; #endif - ht_num = 0; - /* performance counters are shared resources - * assign each hyperthread its own set - * (re-use the ESCR0 register, seems safe - * and keeps the cccr_val the same) - */ - if (!ht_num) { - /* logical cpu 0 */ - perfctr_msr = MSR_P4_IQ_PERFCTR0; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR0; - cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); + if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL)) + clear_msr_range(0x3F1, 2); + /* MSR 0x3F0 seems to have a default value of 0xFC00, but current + docs doesn't fully define it, so leave it alone for now. */ + if (boot_cpu_data.x86_model >= 0x3) { + /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */ + clear_msr_range(0x3A0, 26); + clear_msr_range(0x3BC, 3); } else { - /* logical cpu 1 */ - perfctr_msr = MSR_P4_IQ_PERFCTR1; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR1; - cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); + clear_msr_range(0x3A0, 31); } - - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; - - evntsel = P4_ESCR_EVENT_SELECT(0x3F) - | P4_ESCR_OS - | P4_ESCR_USR; - - cccr_val |= P4_CCCR_THRESHOLD(15) - | P4_CCCR_COMPLEMENT - | P4_CCCR_COMPARE - | P4_CCCR_REQUIRED; - - wrmsr(evntsel_msr, evntsel, 0); - wrmsr(cccr_msr, cccr_val, 0); - write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0"); + clear_msr_range(0x3C0, 6); + clear_msr_range(0x3C8, 6); + clear_msr_range(0x3E0, 2); + clear_msr_range(MSR_P4_CCCR0, 18); + clear_msr_range(MSR_P4_PERFCTR0, 18); + + wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); + wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); + write_watchdog_counter("P4_IQ_COUNTER0"); apic_write(APIC_LVTPC, APIC_DM_NMI); - cccr_val |= P4_CCCR_ENABLE; - wrmsr(cccr_msr, cccr_val, 0); - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = cccr_msr; - wd->check_bit = 1ULL<<39; + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; } -static void stop_p4_watchdog(void) +static void disable_intel_arch_watchdog(void) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->cccr_msr, 0, 0); - wrmsr(wd->evntsel_msr, 0, 0); + unsigned ebx; - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebp indicates event present. + */ + ebx = cpuid_ebx(10); + if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0); } -#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL -#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - static int setup_intel_arch_watchdog(void) { - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - unsigned int perfctr_msr, evntsel_msr; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + unsigned ebx; /* * Check whether the Architectural PerfMon supports * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. + * NOTE: Corresponding bit = 0 in ebp indicates event present. */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - goto fail; - - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; - - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; + ebx = cpuid_ebx(10); + if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + return 0; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - wrmsrl(perfctr_msr, 0UL); + clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); + clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); evntsel = ARCH_PERFMON_EVENTSEL_INT | ARCH_PERFMON_EVENTSEL_OS @@ -703,145 +493,51 @@ static int setup_intel_arch_watchdog(void) | ARCH_PERFMON_NMI_EVENT_SEL | ARCH_PERFMON_NMI_EVENT_UMASK; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - write_watchdog_counter(perfctr_msr, "INTEL_ARCH_PERFCTR0"); + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); + write_watchdog_counter("INTEL_ARCH_PERFCTR0"); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL << (eax.split.bit_width - 1); + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; -} - -static void stop_intel_arch_watchdog(void) -{ - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. - */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - return; - - wrmsr(wd->evntsel_msr, 0, 0); - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); } -void setup_apic_nmi_watchdog (void *unused) +void setup_apic_nmi_watchdog (void) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; - - if (wd->enabled == 1) - return; - - /* cheap hack to support suspend/resume */ - /* if cpu0 is not active neither should the other cpus */ - if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0)) - return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15) + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15) + return; + setup_k7_watchdog(); + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + if (!setup_intel_arch_watchdog()) return; - if (!setup_k7_watchdog()) + break; + } + switch (boot_cpu_data.x86) { + case 6: + if (boot_cpu_data.x86_model > 0xd) return; + + setup_p6_watchdog(); break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - if (!setup_intel_arch_watchdog()) - return; - break; - } - switch (boot_cpu_data.x86) { - case 6: - if (boot_cpu_data.x86_model > 0xd) - return; - - if (!setup_p6_watchdog()) - return; - break; - case 15: - if (boot_cpu_data.x86_model > 0x4) - return; + case 15: + if (boot_cpu_data.x86_model > 0x4) + return; - if (!setup_p4_watchdog()) - return; - break; - default: + if (!setup_p4_watchdog()) return; - } break; default: return; } - } - wd->enabled = 1; - atomic_inc(&nmi_active); -} - -void stop_apic_nmi_watchdog(void *unused) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; - - if (wd->enabled == 0) + break; + default: return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - stop_k7_watchdog(); - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - stop_intel_arch_watchdog(); - break; - } - switch (boot_cpu_data.x86) { - case 6: - if (boot_cpu_data.x86_model > 0xd) - break; - stop_p6_watchdog(); - break; - case 15: - if (boot_cpu_data.x86_model > 0x4) - break; - stop_p4_watchdog(); - break; - } - break; - default: - return; - } } - wd->enabled = 0; - atomic_dec(&nmi_active); + lapic_nmi_owner = LAPIC_NMI_WATCHDOG; + nmi_active = 1; } /* @@ -883,7 +579,7 @@ EXPORT_SYMBOL(touch_nmi_watchdog); extern void die_nmi(struct pt_regs *, const char *msg); -__kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) +void nmi_watchdog_tick (struct pt_regs * regs) { /* @@ -892,23 +588,11 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) * smp_processor_id(). */ unsigned int sum; - int touched = 0; int cpu = smp_processor_id(); - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - u64 dummy; - int rc=0; - - /* check for other users first */ - if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) - == NOTIFY_STOP) { - rc = 1; - touched = 1; - } sum = per_cpu(irq_stat, cpu).apic_timer_irqs; - /* if the apic timer isn't firing, this cpu isn't doing much */ - if (!touched && last_irq_sums[cpu] == sum) { + if (last_irq_sums[cpu] == sum) { /* * Ayiee, looks like this CPU is stuck ... * wait a few IRQs (5 seconds) before doing the oops ... @@ -923,59 +607,27 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) last_irq_sums[cpu] = sum; alert_counter[cpu] = 0; } - /* see if the nmi watchdog went off */ - if (wd->enabled) { - if (nmi_watchdog == NMI_LOCAL_APIC) { - rdmsrl(wd->perfctr_msr, dummy); - if (dummy & wd->check_bit){ - /* this wasn't a watchdog timer interrupt */ - goto done; - } - - /* only Intel P4 uses the cccr msr */ - if (wd->cccr_msr != 0) { - /* - * P4 quirks: - * - An overflown perfctr will assert its interrupt - * until the OVF flag in its CCCR is cleared. - * - LVTPC is masked on interrupt and must be - * unmasked by the LVTPC handler. - */ - rdmsrl(wd->cccr_msr, dummy); - dummy &= ~P4_CCCR_OVF; - wrmsrl(wd->cccr_msr, dummy); - apic_write(APIC_LVTPC, APIC_DM_NMI); - } - else if (wd->perfctr_msr == MSR_P6_PERFCTR0 || - wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { - /* P6 based Pentium M need to re-unmask - * the apic vector but it doesn't hurt - * other P6 variant. - * ArchPerfom/Core Duo also needs this */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - } - /* start the cycle over again */ - write_watchdog_counter(wd->perfctr_msr, NULL); - rc = 1; - } else if (nmi_watchdog == NMI_IO_APIC) { - /* don't know how to accurately check for this. - * just assume it was a watchdog timer interrupt - * This matches the old behaviour. + if (nmi_perfctr_msr) { + if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) { + /* + * P4 quirks: + * - An overflown perfctr will assert its interrupt + * until the OVF flag in its CCCR is cleared. + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. */ - rc = 1; + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); + apic_write(APIC_LVTPC, APIC_DM_NMI); } + else if (nmi_perfctr_msr == MSR_P6_PERFCTR0 || + nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + /* Only P6 based Pentium M need to re-unmask + * the apic vector but it doesn't hurt + * other P6 variant */ + apic_write(APIC_LVTPC, APIC_DM_NMI); + } + write_watchdog_counter(NULL); } -done: - return rc; -} - -int do_nmi_callback(struct pt_regs * regs, int cpu) -{ -#ifdef CONFIG_SYSCTL - if (unknown_nmi_panic) - return unknown_nmi_panic_callback(regs, cpu); -#endif - return 0; } #ifdef CONFIG_SYSCTL @@ -985,46 +637,36 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) unsigned char reason = get_nmi_reason(); char buf[64]; - sprintf(buf, "NMI received for unknown reason %02x\n", reason); - die_nmi(regs, buf); + if (!(reason & 0xc0)) { + sprintf(buf, "NMI received for unknown reason %02x\n", reason); + die_nmi(regs, buf); + } return 0; } /* - * proc handler for /proc/sys/kernel/nmi + * proc handler for /proc/sys/kernel/unknown_nmi_panic */ -int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, +int proc_unknown_nmi_panic(ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, loff_t *ppos) { int old_state; - nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0; - old_state = nmi_watchdog_enabled; + old_state = unknown_nmi_panic; proc_dointvec(table, write, file, buffer, length, ppos); - if (!!old_state == !!nmi_watchdog_enabled) + if (!!old_state == !!unknown_nmi_panic) return 0; - if (atomic_read(&nmi_active) < 0) { - printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); - return -EIO; - } - - if (nmi_watchdog == NMI_DEFAULT) { - if (nmi_known_cpu() > 0) - nmi_watchdog = NMI_LOCAL_APIC; - else - nmi_watchdog = NMI_IO_APIC; - } - - if (nmi_watchdog == NMI_LOCAL_APIC) { - if (nmi_watchdog_enabled) - enable_lapic_nmi_watchdog(); - else - disable_lapic_nmi_watchdog(); + if (unknown_nmi_panic) { + if (reserve_lapic_nmi() < 0) { + unknown_nmi_panic = 0; + return -EBUSY; + } else { + set_nmi_callback(unknown_nmi_panic_callback); + } } else { - printk( KERN_WARNING - "NMI watchdog doesn't know what hardware to touch\n"); - return -EIO; + release_lapic_nmi(); + unset_nmi_callback(); } return 0; } @@ -1033,11 +675,7 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); -EXPORT_SYMBOL(reserve_perfctr_nmi); -EXPORT_SYMBOL(release_perfctr_nmi); -EXPORT_SYMBOL(reserve_evntsel_nmi); -EXPORT_SYMBOL(release_evntsel_nmi); +EXPORT_SYMBOL(reserve_lapic_nmi); +EXPORT_SYMBOL(release_lapic_nmi); EXPORT_SYMBOL(disable_timer_nmi_watchdog); EXPORT_SYMBOL(enable_timer_nmi_watchdog); diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index 8c190ca7ae44..8657c739656a 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -321,6 +320,15 @@ void show_regs(struct pt_regs * regs) * the "args". */ extern void kernel_thread_helper(void); +__asm__(".section .text\n" + ".align 4\n" + "kernel_thread_helper:\n\t" + "movl %edx,%eax\n\t" + "pushl %edx\n\t" + "call *%ebx\n\t" + "pushl %eax\n\t" + "call do_exit\n" + ".previous"); /* * Create a kernel thread @@ -338,7 +346,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) regs.xes = __USER_DS; regs.orig_eax = -1; regs.eip = (unsigned long) kernel_thread_helper; - regs.xcs = __KERNEL_CS | get_kernel_rpl(); + regs.xcs = __KERNEL_CS; regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; /* Ok, create the new process.. */ @@ -897,7 +905,7 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) unsigned long arch_align_stack(unsigned long sp) { - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + if (randomize_va_space) sp -= get_random_int() % 8192; return sp & ~0xf; } diff --git a/trunk/arch/i386/kernel/ptrace.c b/trunk/arch/i386/kernel/ptrace.c index 775f50e9395b..d3db03f4085d 100644 --- a/trunk/arch/i386/kernel/ptrace.c +++ b/trunk/arch/i386/kernel/ptrace.c @@ -185,17 +185,17 @@ static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_ return addr; } -static inline int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) +static inline int is_at_popf(struct task_struct *child, struct pt_regs *regs) { int i, copied; - unsigned char opcode[15]; + unsigned char opcode[16]; unsigned long addr = convert_eip_to_linear(child, regs); copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); for (i = 0; i < copied; i++) { switch (opcode[i]) { - /* popf and iret */ - case 0x9d: case 0xcf: + /* popf */ + case 0x9d: return 1; /* opcode and address size prefixes */ case 0x66: case 0x67: @@ -247,7 +247,7 @@ static void set_singlestep(struct task_struct *child) * don't mark it as being "us" that set it, so that we * won't clear it by hand later. */ - if (is_setting_trap_flag(child, regs)) + if (is_at_popf(child, regs)) return; child->ptrace |= PT_DTRACE; diff --git a/trunk/arch/i386/kernel/relocate_kernel.S b/trunk/arch/i386/kernel/relocate_kernel.S index f151d6fae462..d312616effa1 100644 --- a/trunk/arch/i386/kernel/relocate_kernel.S +++ b/trunk/arch/i386/kernel/relocate_kernel.S @@ -7,138 +7,16 @@ */ #include -#include -#include - -/* - * Must be relocatable PIC code callable as a C function - */ - -#define PTR(x) (x << 2) -#define PAGE_ALIGNED (1 << PAGE_SHIFT) -#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */ -#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */ - - .text - .align PAGE_ALIGNED - .globl relocate_kernel -relocate_kernel: - movl 8(%esp), %ebp /* list of pages */ - -#ifdef CONFIG_X86_PAE - /* map the control page at its virtual address */ - - movl PTR(VA_PGD)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0xc0000000, %eax - shrl $27, %eax - addl %edi, %eax - - movl PTR(PA_PMD_0)(%ebp), %edx - orl $PAE_PGD_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PMD_0)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0x3fe00000, %eax - shrl $18, %eax - addl %edi, %eax - - movl PTR(PA_PTE_0)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PTE_0)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0x001ff000, %eax - shrl $9, %eax - addl %edi, %eax - - movl PTR(PA_CONTROL_PAGE)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - /* identity map the control page at its physical address */ - - movl PTR(VA_PGD)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0xc0000000, %eax - shrl $27, %eax - addl %edi, %eax - - movl PTR(PA_PMD_1)(%ebp), %edx - orl $PAE_PGD_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PMD_1)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0x3fe00000, %eax - shrl $18, %eax - addl %edi, %eax - - movl PTR(PA_PTE_1)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PTE_1)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0x001ff000, %eax - shrl $9, %eax - addl %edi, %eax - - movl PTR(PA_CONTROL_PAGE)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) -#else - /* map the control page at its virtual address */ - - movl PTR(VA_PGD)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0xffc00000, %eax - shrl $20, %eax - addl %edi, %eax - - movl PTR(PA_PTE_0)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PTE_0)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0x003ff000, %eax - shrl $10, %eax - addl %edi, %eax - - movl PTR(PA_CONTROL_PAGE)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - /* identity map the control page at its physical address */ - - movl PTR(VA_PGD)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0xffc00000, %eax - shrl $20, %eax - addl %edi, %eax - - movl PTR(PA_PTE_1)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PTE_1)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0x003ff000, %eax - shrl $10, %eax - addl %edi, %eax - - movl PTR(PA_CONTROL_PAGE)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) -#endif + /* + * Must be relocatable PIC code callable as a C function, that once + * it starts can not use the previous processes stack. + */ + .globl relocate_new_kernel relocate_new_kernel: /* read the arguments and say goodbye to the stack */ movl 4(%esp), %ebx /* page_list */ - movl 8(%esp), %ebp /* list of pages */ + movl 8(%esp), %ebp /* reboot_code_buffer */ movl 12(%esp), %edx /* start address */ movl 16(%esp), %ecx /* cpu_has_pae */ @@ -146,26 +24,11 @@ relocate_new_kernel: pushl $0 popfl - /* get physical address of control page now */ - /* this is impossible after page table switch */ - movl PTR(PA_CONTROL_PAGE)(%ebp), %edi + /* set a new stack at the bottom of our page... */ + lea 4096(%ebp), %esp - /* switch to new set of page tables */ - movl PTR(PA_PGD)(%ebp), %eax - movl %eax, %cr3 - - /* setup a new stack at the end of the physical control page */ - lea 4096(%edi), %esp - - /* jump to identity mapped page */ - movl %edi, %eax - addl $(identity_mapped - relocate_kernel), %eax - pushl %eax - ret - -identity_mapped: - /* store the start address on the stack */ - pushl %edx + /* store the parameters back on the stack */ + pushl %edx /* store the start address */ /* Set cr0 to a known state: * 31 0 == Paging disabled @@ -250,3 +113,8 @@ identity_mapped: xorl %edi, %edi xorl %ebp, %ebp ret +relocate_new_kernel_end: + + .globl relocate_new_kernel_size +relocate_new_kernel_size: + .long relocate_new_kernel_end - relocate_new_kernel diff --git a/trunk/arch/i386/kernel/semaphore.c b/trunk/arch/i386/kernel/semaphore.c new file mode 100644 index 000000000000..98352c374c76 --- /dev/null +++ b/trunk/arch/i386/kernel/semaphore.c @@ -0,0 +1,134 @@ +/* + * i386 semaphore implementation. + * + * (C) Copyright 1999 Linus Torvalds + * + * Portions Copyright 1999 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * rw semaphores implemented November 1999 by Benjamin LaHaise + */ +#include + +/* + * The semaphore operations have a special calling sequence that + * allow us to do a simpler in-line version of them. These routines + * need to convert that sequence back into the C sequence when + * there is contention on the semaphore. + * + * %eax contains the semaphore pointer on entry. Save the C-clobbered + * registers (%eax, %edx and %ecx) except %eax whish is either a return + * value or just clobbered.. + */ +asm( +".section .sched.text\n" +".align 4\n" +".globl __down_failed\n" +"__down_failed:\n\t" +#if defined(CONFIG_FRAME_POINTER) + "pushl %ebp\n\t" + "movl %esp,%ebp\n\t" +#endif + "pushl %edx\n\t" + "pushl %ecx\n\t" + "call __down\n\t" + "popl %ecx\n\t" + "popl %edx\n\t" +#if defined(CONFIG_FRAME_POINTER) + "movl %ebp,%esp\n\t" + "popl %ebp\n\t" +#endif + "ret" +); + +asm( +".section .sched.text\n" +".align 4\n" +".globl __down_failed_interruptible\n" +"__down_failed_interruptible:\n\t" +#if defined(CONFIG_FRAME_POINTER) + "pushl %ebp\n\t" + "movl %esp,%ebp\n\t" +#endif + "pushl %edx\n\t" + "pushl %ecx\n\t" + "call __down_interruptible\n\t" + "popl %ecx\n\t" + "popl %edx\n\t" +#if defined(CONFIG_FRAME_POINTER) + "movl %ebp,%esp\n\t" + "popl %ebp\n\t" +#endif + "ret" +); + +asm( +".section .sched.text\n" +".align 4\n" +".globl __down_failed_trylock\n" +"__down_failed_trylock:\n\t" +#if defined(CONFIG_FRAME_POINTER) + "pushl %ebp\n\t" + "movl %esp,%ebp\n\t" +#endif + "pushl %edx\n\t" + "pushl %ecx\n\t" + "call __down_trylock\n\t" + "popl %ecx\n\t" + "popl %edx\n\t" +#if defined(CONFIG_FRAME_POINTER) + "movl %ebp,%esp\n\t" + "popl %ebp\n\t" +#endif + "ret" +); + +asm( +".section .sched.text\n" +".align 4\n" +".globl __up_wakeup\n" +"__up_wakeup:\n\t" + "pushl %edx\n\t" + "pushl %ecx\n\t" + "call __up\n\t" + "popl %ecx\n\t" + "popl %edx\n\t" + "ret" +); + +/* + * rw spinlock fallbacks + */ +#if defined(CONFIG_SMP) +asm( +".section .sched.text\n" +".align 4\n" +".globl __write_lock_failed\n" +"__write_lock_failed:\n\t" + LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" +"1: rep; nop\n\t" + "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" + "jne 1b\n\t" + LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" + "jnz __write_lock_failed\n\t" + "ret" +); + +asm( +".section .sched.text\n" +".align 4\n" +".globl __read_lock_failed\n" +"__read_lock_failed:\n\t" + LOCK_PREFIX "incl (%eax)\n" +"1: rep; nop\n\t" + "cmpl $1,(%eax)\n\t" + "js 1b\n\t" + LOCK_PREFIX "decl (%eax)\n\t" + "js __read_lock_failed\n\t" + "ret" +); +#endif diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 76a524b4c90f..16d99444cf66 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -90,6 +90,18 @@ EXPORT_SYMBOL(boot_cpu_data); unsigned long mmu_cr4_features; +#ifdef CONFIG_ACPI + int acpi_disabled = 0; +#else + int acpi_disabled = 1; +#endif +EXPORT_SYMBOL(acpi_disabled); + +#ifdef CONFIG_ACPI +int __initdata acpi_force = 0; +extern acpi_interrupt_flags acpi_sci_flags; +#endif + /* for MCA, but anyone else can use it if they want */ unsigned int machine_id; #ifdef CONFIG_MCA @@ -137,6 +149,7 @@ EXPORT_SYMBOL(ist_info); struct e820map e820; extern void early_cpu_init(void); +extern void generic_apic_probe(char *); extern int root_mountflags; unsigned long saved_videomode; @@ -688,132 +701,238 @@ static inline void copy_edd(void) } #endif -static int __initdata user_defined_memmap = 0; - -/* - * "mem=nopentium" disables the 4MB page tables. - * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM - * to , overriding the bios size. - * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from - * to +, overriding the bios size. - * - * HPA tells me bootloaders need to parse mem=, so no new - * option should be mem= [also see Documentation/i386/boot.txt] - */ -static int __init parse_mem(char *arg) +static void __init parse_cmdline_early (char ** cmdline_p) { - if (!arg) - return -EINVAL; + char c = ' ', *to = command_line, *from = saved_command_line; + int len = 0; + int userdef = 0; - if (strcmp(arg, "nopentium") == 0) { - clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); - disable_pse = 1; - } else { - /* If the user specifies memory size, we - * limit the BIOS-provided memory map to - * that size. exactmap can be used to specify - * the exact map. mem=number can be used to - * trim the existing memory map. + /* Save unparsed command line copy for /proc/cmdline */ + saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; + + for (;;) { + if (c != ' ') + goto next_char; + /* + * "mem=nopentium" disables the 4MB page tables. + * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM + * to , overriding the bios size. + * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from + * to +, overriding the bios size. + * + * HPA tells me bootloaders need to parse mem=, so no new + * option should be mem= [also see Documentation/i386/boot.txt] */ - unsigned long long mem_size; + if (!memcmp(from, "mem=", 4)) { + if (to != command_line) + to--; + if (!memcmp(from+4, "nopentium", 9)) { + from += 9+4; + clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); + disable_pse = 1; + } else { + /* If the user specifies memory size, we + * limit the BIOS-provided memory map to + * that size. exactmap can be used to specify + * the exact map. mem=number can be used to + * trim the existing memory map. + */ + unsigned long long mem_size; - mem_size = memparse(arg, &arg); - limit_regions(mem_size); - user_defined_memmap = 1; - } - return 0; -} -early_param("mem", parse_mem); - -static int __init parse_memmap(char *arg) -{ - if (!arg) - return -EINVAL; + mem_size = memparse(from+4, &from); + limit_regions(mem_size); + userdef=1; + } + } - if (strcmp(arg, "exactmap") == 0) { + else if (!memcmp(from, "memmap=", 7)) { + if (to != command_line) + to--; + if (!memcmp(from+7, "exactmap", 8)) { #ifdef CONFIG_CRASH_DUMP - /* If we are doing a crash dump, we - * still need to know the real mem - * size before original memory map is - * reset. - */ - find_max_pfn(); - saved_max_pfn = max_pfn; + /* If we are doing a crash dump, we + * still need to know the real mem + * size before original memory map is + * reset. + */ + find_max_pfn(); + saved_max_pfn = max_pfn; #endif - e820.nr_map = 0; - user_defined_memmap = 1; - } else { - /* If the user specifies memory size, we - * limit the BIOS-provided memory map to - * that size. exactmap can be used to specify - * the exact map. mem=number can be used to - * trim the existing memory map. + from += 8+7; + e820.nr_map = 0; + userdef = 1; + } else { + /* If the user specifies memory size, we + * limit the BIOS-provided memory map to + * that size. exactmap can be used to specify + * the exact map. mem=number can be used to + * trim the existing memory map. + */ + unsigned long long start_at, mem_size; + + mem_size = memparse(from+7, &from); + if (*from == '@') { + start_at = memparse(from+1, &from); + add_memory_region(start_at, mem_size, E820_RAM); + } else if (*from == '#') { + start_at = memparse(from+1, &from); + add_memory_region(start_at, mem_size, E820_ACPI); + } else if (*from == '$') { + start_at = memparse(from+1, &from); + add_memory_region(start_at, mem_size, E820_RESERVED); + } else { + limit_regions(mem_size); + userdef=1; + } + } + } + + else if (!memcmp(from, "noexec=", 7)) + noexec_setup(from + 7); + + +#ifdef CONFIG_X86_SMP + /* + * If the BIOS enumerates physical processors before logical, + * maxcpus=N at enumeration-time can be used to disable HT. */ - unsigned long long start_at, mem_size; - - mem_size = memparse(arg, &arg); - if (*arg == '@') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_RAM); - } else if (*arg == '#') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_ACPI); - } else if (*arg == '$') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_RESERVED); - } else { - limit_regions(mem_size); - user_defined_memmap = 1; + else if (!memcmp(from, "maxcpus=", 8)) { + extern unsigned int maxcpus; + + maxcpus = simple_strtoul(from + 8, NULL, 0); } - } - return 0; -} -early_param("memmap", parse_memmap); +#endif -#ifdef CONFIG_PROC_VMCORE -/* elfcorehdr= specifies the location of elf core header - * stored by the crashed kernel. - */ -static int __init parse_elfcorehdr(char *arg) -{ - if (!arg) - return -EINVAL; +#ifdef CONFIG_ACPI + /* "acpi=off" disables both ACPI table parsing and interpreter */ + else if (!memcmp(from, "acpi=off", 8)) { + disable_acpi(); + } - elfcorehdr_addr = memparse(arg, &arg); - return 0; -} -early_param("elfcorehdr", parse_elfcorehdr); -#endif /* CONFIG_PROC_VMCORE */ + /* acpi=force to over-ride black-list */ + else if (!memcmp(from, "acpi=force", 10)) { + acpi_force = 1; + acpi_ht = 1; + acpi_disabled = 0; + } -/* - * highmem=size forces highmem to be exactly 'size' bytes. - * This works even on boxes that have no highmem otherwise. - * This also works to reduce highmem size on bigger boxes. - */ -static int __init parse_highmem(char *arg) -{ - if (!arg) - return -EINVAL; + /* acpi=strict disables out-of-spec workarounds */ + else if (!memcmp(from, "acpi=strict", 11)) { + acpi_strict = 1; + } - highmem_pages = memparse(arg, &arg) >> PAGE_SHIFT; - return 0; -} -early_param("highmem", parse_highmem); + /* Limit ACPI just to boot-time to enable HT */ + else if (!memcmp(from, "acpi=ht", 7)) { + if (!acpi_force) + disable_acpi(); + acpi_ht = 1; + } + + /* "pci=noacpi" disable ACPI IRQ routing and PCI scan */ + else if (!memcmp(from, "pci=noacpi", 10)) { + acpi_disable_pci(); + } + /* "acpi=noirq" disables ACPI interrupt routing */ + else if (!memcmp(from, "acpi=noirq", 10)) { + acpi_noirq_set(); + } -/* - * vmalloc=size forces the vmalloc area to be exactly 'size' - * bytes. This can be used to increase (or decrease) the - * vmalloc area - the default is 128m. - */ -static int __init parse_vmalloc(char *arg) -{ - if (!arg) - return -EINVAL; + else if (!memcmp(from, "acpi_sci=edge", 13)) + acpi_sci_flags.trigger = 1; - __VMALLOC_RESERVE = memparse(arg, &arg); - return 0; + else if (!memcmp(from, "acpi_sci=level", 14)) + acpi_sci_flags.trigger = 3; + + else if (!memcmp(from, "acpi_sci=high", 13)) + acpi_sci_flags.polarity = 1; + + else if (!memcmp(from, "acpi_sci=low", 12)) + acpi_sci_flags.polarity = 3; + +#ifdef CONFIG_X86_IO_APIC + else if (!memcmp(from, "acpi_skip_timer_override", 24)) + acpi_skip_timer_override = 1; + + if (!memcmp(from, "disable_timer_pin_1", 19)) + disable_timer_pin_1 = 1; + if (!memcmp(from, "enable_timer_pin_1", 18)) + disable_timer_pin_1 = -1; + + /* disable IO-APIC */ + else if (!memcmp(from, "noapic", 6)) + disable_ioapic_setup(); +#endif /* CONFIG_X86_IO_APIC */ +#endif /* CONFIG_ACPI */ + +#ifdef CONFIG_X86_LOCAL_APIC + /* enable local APIC */ + else if (!memcmp(from, "lapic", 5)) + lapic_enable(); + + /* disable local APIC */ + else if (!memcmp(from, "nolapic", 6)) + lapic_disable(); +#endif /* CONFIG_X86_LOCAL_APIC */ + +#ifdef CONFIG_KEXEC + /* crashkernel=size@addr specifies the location to reserve for + * a crash kernel. By reserving this memory we guarantee + * that linux never set's it up as a DMA target. + * Useful for holding code to do something appropriate + * after a kernel panic. + */ + else if (!memcmp(from, "crashkernel=", 12)) { + unsigned long size, base; + size = memparse(from+12, &from); + if (*from == '@') { + base = memparse(from+1, &from); + /* FIXME: Do I want a sanity check + * to validate the memory range? + */ + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + } +#endif +#ifdef CONFIG_PROC_VMCORE + /* elfcorehdr= specifies the location of elf core header + * stored by the crashed kernel. + */ + else if (!memcmp(from, "elfcorehdr=", 11)) + elfcorehdr_addr = memparse(from+11, &from); +#endif + + /* + * highmem=size forces highmem to be exactly 'size' bytes. + * This works even on boxes that have no highmem otherwise. + * This also works to reduce highmem size on bigger boxes. + */ + else if (!memcmp(from, "highmem=", 8)) + highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT; + + /* + * vmalloc=size forces the vmalloc area to be exactly 'size' + * bytes. This can be used to increase (or decrease) the + * vmalloc area - the default is 128m. + */ + else if (!memcmp(from, "vmalloc=", 8)) + __VMALLOC_RESERVE = memparse(from+8, &from); + + next_char: + c = *(from++); + if (!c) + break; + if (COMMAND_LINE_SIZE <= ++len) + break; + *(to++) = c; + } + *to = '\0'; + *cmdline_p = command_line; + if (userdef) { + printk(KERN_INFO "user-defined physical RAM map:\n"); + print_memory_map("user"); + } } -early_param("vmalloc", parse_vmalloc); /* * reservetop=size reserves a hole at the top of the kernel address space which @@ -1070,14 +1189,6 @@ static unsigned long __init setup_memory(void) } printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", pages_to_mb(highend_pfn - highstart_pfn)); - num_physpages = highend_pfn; - high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; -#else - num_physpages = max_low_pfn; - high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; -#endif -#ifdef CONFIG_FLATMEM - max_mapnr = num_physpages; #endif printk(KERN_NOTICE "%ldMB LOWMEM available.\n", pages_to_mb(max_low_pfn)); @@ -1407,15 +1518,17 @@ void __init setup_arch(char **cmdline_p) data_resource.start = virt_to_phys(_etext); data_resource.end = virt_to_phys(_edata)-1; - parse_early_param(); + parse_cmdline_early(cmdline_p); - if (user_defined_memmap) { - printk(KERN_INFO "user-defined physical RAM map:\n"); - print_memory_map("user"); +#ifdef CONFIG_EARLY_PRINTK + { + char *s = strstr(*cmdline_p, "earlyprintk="); + if (s) { + setup_early_printk(strchr(s, '=') + 1); + printk("early console enabled\n"); + } } - - strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; +#endif max_low_pfn = setup_memory(); @@ -1444,7 +1557,7 @@ void __init setup_arch(char **cmdline_p) dmi_scan_machine(); #ifdef CONFIG_X86_GENERICARCH - generic_apic_probe(); + generic_apic_probe(*cmdline_p); #endif if (efi_enabled) efi_map_memmap(); @@ -1456,11 +1569,9 @@ void __init setup_arch(char **cmdline_p) acpi_boot_table_init(); #endif -#ifdef CONFIG_PCI #ifdef CONFIG_X86_IO_APIC check_acpi_pci(); /* Checks more than just ACPI actually */ #endif -#endif #ifdef CONFIG_ACPI acpi_boot_init(); diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 020d873b7d21..efe07990e7fc 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -177,9 +177,6 @@ static void __devinit smp_store_cpu_info(int id) */ if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) { - if (num_possible_cpus() == 1) - goto valid_k7; - /* Athlon 660/661 is valid. */ if ((c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1))) goto valid_k7; @@ -1379,8 +1376,7 @@ int __cpu_disable(void) */ if (cpu == 0) return -EBUSY; - if (nmi_watchdog == NMI_LOCAL_APIC) - stop_apic_nmi_watchdog(NULL); + clear_local_APIC(); /* Allow any queued timer interrupts to get serviced */ local_irq_enable(); @@ -1494,16 +1490,3 @@ void __init smp_intr_init(void) /* IPI for generic function call */ set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); } - -/* - * If the BIOS enumerates physical processors before logical, - * maxcpus=N at enumeration-time can be used to disable HT. - */ -static int __init parse_maxcpus(char *arg) -{ - extern unsigned int maxcpus; - - maxcpus = simple_strtoul(arg, NULL, 0); - return 0; -} -early_param("maxcpus", parse_maxcpus); diff --git a/trunk/arch/i386/kernel/stacktrace.c b/trunk/arch/i386/kernel/stacktrace.c new file mode 100644 index 000000000000..e62a037ab399 --- /dev/null +++ b/trunk/arch/i386/kernel/stacktrace.c @@ -0,0 +1,98 @@ +/* + * arch/i386/kernel/stacktrace.c + * + * Stack trace management functions + * + * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar + */ +#include +#include + +static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) +{ + return p > (void *)tinfo && + p < (void *)tinfo + THREAD_SIZE - 3; +} + +/* + * Save stack-backtrace addresses into a stack_trace buffer: + */ +static inline unsigned long +save_context_stack(struct stack_trace *trace, unsigned int skip, + struct thread_info *tinfo, unsigned long *stack, + unsigned long ebp) +{ + unsigned long addr; + +#ifdef CONFIG_FRAME_POINTER + while (valid_stack_ptr(tinfo, (void *)ebp)) { + addr = *(unsigned long *)(ebp + 4); + if (!skip) + trace->entries[trace->nr_entries++] = addr; + else + skip--; + if (trace->nr_entries >= trace->max_entries) + break; + /* + * break out of recursive entries (such as + * end_of_stack_stop_unwind_function): + */ + if (ebp == *(unsigned long *)ebp) + break; + + ebp = *(unsigned long *)ebp; + } +#else + while (valid_stack_ptr(tinfo, stack)) { + addr = *stack++; + if (__kernel_text_address(addr)) { + if (!skip) + trace->entries[trace->nr_entries++] = addr; + else + skip--; + if (trace->nr_entries >= trace->max_entries) + break; + } + } +#endif + + return ebp; +} + +/* + * Save stack-backtrace addresses into a stack_trace buffer. + * If all_contexts is set, all contexts (hardirq, softirq and process) + * are saved. If not set then only the current context is saved. + */ +void save_stack_trace(struct stack_trace *trace, + struct task_struct *task, int all_contexts, + unsigned int skip) +{ + unsigned long ebp; + unsigned long *stack = &ebp; + + WARN_ON(trace->nr_entries || !trace->max_entries); + + if (!task || task == current) { + /* Grab ebp right from our regs: */ + asm ("movl %%ebp, %0" : "=r" (ebp)); + } else { + /* ebp is the last reg pushed by switch_to(): */ + ebp = *(unsigned long *) task->thread.esp; + } + + while (1) { + struct thread_info *context = (struct thread_info *) + ((unsigned long)stack & (~(THREAD_SIZE - 1))); + + ebp = save_context_stack(trace, skip, context, stack, ebp); + stack = (unsigned long *)context->previous_esp; + if (!all_contexts || !stack || + trace->nr_entries >= trace->max_entries) + break; + trace->entries[trace->nr_entries++] = ULONG_MAX; + if (trace->nr_entries >= trace->max_entries) + break; + } +} + diff --git a/trunk/arch/i386/kernel/syscall_table.S b/trunk/arch/i386/kernel/syscall_table.S index 7e639f78b0b9..dd63d4775398 100644 --- a/trunk/arch/i386/kernel/syscall_table.S +++ b/trunk/arch/i386/kernel/syscall_table.S @@ -317,4 +317,3 @@ ENTRY(sys_call_table) .long sys_tee /* 315 */ .long sys_vmsplice .long sys_move_pages - .long sys_getcpu diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c index 86944acfb647..1302e4ab3c4f 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -130,33 +130,18 @@ static int set_rtc_mmss(unsigned long nowtime) int timer_ack; +#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); -#ifdef CONFIG_SMP - if (!user_mode_vm(regs) && in_lock_functions(pc)) { -#ifdef CONFIG_FRAME_POINTER + if (!user_mode_vm(regs) && in_lock_functions(pc)) return *(unsigned long *)(regs->ebp + 4); -#else - unsigned long *sp; - if ((regs->xcs & 3) == 0) - sp = (unsigned long *)®s->esp; - else - sp = (unsigned long *)regs->esp; - /* Return address is either directly at stack pointer - or above a saved eflags. Eflags has bits 22-31 zero, - kernel addresses don't. */ - if (sp[0] >> 22) - return sp[0]; - if (sp[1] >> 22) - return sp[1]; -#endif - } -#endif + return pc; } EXPORT_SYMBOL(profile_pc); +#endif /* * This is the same as the above, except we _also_ save the current diff --git a/trunk/arch/i386/kernel/topology.c b/trunk/arch/i386/kernel/topology.c index 07d6da36a825..e2e281d4bcc8 100644 --- a/trunk/arch/i386/kernel/topology.c +++ b/trunk/arch/i386/kernel/topology.c @@ -28,7 +28,6 @@ #include #include #include -#include #include static struct i386_cpu cpu_devices[NR_CPUS]; @@ -56,18 +55,34 @@ EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); #endif /*CONFIG_HOTPLUG_CPU*/ + + +#ifdef CONFIG_NUMA +#include + static int __init topology_init(void) { int i; -#ifdef CONFIG_NUMA for_each_online_node(i) register_one_node(i); -#endif /* CONFIG_NUMA */ for_each_present_cpu(i) arch_register_cpu(i); return 0; } +#else /* !CONFIG_NUMA */ + +static int __init topology_init(void) +{ + int i; + + for_each_present_cpu(i) + arch_register_cpu(i); + return 0; +} + +#endif /* CONFIG_NUMA */ + subsys_initcall(topology_init); diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 21aa1cd57773..4fcc6690be99 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -51,7 +51,6 @@ #include #include #include -#include #include @@ -119,16 +118,26 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) p < (void *)tinfo + THREAD_SIZE - 3; } +/* + * Print one address/symbol entries per line. + */ +static inline void print_addr_and_symbol(unsigned long addr, char *log_lvl) +{ + printk(" [<%08lx>] ", addr); + + print_symbol("%s\n", addr); +} + static inline unsigned long print_context_stack(struct thread_info *tinfo, unsigned long *stack, unsigned long ebp, - struct stacktrace_ops *ops, void *data) + char *log_lvl) { unsigned long addr; #ifdef CONFIG_FRAME_POINTER while (valid_stack_ptr(tinfo, (void *)ebp)) { addr = *(unsigned long *)(ebp + 4); - ops->address(data, addr); + print_addr_and_symbol(addr, log_lvl); /* * break out of recursive entries (such as * end_of_stack_stop_unwind_function): @@ -141,37 +150,30 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, while (valid_stack_ptr(tinfo, stack)) { addr = *stack++; if (__kernel_text_address(addr)) - ops->address(data, addr); + print_addr_and_symbol(addr, log_lvl); } #endif return ebp; } -struct ops_and_data { - struct stacktrace_ops *ops; - void *data; -}; - static asmlinkage int -dump_trace_unwind(struct unwind_frame_info *info, void *data) +show_trace_unwind(struct unwind_frame_info *info, void *log_lvl) { - struct ops_and_data *oad = (struct ops_and_data *)data; int n = 0; while (unwind(info) == 0 && UNW_PC(info)) { n++; - oad->ops->address(oad->data, UNW_PC(info)); + print_addr_and_symbol(UNW_PC(info), log_lvl); if (arch_unw_user_mode(info)) break; } return n; } -void dump_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, - struct stacktrace_ops *ops, void *data) +static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, char *log_lvl) { - unsigned long ebp = 0; + unsigned long ebp; if (!task) task = current; @@ -179,116 +181,54 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (call_trace >= 0) { int unw_ret = 0; struct unwind_frame_info info; - struct ops_and_data oad = { .ops = ops, .data = data }; if (regs) { if (unwind_init_frame_info(&info, task, regs) == 0) - unw_ret = dump_trace_unwind(&info, &oad); + unw_ret = show_trace_unwind(&info, log_lvl); } else if (task == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad); + unw_ret = unwind_init_running(&info, show_trace_unwind, log_lvl); else { if (unwind_init_blocked(&info, task) == 0) - unw_ret = dump_trace_unwind(&info, &oad); + unw_ret = show_trace_unwind(&info, log_lvl); } if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n", + print_symbol("DWARF2 unwinder stuck at %s\n", UNW_PC(&info)); if (UNW_SP(&info) >= PAGE_OFFSET) { - ops->warning(data, "Leftover inexact backtrace:\n"); + printk("Leftover inexact backtrace:\n"); stack = (void *)UNW_SP(&info); - if (!stack) - return; - ebp = UNW_FP(&info); } else - ops->warning(data, "Full inexact backtrace again:\n"); + printk("Full inexact backtrace again:\n"); } else if (call_trace >= 1) return; else - ops->warning(data, "Full inexact backtrace again:\n"); + printk("Full inexact backtrace again:\n"); } else - ops->warning(data, "Inexact backtrace:\n"); - } - if (!stack) { - unsigned long dummy; - stack = &dummy; - if (task && task != current) - stack = (unsigned long *)task->thread.esp; + printk("Inexact backtrace:\n"); } -#ifdef CONFIG_FRAME_POINTER - if (!ebp) { - if (task == current) { - /* Grab ebp right from our regs */ - asm ("movl %%ebp, %0" : "=r" (ebp) : ); - } else { - /* ebp is the last reg pushed by switch_to */ - ebp = *(unsigned long *) task->thread.esp; - } + if (task == current) { + /* Grab ebp right from our regs */ + asm ("movl %%ebp, %0" : "=r" (ebp) : ); + } else { + /* ebp is the last reg pushed by switch_to */ + ebp = *(unsigned long *) task->thread.esp; } -#endif while (1) { struct thread_info *context; context = (struct thread_info *) ((unsigned long)stack & (~(THREAD_SIZE - 1))); - ebp = print_context_stack(context, stack, ebp, ops, data); - /* Should be after the line below, but somewhere - in early boot context comes out corrupted and we - can't reference it -AK */ - if (ops->stack(data, "IRQ") < 0) - break; + ebp = print_context_stack(context, stack, ebp, log_lvl); stack = (unsigned long*)context->previous_esp; if (!stack) break; + printk("%s =======================\n", log_lvl); } } -EXPORT_SYMBOL(dump_trace); - -static void -print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) -{ - printk(data); - print_symbol(msg, symbol); - printk("\n"); -} - -static void print_trace_warning(void *data, char *msg) -{ - printk("%s%s\n", (char *)data, msg); -} - -static int print_trace_stack(void *data, char *name) -{ - return 0; -} - -/* - * Print one address/symbol entries per line. - */ -static void print_trace_address(void *data, unsigned long addr) -{ - printk("%s [<%08lx>] ", (char *)data, addr); - print_symbol("%s\n", addr); -} - -static struct stacktrace_ops print_trace_ops = { - .warning = print_trace_warning, - .warning_symbol = print_trace_warning_symbol, - .stack = print_trace_stack, - .address = print_trace_address, -}; - -static void -show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, - unsigned long * stack, char *log_lvl) -{ - dump_trace(task, regs, stack, &print_trace_ops, log_lvl); - printk("%s =======================\n", log_lvl); -} -void show_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long * stack) +void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long * stack) { show_trace_log_lvl(task, regs, stack, ""); } @@ -351,9 +291,8 @@ void show_registers(struct pt_regs *regs) ss = regs->xss & 0xffff; } print_modules(); - printk(KERN_EMERG "CPU: %d\n" - KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n" - KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n", + printk(KERN_EMERG "CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\n" + "EFLAGS: %08lx (%s %.*s) \n", smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags, system_utsname.release, (int)strcspn(system_utsname.version, " "), @@ -695,24 +634,18 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, } } -static __kprobes void -mem_parity_error(unsigned char reason, struct pt_regs * regs) +static void mem_parity_error(unsigned char reason, struct pt_regs * regs) { - printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on " - "CPU %d.\n", reason, smp_processor_id()); + printk(KERN_EMERG "Uhhuh. NMI received. Dazed and confused, but trying " + "to continue\n"); printk(KERN_EMERG "You probably have a hardware problem with your RAM " "chips\n"); - if (panic_on_unrecovered_nmi) - panic("NMI: Not continuing"); - - printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); /* Clear and disable the memory parity error line. */ clear_mem_error(reason); } -static __kprobes void -io_check_error(unsigned char reason, struct pt_regs * regs) +static void io_check_error(unsigned char reason, struct pt_regs * regs) { unsigned long i; @@ -728,8 +661,7 @@ io_check_error(unsigned char reason, struct pt_regs * regs) outb(reason, 0x61); } -static __kprobes void -unknown_nmi_error(unsigned char reason, struct pt_regs * regs) +static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) { #ifdef CONFIG_MCA /* Might actually be able to figure out what the guilty party @@ -739,18 +671,15 @@ unknown_nmi_error(unsigned char reason, struct pt_regs * regs) return; } #endif - printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on " - "CPU %d.\n", reason, smp_processor_id()); - printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); - if (panic_on_unrecovered_nmi) - panic("NMI: Not continuing"); - - printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); + printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", + reason, smp_processor_id()); + printk("Dazed and confused, but trying to continue\n"); + printk("Do you have a strange power saving mode enabled?\n"); } static DEFINE_SPINLOCK(nmi_print_lock); -void __kprobes die_nmi(struct pt_regs *regs, const char *msg) +void die_nmi (struct pt_regs *regs, const char *msg) { if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == NOTIFY_STOP) @@ -782,7 +711,7 @@ void __kprobes die_nmi(struct pt_regs *regs, const char *msg) do_exit(SIGSEGV); } -static __kprobes void default_do_nmi(struct pt_regs * regs) +static void default_do_nmi(struct pt_regs * regs) { unsigned char reason = 0; @@ -799,12 +728,12 @@ static __kprobes void default_do_nmi(struct pt_regs * regs) * Ok, so this is none of the documented NMI sources, * so it must be the NMI watchdog. */ - if (nmi_watchdog_tick(regs, reason)) + if (nmi_watchdog) { + nmi_watchdog_tick(regs); return; - if (!do_nmi_callback(regs, smp_processor_id())) + } #endif - unknown_nmi_error(reason, regs); - + unknown_nmi_error(reason, regs); return; } if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) @@ -820,7 +749,14 @@ static __kprobes void default_do_nmi(struct pt_regs * regs) reassert_nmi(); } -fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) +static int dummy_nmi_callback(struct pt_regs * regs, int cpu) +{ + return 0; +} + +static nmi_callback_t nmi_callback = dummy_nmi_callback; + +fastcall void do_nmi(struct pt_regs * regs, long error_code) { int cpu; @@ -830,11 +766,25 @@ fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) ++nmi_count(cpu); - default_do_nmi(regs); + if (!rcu_dereference(nmi_callback)(regs, cpu)) + default_do_nmi(regs); nmi_exit(); } +void set_nmi_callback(nmi_callback_t callback) +{ + vmalloc_sync_all(); + rcu_assign_pointer(nmi_callback, callback); +} +EXPORT_SYMBOL_GPL(set_nmi_callback); + +void unset_nmi_callback(void) +{ + nmi_callback = dummy_nmi_callback; +} +EXPORT_SYMBOL_GPL(unset_nmi_callback); + #ifdef CONFIG_KPROBES fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) { @@ -1174,6 +1124,20 @@ void __init trap_init_f00f_bug(void) } #endif +#define _set_gate(gate_addr,type,dpl,addr,seg) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ + "movw %4,%%dx\n\t" \ + "movl %%eax,%0\n\t" \ + "movl %%edx,%1" \ + :"=m" (*((long *) (gate_addr))), \ + "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ + :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ + "3" ((char *) (addr)),"2" ((seg) << 16)); \ +} while (0) + + /* * This needs to use 'idt_table' rather than 'idt', and * thus use the _nonmapped_ version of the IDT, as the @@ -1182,7 +1146,7 @@ void __init trap_init_f00f_bug(void) */ void set_intr_gate(unsigned int n, void *addr) { - _set_gate(n, DESCTYPE_INT, addr, __KERNEL_CS); + _set_gate(idt_table+n,14,0,addr,__KERNEL_CS); } /* @@ -1190,22 +1154,22 @@ void set_intr_gate(unsigned int n, void *addr) */ static inline void set_system_intr_gate(unsigned int n, void *addr) { - _set_gate(n, DESCTYPE_INT | DESCTYPE_DPL3, addr, __KERNEL_CS); + _set_gate(idt_table+n, 14, 3, addr, __KERNEL_CS); } static void __init set_trap_gate(unsigned int n, void *addr) { - _set_gate(n, DESCTYPE_TRAP, addr, __KERNEL_CS); + _set_gate(idt_table+n,15,0,addr,__KERNEL_CS); } static void __init set_system_gate(unsigned int n, void *addr) { - _set_gate(n, DESCTYPE_TRAP | DESCTYPE_DPL3, addr, __KERNEL_CS); + _set_gate(idt_table+n,15,3,addr,__KERNEL_CS); } static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) { - _set_gate(n, DESCTYPE_TASK, (void *)0, (gdt_entry<<3)); + _set_gate(idt_table+n,5,0,0,(gdt_entry<<3)); } diff --git a/trunk/arch/i386/kernel/tsc.c b/trunk/arch/i386/kernel/tsc.c index b8fa0a8b2e47..7e0d8dab2075 100644 --- a/trunk/arch/i386/kernel/tsc.c +++ b/trunk/arch/i386/kernel/tsc.c @@ -192,7 +192,7 @@ int recalibrate_cpu_khz(void) EXPORT_SYMBOL(recalibrate_cpu_khz); -void __init tsc_init(void) +void tsc_init(void) { if (!cpu_has_tsc || tsc_disable) return; diff --git a/trunk/arch/i386/lib/Makefile b/trunk/arch/i386/lib/Makefile index d86a548b8d54..914933e9ec3d 100644 --- a/trunk/arch/i386/lib/Makefile +++ b/trunk/arch/i386/lib/Makefile @@ -4,6 +4,6 @@ lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \ - bitops.o semaphore.o + bitops.o lib-$(CONFIG_X86_USE_3DNOW) += mmx.o diff --git a/trunk/arch/i386/lib/semaphore.S b/trunk/arch/i386/lib/semaphore.S deleted file mode 100644 index 01f80b5c45d2..000000000000 --- a/trunk/arch/i386/lib/semaphore.S +++ /dev/null @@ -1,217 +0,0 @@ -/* - * i386 semaphore implementation. - * - * (C) Copyright 1999 Linus Torvalds - * - * Portions Copyright 1999 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * rw semaphores implemented November 1999 by Benjamin LaHaise - */ - -#include -#include -#include -#include -#include -#include - -/* - * The semaphore operations have a special calling sequence that - * allow us to do a simpler in-line version of them. These routines - * need to convert that sequence back into the C sequence when - * there is contention on the semaphore. - * - * %eax contains the semaphore pointer on entry. Save the C-clobbered - * registers (%eax, %edx and %ecx) except %eax whish is either a return - * value or just clobbered.. - */ - .section .sched.text -ENTRY(__down_failed) - CFI_STARTPROC - FRAME - pushl %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - pushl %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call __down - popl %ecx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ecx - popl %edx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edx - ENDFRAME - ret - CFI_ENDPROC - END(__down_failed) - -ENTRY(__down_failed_interruptible) - CFI_STARTPROC - FRAME - pushl %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - pushl %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call __down_interruptible - popl %ecx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ecx - popl %edx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edx - ENDFRAME - ret - CFI_ENDPROC - END(__down_failed_interruptible) - -ENTRY(__down_failed_trylock) - CFI_STARTPROC - FRAME - pushl %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - pushl %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call __down_trylock - popl %ecx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ecx - popl %edx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edx - ENDFRAME - ret - CFI_ENDPROC - END(__down_failed_trylock) - -ENTRY(__up_wakeup) - CFI_STARTPROC - FRAME - pushl %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - pushl %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call __up - popl %ecx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ecx - popl %edx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edx - ENDFRAME - ret - CFI_ENDPROC - END(__up_wakeup) - -/* - * rw spinlock fallbacks - */ -#ifdef CONFIG_SMP -ENTRY(__write_lock_failed) - CFI_STARTPROC simple - FRAME -2: LOCK_PREFIX - addl $ RW_LOCK_BIAS,(%eax) -1: rep; nop - cmpl $ RW_LOCK_BIAS,(%eax) - jne 1b - LOCK_PREFIX - subl $ RW_LOCK_BIAS,(%eax) - jnz 2b - ENDFRAME - ret - CFI_ENDPROC - END(__write_lock_failed) - -ENTRY(__read_lock_failed) - CFI_STARTPROC - FRAME -2: LOCK_PREFIX - incl (%eax) -1: rep; nop - cmpl $1,(%eax) - js 1b - LOCK_PREFIX - decl (%eax) - js 2b - ENDFRAME - ret - CFI_ENDPROC - END(__read_lock_failed) - -#endif - -/* Fix up special calling conventions */ -ENTRY(call_rwsem_down_read_failed) - CFI_STARTPROC - push %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - push %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - call rwsem_down_read_failed - pop %edx - CFI_ADJUST_CFA_OFFSET -4 - pop %ecx - CFI_ADJUST_CFA_OFFSET -4 - ret - CFI_ENDPROC - END(call_rwsem_down_read_failed) - -ENTRY(call_rwsem_down_write_failed) - CFI_STARTPROC - push %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - calll rwsem_down_write_failed - pop %ecx - CFI_ADJUST_CFA_OFFSET -4 - ret - CFI_ENDPROC - END(call_rwsem_down_write_failed) - -ENTRY(call_rwsem_wake) - CFI_STARTPROC - decw %dx /* do nothing if still outstanding active readers */ - jnz 1f - push %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call rwsem_wake - pop %ecx - CFI_ADJUST_CFA_OFFSET -4 -1: ret - CFI_ENDPROC - END(call_rwsem_wake) - -/* Fix up special calling conventions */ -ENTRY(call_rwsem_downgrade_wake) - CFI_STARTPROC - push %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - push %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - call rwsem_downgrade_wake - pop %edx - CFI_ADJUST_CFA_OFFSET -4 - pop %ecx - CFI_ADJUST_CFA_OFFSET -4 - ret - CFI_ENDPROC - END(call_rwsem_downgrade_wake) - diff --git a/trunk/arch/i386/mach-generic/bigsmp.c b/trunk/arch/i386/mach-generic/bigsmp.c index 33d9f93557ba..ef7a6e6fcb9f 100644 --- a/trunk/arch/i386/mach-generic/bigsmp.c +++ b/trunk/arch/i386/mach-generic/bigsmp.c @@ -5,7 +5,6 @@ #define APIC_DEFINITION 1 #include #include -#include #include #include #include diff --git a/trunk/arch/i386/mach-generic/es7000.c b/trunk/arch/i386/mach-generic/es7000.c index aa144d82334d..845cdd0b3593 100644 --- a/trunk/arch/i386/mach-generic/es7000.c +++ b/trunk/arch/i386/mach-generic/es7000.c @@ -4,7 +4,6 @@ #define APIC_DEFINITION 1 #include #include -#include #include #include #include diff --git a/trunk/arch/i386/mach-generic/probe.c b/trunk/arch/i386/mach-generic/probe.c index 94b1fd9cbe3c..bcd1bcfaa723 100644 --- a/trunk/arch/i386/mach-generic/probe.c +++ b/trunk/arch/i386/mach-generic/probe.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -30,24 +29,7 @@ struct genapic *apic_probe[] __initdata = { NULL, }; -static int cmdline_apic __initdata; -static int __init parse_apic(char *arg) -{ - int i; - - if (!arg) - return -EINVAL; - - for (i = 0; apic_probe[i]; i++) { - if (!strcmp(apic_probe[i]->name, arg)) { - genapic = apic_probe[i]; - cmdline_apic = 1; - return 0; - } - } - return -ENOENT; -} -early_param("apic", parse_apic); +static int cmdline_apic; void __init generic_bigsmp_probe(void) { @@ -66,20 +48,40 @@ void __init generic_bigsmp_probe(void) } } -void __init generic_apic_probe(void) +void __init generic_apic_probe(char *command_line) { - if (!cmdline_apic) { - int i; - for (i = 0; apic_probe[i]; i++) { - if (apic_probe[i]->probe()) { + char *s; + int i; + int changed = 0; + + s = strstr(command_line, "apic="); + if (s && (s == command_line || isspace(s[-1]))) { + char *p = strchr(s, ' '), old; + if (!p) + p = strchr(s, '\0'); + old = *p; + *p = 0; + for (i = 0; !changed && apic_probe[i]; i++) { + if (!strcmp(apic_probe[i]->name, s+5)) { + changed = 1; genapic = apic_probe[i]; - break; } } - /* Not visible without early console */ - if (!apic_probe[i]) - panic("Didn't find an APIC driver"); + if (!changed) + printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); + *p = old; + cmdline_apic = changed; + } + for (i = 0; !changed && apic_probe[i]; i++) { + if (apic_probe[i]->probe()) { + changed = 1; + genapic = apic_probe[i]; + } } + /* Not visible without early console */ + if (!changed) + panic("Didn't find an APIC driver"); + printk(KERN_INFO "Using APIC driver %s\n", genapic->name); } @@ -117,9 +119,7 @@ int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 0; } -#ifdef CONFIG_SMP int hard_smp_processor_id(void) { return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID)); } -#endif diff --git a/trunk/arch/i386/mach-generic/summit.c b/trunk/arch/i386/mach-generic/summit.c index f7e5d66648dc..b73501ddd653 100644 --- a/trunk/arch/i386/mach-generic/summit.c +++ b/trunk/arch/i386/mach-generic/summit.c @@ -4,7 +4,6 @@ #define APIC_DEFINITION 1 #include #include -#include #include #include #include diff --git a/trunk/arch/i386/mm/discontig.c b/trunk/arch/i386/mm/discontig.c index 941d1a5ebabb..fb5d8b747de4 100644 --- a/trunk/arch/i386/mm/discontig.c +++ b/trunk/arch/i386/mm/discontig.c @@ -322,11 +322,6 @@ unsigned long __init setup_memory(void) highstart_pfn = system_max_low_pfn; printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", pages_to_mb(highend_pfn - highstart_pfn)); - num_physpages = highend_pfn; - high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; -#else - num_physpages = system_max_low_pfn; - high_memory = (void *) __va(system_max_low_pfn * PAGE_SIZE - 1) + 1; #endif printk(KERN_NOTICE "%ldMB LOWMEM available.\n", pages_to_mb(system_max_low_pfn)); diff --git a/trunk/arch/i386/mm/extable.c b/trunk/arch/i386/mm/extable.c index 0ce4f22a2635..de03c5430abc 100644 --- a/trunk/arch/i386/mm/extable.c +++ b/trunk/arch/i386/mm/extable.c @@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs) const struct exception_table_entry *fixup; #ifdef CONFIG_PNPBIOS - if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs))) + if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3))) { extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; extern u32 pnp_bios_is_utter_crap; diff --git a/trunk/arch/i386/mm/fault.c b/trunk/arch/i386/mm/fault.c index 5e17a3f43b41..f7279468323a 100644 --- a/trunk/arch/i386/mm/fault.c +++ b/trunk/arch/i386/mm/fault.c @@ -27,24 +27,21 @@ #include #include #include -#include extern void die(const char *,struct pt_regs *,long); -static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); - +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); int register_page_fault_notifier(struct notifier_block *nb) { vmalloc_sync_all(); return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); } -EXPORT_SYMBOL_GPL(register_page_fault_notifier); int unregister_page_fault_notifier(struct notifier_block *nb) { return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); } -EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); static inline int notify_page_fault(enum die_val val, const char *str, struct pt_regs *regs, long err, int trap, int sig) @@ -58,6 +55,14 @@ static inline int notify_page_fault(enum die_val val, const char *str, }; return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); } +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif + /* * Unlock any spinlocks which will prevent us from getting the @@ -114,10 +119,10 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, } /* The standard kernel/user address space limit. */ - *eip_limit = user_mode(regs) ? USER_DS.seg : KERNEL_DS.seg; + *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg; /* By far the most common cases. */ - if (likely(SEGMENT_IS_FLAT_CODE(seg))) + if (likely(seg == __USER_CS || seg == __KERNEL_CS)) return eip; /* Check the segment exists, is within the current LDT/GDT size, @@ -431,7 +436,11 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, write = 0; switch (error_code & 3) { default: /* 3: write, present */ - /* fall through */ +#ifdef TEST_VERIFY_AREA + if (regs->cs == KERNEL_CS) + printk("WP fault at %08lx\n", regs->eip); +#endif + /* fall through */ case 2: /* write, not present */ if (!(vma->vm_flags & VM_WRITE)) goto bad_area; diff --git a/trunk/arch/i386/mm/highmem.c b/trunk/arch/i386/mm/highmem.c index ba44000b9069..b6eb4dcb8777 100644 --- a/trunk/arch/i386/mm/highmem.c +++ b/trunk/arch/i386/mm/highmem.c @@ -54,7 +54,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); - if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) { + if (vaddr < FIXADDR_START) { // FIXME dec_preempt_count(); preempt_check_resched(); return; diff --git a/trunk/arch/i386/mm/init.c b/trunk/arch/i386/mm/init.c index 4a5a914b3432..efd0bcdac65d 100644 --- a/trunk/arch/i386/mm/init.c +++ b/trunk/arch/i386/mm/init.c @@ -435,22 +435,16 @@ u64 __supported_pte_mask __read_mostly = ~_PAGE_NX; * on Enable * off Disable */ -static int __init noexec_setup(char *str) +void __init noexec_setup(const char *str) { - if (!str || !strcmp(str, "on")) { - if (cpu_has_nx) { - __supported_pte_mask |= _PAGE_NX; - disable_nx = 0; - } - } else if (!strcmp(str,"off")) { + if (!strncmp(str, "on",2) && cpu_has_nx) { + __supported_pte_mask |= _PAGE_NX; + disable_nx = 0; + } else if (!strncmp(str,"off",3)) { disable_nx = 1; __supported_pte_mask &= ~_PAGE_NX; - } else - return -EINVAL; - - return 0; + } } -early_param("noexec", noexec_setup); int nx_enabled = 0; #ifdef CONFIG_X86_PAE @@ -558,6 +552,18 @@ static void __init test_wp_bit(void) } } +static void __init set_max_mapnr_init(void) +{ +#ifdef CONFIG_HIGHMEM + num_physpages = highend_pfn; +#else + num_physpages = max_low_pfn; +#endif +#ifdef CONFIG_FLATMEM + max_mapnr = num_physpages; +#endif +} + static struct kcore_list kcore_mem, kcore_vmalloc; void __init mem_init(void) @@ -584,6 +590,14 @@ void __init mem_init(void) } #endif + set_max_mapnr_init(); + +#ifdef CONFIG_HIGHMEM + high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; +#else + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; +#endif + /* this will put all low memory onto the freelists */ totalram_pages += free_all_bootmem(); diff --git a/trunk/arch/i386/oprofile/nmi_int.c b/trunk/arch/i386/oprofile/nmi_int.c index 3700eef78743..5f8dc8a21bd7 100644 --- a/trunk/arch/i386/oprofile/nmi_int.c +++ b/trunk/arch/i386/oprofile/nmi_int.c @@ -17,15 +17,14 @@ #include #include #include -#include #include "op_counter.h" #include "op_x86_model.h" - + static struct op_x86_model_spec const * model; static struct op_msrs cpu_msrs[NR_CPUS]; static unsigned long saved_lvtpc[NR_CPUS]; - + static int nmi_start(void); static void nmi_stop(void); @@ -83,24 +82,13 @@ static void exit_driverfs(void) #define exit_driverfs() do { } while (0) #endif /* CONFIG_PM */ -static int profile_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - struct die_args *args = (struct die_args *)data; - int ret = NOTIFY_DONE; - int cpu = smp_processor_id(); - switch(val) { - case DIE_NMI: - if (model->check_ctrs(args->regs, &cpu_msrs[cpu])) - ret = NOTIFY_STOP; - break; - default: - break; - } - return ret; +static int nmi_callback(struct pt_regs * regs, int cpu) +{ + return model->check_ctrs(regs, &cpu_msrs[cpu]); } - + + static void nmi_cpu_save_registers(struct op_msrs * msrs) { unsigned int const nr_ctrs = model->num_counters; @@ -110,19 +98,15 @@ static void nmi_cpu_save_registers(struct op_msrs * msrs) unsigned int i; for (i = 0; i < nr_ctrs; ++i) { - if (counters[i].addr){ - rdmsr(counters[i].addr, - counters[i].saved.low, - counters[i].saved.high); - } + rdmsr(counters[i].addr, + counters[i].saved.low, + counters[i].saved.high); } for (i = 0; i < nr_ctrls; ++i) { - if (controls[i].addr){ - rdmsr(controls[i].addr, - controls[i].saved.low, - controls[i].saved.high); - } + rdmsr(controls[i].addr, + controls[i].saved.low, + controls[i].saved.high); } } @@ -186,29 +170,27 @@ static void nmi_cpu_setup(void * dummy) apic_write(APIC_LVTPC, APIC_DM_NMI); } -static struct notifier_block profile_exceptions_nb = { - .notifier_call = profile_exceptions_notify, - .next = NULL, - .priority = 0 -}; static int nmi_setup(void) { - int err=0; - if (!allocate_msrs()) return -ENOMEM; - if ((err = register_die_notifier(&profile_exceptions_nb))){ + /* We walk a thin line between law and rape here. + * We need to be careful to install our NMI handler + * without actually triggering any NMIs as this will + * break the core code horrifically. + */ + if (reserve_lapic_nmi() < 0) { free_msrs(); - return err; + return -EBUSY; } - /* We need to serialize save and setup for HT because the subset * of msrs are distinct for save and setup operations */ on_each_cpu(nmi_save_registers, NULL, 0, 1); on_each_cpu(nmi_cpu_setup, NULL, 0, 1); + set_nmi_callback(nmi_callback); nmi_enabled = 1; return 0; } @@ -223,19 +205,15 @@ static void nmi_restore_registers(struct op_msrs * msrs) unsigned int i; for (i = 0; i < nr_ctrls; ++i) { - if (controls[i].addr){ - wrmsr(controls[i].addr, - controls[i].saved.low, - controls[i].saved.high); - } + wrmsr(controls[i].addr, + controls[i].saved.low, + controls[i].saved.high); } for (i = 0; i < nr_ctrs; ++i) { - if (counters[i].addr){ - wrmsr(counters[i].addr, - counters[i].saved.low, - counters[i].saved.high); - } + wrmsr(counters[i].addr, + counters[i].saved.low, + counters[i].saved.high); } } @@ -256,7 +234,6 @@ static void nmi_cpu_shutdown(void * dummy) apic_write(APIC_LVTPC, saved_lvtpc[cpu]); apic_write(APIC_LVTERR, v); nmi_restore_registers(msrs); - model->shutdown(msrs); } @@ -264,7 +241,8 @@ static void nmi_shutdown(void) { nmi_enabled = 0; on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1); - unregister_die_notifier(&profile_exceptions_nb); + unset_nmi_callback(); + release_lapic_nmi(); free_msrs(); } @@ -306,14 +284,6 @@ static int nmi_create_files(struct super_block * sb, struct dentry * root) struct dentry * dir; char buf[4]; - /* quick little hack to _not_ expose a counter if it is not - * available for use. This should protect userspace app. - * NOTE: assumes 1:1 mapping here (that counters are organized - * sequentially in their struct assignment). - */ - if (unlikely(!avail_to_resrv_perfctr_nmi_bit(i))) - continue; - snprintf(buf, sizeof(buf), "%d", i); dir = oprofilefs_mkdir(sb, root, buf); oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); diff --git a/trunk/arch/i386/oprofile/nmi_timer_int.c b/trunk/arch/i386/oprofile/nmi_timer_int.c index abf0ba52a635..930a1127bb30 100644 --- a/trunk/arch/i386/oprofile/nmi_timer_int.c +++ b/trunk/arch/i386/oprofile/nmi_timer_int.c @@ -17,49 +17,34 @@ #include #include #include -#include -static int profile_timer_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) +static int nmi_timer_callback(struct pt_regs * regs, int cpu) { - struct die_args *args = (struct die_args *)data; - int ret = NOTIFY_DONE; - - switch(val) { - case DIE_NMI: - oprofile_add_sample(args->regs, 0); - ret = NOTIFY_STOP; - break; - default: - break; - } - return ret; + oprofile_add_sample(regs, 0); + return 1; } -static struct notifier_block profile_timer_exceptions_nb = { - .notifier_call = profile_timer_exceptions_notify, - .next = NULL, - .priority = 0 -}; - static int timer_start(void) { - if (register_die_notifier(&profile_timer_exceptions_nb)) - return 1; + disable_timer_nmi_watchdog(); + set_nmi_callback(nmi_timer_callback); return 0; } static void timer_stop(void) { - unregister_die_notifier(&profile_timer_exceptions_nb); + enable_timer_nmi_watchdog(); + unset_nmi_callback(); synchronize_sched(); /* Allow already-started NMIs to complete. */ } int __init op_nmi_timer_init(struct oprofile_operations * ops) { - if ((nmi_watchdog != NMI_IO_APIC) || (atomic_read(&nmi_active) <= 0)) + extern int nmi_active; + + if (nmi_active <= 0) return -ENODEV; ops->start = timer_start; diff --git a/trunk/arch/i386/oprofile/op_model_athlon.c b/trunk/arch/i386/oprofile/op_model_athlon.c index 3057a19e4641..693bdea4a52b 100644 --- a/trunk/arch/i386/oprofile/op_model_athlon.c +++ b/trunk/arch/i386/oprofile/op_model_athlon.c @@ -21,12 +21,10 @@ #define NUM_COUNTERS 4 #define NUM_CONTROLS 4 -#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0) #define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0) #define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1);} while (0) #define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) -#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0) #define CTRL_READ(l,h,msrs,c) do {rdmsr(msrs->controls[(c)].addr, (l), (h));} while (0) #define CTRL_WRITE(l,h,msrs,c) do {wrmsr(msrs->controls[(c)].addr, (l), (h));} while (0) #define CTRL_SET_ACTIVE(n) (n |= (1<<22)) @@ -42,21 +40,15 @@ static unsigned long reset_value[NUM_COUNTERS]; static void athlon_fill_in_addresses(struct op_msrs * const msrs) { - int i; - - for (i=0; i < NUM_COUNTERS; i++) { - if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) - msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; - else - msrs->counters[i].addr = 0; - } - - for (i=0; i < NUM_CONTROLS; i++) { - if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) - msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; - else - msrs->controls[i].addr = 0; - } + msrs->counters[0].addr = MSR_K7_PERFCTR0; + msrs->counters[1].addr = MSR_K7_PERFCTR1; + msrs->counters[2].addr = MSR_K7_PERFCTR2; + msrs->counters[3].addr = MSR_K7_PERFCTR3; + + msrs->controls[0].addr = MSR_K7_EVNTSEL0; + msrs->controls[1].addr = MSR_K7_EVNTSEL1; + msrs->controls[2].addr = MSR_K7_EVNTSEL2; + msrs->controls[3].addr = MSR_K7_EVNTSEL3; } @@ -67,23 +59,19 @@ static void athlon_setup_ctrs(struct op_msrs const * const msrs) /* clear all counters */ for (i = 0 ; i < NUM_CONTROLS; ++i) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) - continue; CTRL_READ(low, high, msrs, i); CTRL_CLEAR(low); CTRL_WRITE(low, high, msrs, i); } - + /* avoid a false detection of ctr overflows in NMI handler */ for (i = 0; i < NUM_COUNTERS; ++i) { - if (unlikely(!CTR_IS_RESERVED(msrs,i))) - continue; CTR_WRITE(1, msrs, i); } /* enable active counters */ for (i = 0; i < NUM_COUNTERS; ++i) { - if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs,i))) { + if (counter_config[i].enabled) { reset_value[i] = counter_config[i].count; CTR_WRITE(counter_config[i].count, msrs, i); @@ -110,8 +98,6 @@ static int athlon_check_ctrs(struct pt_regs * const regs, int i; for (i = 0 ; i < NUM_COUNTERS; ++i) { - if (!reset_value[i]) - continue; CTR_READ(low, high, msrs, i); if (CTR_OVERFLOWED(low)) { oprofile_add_sample(regs, i); @@ -146,27 +132,12 @@ static void athlon_stop(struct op_msrs const * const msrs) /* Subtle: stop on all counters to avoid race with * setting our pm callback */ for (i = 0 ; i < NUM_COUNTERS ; ++i) { - if (!reset_value[i]) - continue; CTRL_READ(low, high, msrs, i); CTRL_SET_INACTIVE(low); CTRL_WRITE(low, high, msrs, i); } } -static void athlon_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0 ; i < NUM_COUNTERS ; ++i) { - if (CTR_IS_RESERVED(msrs,i)) - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); - } - for (i = 0 ; i < NUM_CONTROLS ; ++i) { - if (CTRL_IS_RESERVED(msrs,i)) - release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); - } -} struct op_x86_model_spec const op_athlon_spec = { .num_counters = NUM_COUNTERS, @@ -175,6 +146,5 @@ struct op_x86_model_spec const op_athlon_spec = { .setup_ctrs = &athlon_setup_ctrs, .check_ctrs = &athlon_check_ctrs, .start = &athlon_start, - .stop = &athlon_stop, - .shutdown = &athlon_shutdown + .stop = &athlon_stop }; diff --git a/trunk/arch/i386/oprofile/op_model_p4.c b/trunk/arch/i386/oprofile/op_model_p4.c index 47925927b12f..7c61d357b82b 100644 --- a/trunk/arch/i386/oprofile/op_model_p4.c +++ b/trunk/arch/i386/oprofile/op_model_p4.c @@ -32,7 +32,7 @@ #define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) static unsigned int num_counters = NUM_COUNTERS_NON_HT; -static unsigned int num_controls = NUM_CONTROLS_NON_HT; + /* this has to be checked dynamically since the hyper-threadedness of a chip is discovered at @@ -40,10 +40,8 @@ static unsigned int num_controls = NUM_CONTROLS_NON_HT; static inline void setup_num_counters(void) { #ifdef CONFIG_SMP - if (smp_num_siblings == 2){ + if (smp_num_siblings == 2) num_counters = NUM_COUNTERS_HT2; - num_controls = NUM_CONTROLS_HT2; - } #endif } @@ -99,6 +97,15 @@ static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = { #define NUM_UNUSED_CCCRS NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT +/* All cccr we don't use. */ +static int p4_unused_cccr[NUM_UNUSED_CCCRS] = { + MSR_P4_BPU_CCCR1, MSR_P4_BPU_CCCR3, + MSR_P4_MS_CCCR1, MSR_P4_MS_CCCR3, + MSR_P4_FLAME_CCCR1, MSR_P4_FLAME_CCCR3, + MSR_P4_IQ_CCCR0, MSR_P4_IQ_CCCR1, + MSR_P4_IQ_CCCR2, MSR_P4_IQ_CCCR3 +}; + /* p4 event codes in libop/op_event.h are indices into this table. */ static struct p4_event_binding p4_events[NUM_EVENTS] = { @@ -365,8 +372,6 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) -#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0) -#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0) #define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0) #define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0) #define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000)) @@ -396,34 +401,29 @@ static unsigned long reset_value[NUM_COUNTERS_NON_HT]; static void p4_fill_in_addresses(struct op_msrs * const msrs) { unsigned int i; - unsigned int addr, cccraddr, stag; + unsigned int addr, stag; setup_num_counters(); stag = get_stagger(); - /* initialize some registers */ + /* the counter registers we pay attention to */ for (i = 0; i < num_counters; ++i) { - msrs->counters[i].addr = 0; + msrs->counters[i].addr = + p4_counters[VIRT_CTR(stag, i)].counter_address; } - for (i = 0; i < num_controls; ++i) { - msrs->controls[i].addr = 0; + + /* FIXME: bad feeling, we don't save the 10 counters we don't use. */ + + /* 18 CCCR registers */ + for (i = 0, addr = MSR_P4_BPU_CCCR0 + stag; + addr <= MSR_P4_IQ_CCCR5; ++i, addr += addr_increment()) { + msrs->controls[i].addr = addr; } - /* the counter & cccr registers we pay attention to */ - for (i = 0; i < num_counters; ++i) { - addr = p4_counters[VIRT_CTR(stag, i)].counter_address; - cccraddr = p4_counters[VIRT_CTR(stag, i)].cccr_address; - if (reserve_perfctr_nmi(addr)){ - msrs->counters[i].addr = addr; - msrs->controls[i].addr = cccraddr; - } - } - /* 43 ESCR registers in three or four discontiguous group */ for (addr = MSR_P4_BSU_ESCR0 + stag; addr < MSR_P4_IQ_ESCR0; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } /* no IQ_ESCR0/1 on some models, we save a seconde time BSU_ESCR0/1 @@ -431,57 +431,47 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs) if (boot_cpu_data.x86_model >= 0x3) { for (addr = MSR_P4_BSU_ESCR0 + stag; addr <= MSR_P4_BSU_ESCR1; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } } else { for (addr = MSR_P4_IQ_ESCR0 + stag; addr <= MSR_P4_IQ_ESCR1; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } } for (addr = MSR_P4_RAT_ESCR0 + stag; addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } for (addr = MSR_P4_MS_ESCR0 + stag; addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } for (addr = MSR_P4_IX_ESCR0 + stag; addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } /* there are 2 remaining non-contiguously located ESCRs */ if (num_counters == NUM_COUNTERS_NON_HT) { /* standard non-HT CPUs handle both remaining ESCRs*/ - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5)) - msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4)) - msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; + msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; + msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; } else if (stag == 0) { /* HT CPUs give the first remainder to the even thread, as the 32nd control register */ - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4)) - msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; + msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; } else { /* and two copies of the second to the odd thread, for the 22st and 23nd control registers */ - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5)) { - msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; - msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; - } + msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; + msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; } } @@ -554,6 +544,7 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs) { unsigned int i; unsigned int low, high; + unsigned int addr; unsigned int stag; stag = get_stagger(); @@ -566,24 +557,59 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs) /* clear the cccrs we will use */ for (i = 0 ; i < num_counters ; i++) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) - continue; rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); CCCR_CLEAR(low); CCCR_SET_REQUIRED_BITS(low); wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); } + /* clear cccrs outside our concern */ + for (i = stag ; i < NUM_UNUSED_CCCRS ; i += addr_increment()) { + rdmsr(p4_unused_cccr[i], low, high); + CCCR_CLEAR(low); + CCCR_SET_REQUIRED_BITS(low); + wrmsr(p4_unused_cccr[i], low, high); + } + /* clear all escrs (including those outside our concern) */ - for (i = num_counters; i < num_controls; i++) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) - continue; - wrmsr(msrs->controls[i].addr, 0, 0); + for (addr = MSR_P4_BSU_ESCR0 + stag; + addr < MSR_P4_IQ_ESCR0; addr += addr_increment()) { + wrmsr(addr, 0, 0); + } + + /* On older models clear also MSR_P4_IQ_ESCR0/1 */ + if (boot_cpu_data.x86_model < 0x3) { + wrmsr(MSR_P4_IQ_ESCR0, 0, 0); + wrmsr(MSR_P4_IQ_ESCR1, 0, 0); } + for (addr = MSR_P4_RAT_ESCR0 + stag; + addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { + wrmsr(addr, 0, 0); + } + + for (addr = MSR_P4_MS_ESCR0 + stag; + addr <= MSR_P4_TC_ESCR1; addr += addr_increment()){ + wrmsr(addr, 0, 0); + } + + for (addr = MSR_P4_IX_ESCR0 + stag; + addr <= MSR_P4_CRU_ESCR3; addr += addr_increment()){ + wrmsr(addr, 0, 0); + } + + if (num_counters == NUM_COUNTERS_NON_HT) { + wrmsr(MSR_P4_CRU_ESCR4, 0, 0); + wrmsr(MSR_P4_CRU_ESCR5, 0, 0); + } else if (stag == 0) { + wrmsr(MSR_P4_CRU_ESCR4, 0, 0); + } else { + wrmsr(MSR_P4_CRU_ESCR5, 0, 0); + } + /* setup all counters */ for (i = 0 ; i < num_counters ; ++i) { - if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs,i))) { + if (counter_config[i].enabled) { reset_value[i] = counter_config[i].count; pmc_setup_one_p4_counter(i); CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i)); @@ -670,32 +696,12 @@ static void p4_stop(struct op_msrs const * const msrs) stag = get_stagger(); for (i = 0; i < num_counters; ++i) { - if (!reset_value[i]) - continue; CCCR_READ(low, high, VIRT_CTR(stag, i)); CCCR_SET_DISABLE(low); CCCR_WRITE(low, high, VIRT_CTR(stag, i)); } } -static void p4_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0 ; i < num_counters ; ++i) { - if (CTR_IS_RESERVED(msrs,i)) - release_perfctr_nmi(msrs->counters[i].addr); - } - /* some of the control registers are specially reserved in - * conjunction with the counter registers (hence the starting offset). - * This saves a few bits. - */ - for (i = num_counters ; i < num_controls ; ++i) { - if (CTRL_IS_RESERVED(msrs,i)) - release_evntsel_nmi(msrs->controls[i].addr); - } -} - #ifdef CONFIG_SMP struct op_x86_model_spec const op_p4_ht2_spec = { @@ -705,8 +711,7 @@ struct op_x86_model_spec const op_p4_ht2_spec = { .setup_ctrs = &p4_setup_ctrs, .check_ctrs = &p4_check_ctrs, .start = &p4_start, - .stop = &p4_stop, - .shutdown = &p4_shutdown + .stop = &p4_stop }; #endif @@ -717,6 +722,5 @@ struct op_x86_model_spec const op_p4_spec = { .setup_ctrs = &p4_setup_ctrs, .check_ctrs = &p4_check_ctrs, .start = &p4_start, - .stop = &p4_stop, - .shutdown = &p4_shutdown + .stop = &p4_stop }; diff --git a/trunk/arch/i386/oprofile/op_model_ppro.c b/trunk/arch/i386/oprofile/op_model_ppro.c index f88e05ba8eb3..5c3ab4b027ad 100644 --- a/trunk/arch/i386/oprofile/op_model_ppro.c +++ b/trunk/arch/i386/oprofile/op_model_ppro.c @@ -22,12 +22,10 @@ #define NUM_COUNTERS 2 #define NUM_CONTROLS 2 -#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0) #define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0) #define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(u32)(l), -1);} while (0) #define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) -#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0) #define CTRL_READ(l,h,msrs,c) do {rdmsr((msrs->controls[(c)].addr), (l), (h));} while (0) #define CTRL_WRITE(l,h,msrs,c) do {wrmsr((msrs->controls[(c)].addr), (l), (h));} while (0) #define CTRL_SET_ACTIVE(n) (n |= (1<<22)) @@ -43,21 +41,11 @@ static unsigned long reset_value[NUM_COUNTERS]; static void ppro_fill_in_addresses(struct op_msrs * const msrs) { - int i; - - for (i=0; i < NUM_COUNTERS; i++) { - if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) - msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; - else - msrs->counters[i].addr = 0; - } + msrs->counters[0].addr = MSR_P6_PERFCTR0; + msrs->counters[1].addr = MSR_P6_PERFCTR1; - for (i=0; i < NUM_CONTROLS; i++) { - if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) - msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; - else - msrs->controls[i].addr = 0; - } + msrs->controls[0].addr = MSR_P6_EVNTSEL0; + msrs->controls[1].addr = MSR_P6_EVNTSEL1; } @@ -68,8 +56,6 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs) /* clear all counters */ for (i = 0 ; i < NUM_CONTROLS; ++i) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) - continue; CTRL_READ(low, high, msrs, i); CTRL_CLEAR(low); CTRL_WRITE(low, high, msrs, i); @@ -77,14 +63,12 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs) /* avoid a false detection of ctr overflows in NMI handler */ for (i = 0; i < NUM_COUNTERS; ++i) { - if (unlikely(!CTR_IS_RESERVED(msrs,i))) - continue; CTR_WRITE(1, msrs, i); } /* enable active counters */ for (i = 0; i < NUM_COUNTERS; ++i) { - if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs,i))) { + if (counter_config[i].enabled) { reset_value[i] = counter_config[i].count; CTR_WRITE(counter_config[i].count, msrs, i); @@ -97,8 +81,6 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs) CTRL_SET_UM(low, counter_config[i].unit_mask); CTRL_SET_EVENT(low, counter_config[i].event); CTRL_WRITE(low, high, msrs, i); - } else { - reset_value[i] = 0; } } } @@ -111,8 +93,6 @@ static int ppro_check_ctrs(struct pt_regs * const regs, int i; for (i = 0 ; i < NUM_COUNTERS; ++i) { - if (!reset_value[i]) - continue; CTR_READ(low, high, msrs, i); if (CTR_OVERFLOWED(low)) { oprofile_add_sample(regs, i); @@ -138,38 +118,18 @@ static int ppro_check_ctrs(struct pt_regs * const regs, static void ppro_start(struct op_msrs const * const msrs) { unsigned int low,high; - - if (reset_value[0]) { - CTRL_READ(low, high, msrs, 0); - CTRL_SET_ACTIVE(low); - CTRL_WRITE(low, high, msrs, 0); - } + CTRL_READ(low, high, msrs, 0); + CTRL_SET_ACTIVE(low); + CTRL_WRITE(low, high, msrs, 0); } static void ppro_stop(struct op_msrs const * const msrs) { unsigned int low,high; - - if (reset_value[0]) { - CTRL_READ(low, high, msrs, 0); - CTRL_SET_INACTIVE(low); - CTRL_WRITE(low, high, msrs, 0); - } -} - -static void ppro_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0 ; i < NUM_COUNTERS ; ++i) { - if (CTR_IS_RESERVED(msrs,i)) - release_perfctr_nmi(MSR_P6_PERFCTR0 + i); - } - for (i = 0 ; i < NUM_CONTROLS ; ++i) { - if (CTRL_IS_RESERVED(msrs,i)) - release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); - } + CTRL_READ(low, high, msrs, 0); + CTRL_SET_INACTIVE(low); + CTRL_WRITE(low, high, msrs, 0); } @@ -180,6 +140,5 @@ struct op_x86_model_spec const op_ppro_spec = { .setup_ctrs = &ppro_setup_ctrs, .check_ctrs = &ppro_check_ctrs, .start = &ppro_start, - .stop = &ppro_stop, - .shutdown = &ppro_shutdown + .stop = &ppro_stop }; diff --git a/trunk/arch/i386/oprofile/op_x86_model.h b/trunk/arch/i386/oprofile/op_x86_model.h index abb1aa95b979..123b7e90a9ee 100644 --- a/trunk/arch/i386/oprofile/op_x86_model.h +++ b/trunk/arch/i386/oprofile/op_x86_model.h @@ -40,7 +40,6 @@ struct op_x86_model_spec { struct op_msrs const * const msrs); void (*start)(struct op_msrs const * const msrs); void (*stop)(struct op_msrs const * const msrs); - void (*shutdown)(struct op_msrs const * const msrs); }; extern struct op_x86_model_spec const op_ppro_spec; diff --git a/trunk/arch/i386/pci/Makefile b/trunk/arch/i386/pci/Makefile index 1594d2f55c8f..62ad75c57e6a 100644 --- a/trunk/arch/i386/pci/Makefile +++ b/trunk/arch/i386/pci/Makefile @@ -11,4 +11,4 @@ pci-y += legacy.o irq.o pci-$(CONFIG_X86_VISWS) := visws.o fixup.o pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o -obj-y += $(pci-y) common.o early.o +obj-y += $(pci-y) common.o diff --git a/trunk/arch/i386/pci/common.c b/trunk/arch/i386/pci/common.c index 68bce194e688..0a362e3aeac5 100644 --- a/trunk/arch/i386/pci/common.c +++ b/trunk/arch/i386/pci/common.c @@ -242,10 +242,6 @@ char * __devinit pcibios_setup(char *str) acpi_noirq_set(); return NULL; } - else if (!strcmp(str, "noearly")) { - pci_probe |= PCI_PROBE_NOEARLY; - return NULL; - } #ifndef CONFIG_X86_VISWS else if (!strcmp(str, "usepirqmask")) { pci_probe |= PCI_USE_PIRQ_MASK; diff --git a/trunk/arch/i386/pci/direct.c b/trunk/arch/i386/pci/direct.c index 5acf0b4743cf..5d81fb510375 100644 --- a/trunk/arch/i386/pci/direct.c +++ b/trunk/arch/i386/pci/direct.c @@ -254,16 +254,7 @@ static int __init pci_check_type2(void) return works; } -void __init pci_direct_init(int type) -{ - printk(KERN_INFO "PCI: Using configuration type %d\n", type); - if (type == 1) - raw_pci_ops = &pci_direct_conf1; - else - raw_pci_ops = &pci_direct_conf2; -} - -int __init pci_direct_probe(void) +void __init pci_direct_init(void) { struct resource *region, *region2; @@ -273,16 +264,19 @@ int __init pci_direct_probe(void) if (!region) goto type2; - if (pci_check_type1()) - return 1; + if (pci_check_type1()) { + printk(KERN_INFO "PCI: Using configuration type 1\n"); + raw_pci_ops = &pci_direct_conf1; + return; + } release_resource(region); type2: if ((pci_probe & PCI_PROBE_CONF2) == 0) - return 0; + return; region = request_region(0xCF8, 4, "PCI conf2"); if (!region) - return 0; + return; region2 = request_region(0xC000, 0x1000, "PCI conf2"); if (!region2) goto fail2; @@ -290,11 +284,10 @@ int __init pci_direct_probe(void) if (pci_check_type2()) { printk(KERN_INFO "PCI: Using configuration type 2\n"); raw_pci_ops = &pci_direct_conf2; - return 2; + return; } release_resource(region2); fail2: release_resource(region); - return 0; } diff --git a/trunk/arch/i386/pci/early.c b/trunk/arch/i386/pci/early.c deleted file mode 100644 index 713d6c866cae..000000000000 --- a/trunk/arch/i386/pci/early.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include -#include "pci.h" - -/* Direct PCI access. This is used for PCI accesses in early boot before - the PCI subsystem works. */ - -#define PDprintk(x...) - -u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) -{ - u32 v; - outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - v = inl(0xcfc); - if (v != 0xffffffff) - PDprintk("%x reading 4 from %x: %x\n", slot, offset, v); - return v; -} - -u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset) -{ - u8 v; - outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - v = inb(0xcfc + (offset&3)); - PDprintk("%x reading 1 from %x: %x\n", slot, offset, v); - return v; -} - -u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset) -{ - u16 v; - outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - v = inw(0xcfc + (offset&2)); - PDprintk("%x reading 2 from %x: %x\n", slot, offset, v); - return v; -} - -void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, - u32 val) -{ - PDprintk("%x writing to %x: %x\n", slot, offset, val); - outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - outl(val, 0xcfc); -} - -int early_pci_allowed(void) -{ - return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) == - PCI_PROBE_CONF1; -} diff --git a/trunk/arch/i386/pci/init.c b/trunk/arch/i386/pci/init.c index d028e1b05c36..51087a9d9172 100644 --- a/trunk/arch/i386/pci/init.c +++ b/trunk/arch/i386/pci/init.c @@ -6,13 +6,8 @@ in the right sequence from here. */ static __init int pci_access_init(void) { - int type = 0; - -#ifdef CONFIG_PCI_DIRECT - type = pci_direct_probe(); -#endif #ifdef CONFIG_PCI_MMCONFIG - pci_mmcfg_init(type); + pci_mmcfg_init(); #endif if (raw_pci_ops) return 0; @@ -26,7 +21,7 @@ static __init int pci_access_init(void) * fails. */ #ifdef CONFIG_PCI_DIRECT - pci_direct_init(type); + pci_direct_init(); #endif return 0; } diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c index 05be8db58a8c..972180f738d9 100644 --- a/trunk/arch/i386/pci/mmconfig.c +++ b/trunk/arch/i386/pci/mmconfig.c @@ -151,38 +151,6 @@ static struct pci_raw_ops pci_mmcfg = { .write = pci_mmcfg_write, }; - -static __init void pci_mmcfg_insert_resources(void) -{ -#define PCI_MMCFG_RESOURCE_NAME_LEN 19 - int i; - struct resource *res; - char *names; - unsigned num_buses; - - res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), - pci_mmcfg_config_num, GFP_KERNEL); - - if (!res) { - printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); - return; - } - - names = (void *)&res[pci_mmcfg_config_num]; - for (i = 0; i < pci_mmcfg_config_num; i++, res++) { - num_buses = pci_mmcfg_config[i].end_bus_number - - pci_mmcfg_config[i].start_bus_number + 1; - res->name = names; - snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", - pci_mmcfg_config[i].pci_segment_group_number); - res->start = pci_mmcfg_config[i].base_address; - res->end = res->start + (num_buses << 20) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - insert_resource(&iomem_resource, res); - names += PCI_MMCFG_RESOURCE_NAME_LEN; - } -} - /* K8 systems have some devices (typically in the builtin northbridge) that are only accessible using type1 Normally this can be expressed in the MCFG by not listing them @@ -219,9 +187,7 @@ static __init void unreachable_devices(void) } } - - -void __init pci_mmcfg_init(int type) +void __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; @@ -232,9 +198,7 @@ void __init pci_mmcfg_init(int type) (pci_mmcfg_config[0].base_address == 0)) return; - /* Only do this check when type 1 works. If it doesn't work - assume we run on a Mac and always use MCFG */ - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address, + if (!e820_all_mapped(pci_mmcfg_config[0].base_address, pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", @@ -248,5 +212,4 @@ void __init pci_mmcfg_init(int type) pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; unreachable_devices(); - pci_mmcfg_insert_resources(); } diff --git a/trunk/arch/i386/pci/pci.h b/trunk/arch/i386/pci/pci.h index 1814f74569c6..bf4e79335388 100644 --- a/trunk/arch/i386/pci/pci.h +++ b/trunk/arch/i386/pci/pci.h @@ -17,7 +17,6 @@ #define PCI_PROBE_CONF2 0x0004 #define PCI_PROBE_MMCONF 0x0008 #define PCI_PROBE_MASK 0x000f -#define PCI_PROBE_NOEARLY 0x0010 #define PCI_NO_SORT 0x0100 #define PCI_BIOS_SORT 0x0200 @@ -82,9 +81,7 @@ extern int pci_conf1_write(unsigned int seg, unsigned int bus, extern int pci_conf1_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value); -extern int pci_direct_probe(void); -extern void pci_direct_init(int type); +extern void pci_direct_init(void); extern void pci_pcbios_init(void); -extern void pci_mmcfg_init(int type); +extern void pci_mmcfg_init(void); extern void pcibios_sort(void); - diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index 15c7c670da39..60b45e79f080 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -562,8 +562,7 @@ pcibios_enable_device (struct pci_dev *dev, int mask) void pcibios_disable_device (struct pci_dev *dev) { - if (dev->is_enabled) - acpi_pci_irq_disable(dev); + acpi_pci_irq_disable(dev); } void diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 30750c54bdf5..330f6abc7703 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -126,7 +126,7 @@ config BASLER_EXCITE select IRQ_CPU select IRQ_CPU_RM7K select IRQ_CPU_RM9K - select MIPS_RM9122 + select SERIAL_RM9000 select SYS_HAS_CPU_RM9000 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL @@ -203,6 +203,26 @@ config MIPS_EV64120 . Say Y here if you wish to build a kernel for this platform. +config MIPS_EV96100 + bool "Galileo EV96100 Evaluation board (EXPERIMENTAL)" + depends on EXPERIMENTAL + select DMA_NONCOHERENT + select HW_HAS_PCI + select IRQ_CPU + select MIPS_GT96100 + select RM7000_CPU_SCACHE + select SWAP_IO_SPACE + select SYS_HAS_CPU_R5000 + select SYS_HAS_CPU_RM7000 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL + select SYS_SUPPORTS_BIG_ENDIAN + help + This is an evaluation board based on the Galileo GT-96100 LAN/WAN + communications controllers containing a MIPS R5000 compatible core + running at 83MHz. Their website is . Say Y + here if you wish to build a kernel for this platform. + config MIPS_IVR bool "Globespan IVR board" select DMA_NONCOHERENT @@ -954,12 +974,6 @@ config MIPS_TX3927 bool select HAS_TXX9_SERIAL -config MIPS_RM9122 - bool - select SERIAL_RM9000 - select GPI_RM9000 - select WDT_RM9000 - config PCI_MARVELL bool @@ -1010,15 +1024,6 @@ config EMMA2RH depends on MARKEINS default y -config SERIAL_RM9000 - bool - -config GPI_RM9000 - bool - -config WDT_RM9000 - bool - # # Unfortunately not all GT64120 systems run the chip at the same clock. # As the user for the clock rate and try to minimize the available options. @@ -1049,6 +1054,10 @@ config AU1X00_USB_DEVICE depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000 default n +config MIPS_GT96100 + bool + select MIPS_GT64120 + config IT8172_CIR bool depends on MIPS_ITE8172 || MIPS_IVR @@ -1518,7 +1527,6 @@ config MIPS_MT_SMTC select CPU_MIPSR2_SRS select MIPS_MT select SMP - select SYS_SUPPORTS_SMP help This is a kernel model which is known a SMTC or lately has been marketesed into SMVP. @@ -1530,7 +1538,6 @@ config MIPS_MT_SMP select CPU_MIPSR2_SRS select MIPS_MT select SMP - select SYS_SUPPORTS_SMP help This is a kernel model which is also known a VSMP or lately has been marketesed into SMVP. @@ -1642,7 +1649,9 @@ config GENERIC_IRQ_PROBE default y config IRQ_PER_CPU + depends on SMP bool + default y # # - Highmem only makes sense for the 32-bit kernel. @@ -1710,7 +1719,6 @@ source "mm/Kconfig" config SMP bool "Multi-Processing support" depends on SYS_SUPPORTS_SMP - select IRQ_PER_CPU help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index e521826b4234..d333ce4ba26b 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -279,6 +279,13 @@ core-$(CONFIG_MIPS_EV64120) += arch/mips/gt64120/common/ cflags-$(CONFIG_MIPS_EV64120) += -Iinclude/asm-mips/mach-ev64120 load-$(CONFIG_MIPS_EV64120) += 0xffffffff80100000 +# +# Galileo EV96100 Board +# +core-$(CONFIG_MIPS_EV96100) += arch/mips/galileo-boards/ev96100/ +cflags-$(CONFIG_MIPS_EV96100) += -Iinclude/asm-mips/mach-ev96100 +load-$(CONFIG_MIPS_EV96100) += 0xffffffff80100000 + # # Wind River PPMC Board (4KC + GT64120) # @@ -323,7 +330,6 @@ load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000 # MIPS SEAD board # core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/ -cflags-$(CONFIG_MIPS_SEAD) += -Iinclude/asm-mips/mach-mips load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000 # diff --git a/trunk/arch/mips/au1000/db1x00/Makefile b/trunk/arch/mips/au1000/db1x00/Makefile index 51d62bd5d900..4c7d763f2113 100644 --- a/trunk/arch/mips/au1000/db1x00/Makefile +++ b/trunk/arch/mips/au1000/db1x00/Makefile @@ -6,3 +6,4 @@ # Makefile for the Alchemy Semiconductor Db1x00 board. lib-y := init.o board_setup.o irqmap.o +obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o diff --git a/trunk/arch/mips/au1000/db1x00/mirage_ts.c b/trunk/arch/mips/au1000/db1x00/mirage_ts.c new file mode 100644 index 000000000000..0942dcf69518 --- /dev/null +++ b/trunk/arch/mips/au1000/db1x00/mirage_ts.c @@ -0,0 +1,260 @@ +/* + * linux/arch/mips/au1000/db1x00/mirage_ts.c + * + * BRIEF MODULE DESCRIPTION + * Glue between Mirage board-specific touchscreen pieces + * and generic Wolfson Codec touchscreen support. + * + * Based on pb1100_ts.c used in Hydrogen II. + * + * Copyright (c) 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Imported interface to Wolfson Codec driver. + */ +extern void *wm97xx_ts_get_handle(int which); +extern int wm97xx_ts_ready(void* ts_handle); +extern void wm97xx_ts_set_cal(void* ts_handle, int xscale, int xtrans, int yscale, int ytrans); +extern u16 wm97xx_ts_get_ac97(void* ts_handle, u8 reg); +extern void wm97xx_ts_set_ac97(void* ts_handle, u8 reg, u16 val); +extern int wm97xx_ts_read_data(void* ts_handle, long* x, long* y, long* pressure); +extern void wm97xx_ts_send_data(void* ts_handle, long x, long y, long z); + +int wm97xx_comodule_present = 1; + + +#define TS_NAME "mirage_ts" + +#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg) +#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg) +#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg) +#define DPRINTK(format, arg...) printk("%s: " format "\n", __FUNCTION__ , ## arg) + + +#define PEN_DOWN_IRQ AU1000_GPIO_7 + +static struct task_struct *ts_task = 0; +static DECLARE_COMPLETION(ts_complete); +static DECLARE_WAIT_QUEUE_HEAD(pendown_wait); + +#ifdef CONFIG_WM97XX_FIVEWIRETS +static int release_pressure = 1; +#else +static int release_pressure = 50; +#endif + +typedef struct { + long x; + long y; +} DOWN_EVENT; + +#define SAMPLE_RATE 50 /* samples per second */ +#define PEN_DEBOUNCE 5 /* samples for settling - fn of SAMPLE_RATE */ +#define PEN_UP_TIMEOUT 10 /* in seconds */ +#define PEN_UP_SETTLE 5 /* samples per second */ + +static struct { + int xscale; + int xtrans; + int yscale; + int ytrans; +} mirage_ts_cal = +{ +#if 0 + .xscale = 84, + .xtrans = -157, + .yscale = 66, + .ytrans = -150, +#else + .xscale = 84, + .xtrans = -150, + .yscale = 66, + .ytrans = -146, +#endif +}; + + +static void pendown_irq(int irqnr, void *devid, struct pt_regs *regs) +{ +//DPRINTK("got one 0x%x", au_readl(SYS_PINSTATERD)); + wake_up(&pendown_wait); +} + +static int ts_thread(void *id) +{ + static int pen_was_down = 0; + static DOWN_EVENT pen_xy; + long x, y, z; + void *ts; /* handle */ + struct task_struct *tsk = current; + int timeout = HZ / SAMPLE_RATE; + + ts_task = tsk; + + daemonize(); + tsk->tty = NULL; + tsk->policy = SCHED_FIFO; + tsk->rt_priority = 1; + strcpy(tsk->comm, "touchscreen"); + + /* only want to receive SIGKILL */ + spin_lock_irq(&tsk->sigmask_lock); + siginitsetinv(&tsk->blocked, sigmask(SIGKILL)); + recalc_sigpending(tsk); + spin_unlock_irq(&tsk->sigmask_lock); + + /* get handle for codec */ + ts = wm97xx_ts_get_handle(0); + + /* proceed only after everybody is ready */ + wait_event_timeout(pendown_wait, wm97xx_ts_ready(ts), HZ/4); + + /* board-specific calibration */ + wm97xx_ts_set_cal(ts, + mirage_ts_cal.xscale, + mirage_ts_cal.xtrans, + mirage_ts_cal.yscale, + mirage_ts_cal.ytrans); + + /* route Wolfson pendown interrupts to our GPIO */ + au_sync(); + wm97xx_ts_set_ac97(ts, 0x4c, wm97xx_ts_get_ac97(ts, 0x4c) & ~0x0008); + au_sync(); + wm97xx_ts_set_ac97(ts, 0x56, wm97xx_ts_get_ac97(ts, 0x56) & ~0x0008); + au_sync(); + wm97xx_ts_set_ac97(ts, 0x52, wm97xx_ts_get_ac97(ts, 0x52) | 0x2008); + au_sync(); + + for (;;) { + interruptible_sleep_on_timeout(&pendown_wait, timeout); + disable_irq(PEN_DOWN_IRQ); + if (signal_pending(tsk)) { + break; + } + + /* read codec */ + if (!wm97xx_ts_read_data(ts, &x, &y, &z)) + z = 0; /* treat no-data and pen-up the same */ + + if (signal_pending(tsk)) { + break; + } + + if (z >= release_pressure) { + y = ~y; /* top to bottom */ + if (pen_was_down > 1 /*&& pen_was_down < PEN_DEBOUNCE*/) {//THXXX + /* bounce ? */ + x = pen_xy.x; + y = pen_xy.y; + --pen_was_down; + } else if (pen_was_down <= 1) { + pen_xy.x = x; + pen_xy.y = y; + if (pen_was_down) + wm97xx_ts_send_data(ts, x, y, z); + pen_was_down = PEN_DEBOUNCE; + } + //wm97xx_ts_send_data(ts, x, y, z); + timeout = HZ / SAMPLE_RATE; + } else { + if (pen_was_down) { + if (--pen_was_down) + z = release_pressure; + else //THXXX + wm97xx_ts_send_data(ts, pen_xy.x, pen_xy.y, z); + } + /* The pendown signal takes some time to settle after + * reading the pen pressure so wait a little + * before enabling the pen. + */ + if (! pen_was_down) { +// interruptible_sleep_on_timeout(&pendown_wait, HZ / PEN_UP_SETTLE); + timeout = HZ * PEN_UP_TIMEOUT; + } + } + enable_irq(PEN_DOWN_IRQ); + } + enable_irq(PEN_DOWN_IRQ); + ts_task = NULL; + complete(&ts_complete); + return 0; +} + +static int __init ts_mirage_init(void) +{ + int ret; + + /* pen down signal is connected to GPIO 7 */ + + ret = request_irq(PEN_DOWN_IRQ, pendown_irq, 0, "ts-pendown", NULL); + if (ret) { + err("unable to get pendown irq%d: [%d]", PEN_DOWN_IRQ, ret); + return ret; + } + + lock_kernel(); + ret = kernel_thread(ts_thread, NULL, CLONE_FS | CLONE_FILES); + if (ret < 0) { + unlock_kernel(); + return ret; + } + unlock_kernel(); + + info("Mirage touchscreen IRQ initialized."); + + return 0; +} + +static void __exit ts_mirage_exit(void) +{ + if (ts_task) { + send_sig(SIGKILL, ts_task, 1); + wait_for_completion(&ts_complete); + } + + free_irq(PEN_DOWN_IRQ, NULL); +} + +module_init(ts_mirage_init); +module_exit(ts_mirage_exit); + diff --git a/trunk/arch/mips/basler/excite/excite_device.c b/trunk/arch/mips/basler/excite/excite_device.c index cc1ce77eab4a..bbb4ea43da88 100644 --- a/trunk/arch/mips/basler/excite/excite_device.c +++ b/trunk/arch/mips/basler/excite/excite_device.c @@ -68,7 +68,7 @@ enum { static struct resource - excite_ctr_resource __attribute__((unused)) = { + excite_ctr_resource = { .name = "GPI counters", .start = 0, .end = 5, @@ -77,7 +77,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_gpislice_resource __attribute__((unused)) = { + excite_gpislice_resource = { .name = "GPI slices", .start = 0, .end = 1, @@ -86,7 +86,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_mdio_channel_resource __attribute__((unused)) = { + excite_mdio_channel_resource = { .name = "MDIO channels", .start = 0, .end = 1, @@ -95,7 +95,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_fifomem_resource __attribute__((unused)) = { + excite_fifomem_resource = { .name = "FIFO memory", .start = 0, .end = 767, @@ -104,7 +104,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_scram_resource __attribute__((unused)) = { + excite_scram_resource = { .name = "Scratch RAM", .start = EXCITE_PHYS_SCRAM, .end = EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1, @@ -113,7 +113,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_fpga_resource __attribute__((unused)) = { + excite_fpga_resource = { .name = "System FPGA", .start = EXCITE_PHYS_FPGA, .end = EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1, @@ -122,7 +122,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_nand_resource __attribute__((unused)) = { + excite_nand_resource = { .name = "NAND flash control", .start = EXCITE_PHYS_NAND, .end = EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1, @@ -131,7 +131,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_titan_resource __attribute__((unused)) = { + excite_titan_resource = { .name = "TITAN registers", .start = EXCITE_PHYS_TITAN, .end = EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1, diff --git a/trunk/include/asm-mips/mach-excite/excite_fpga.h b/trunk/arch/mips/basler/excite/excite_fpga.h similarity index 100% rename from trunk/include/asm-mips/mach-excite/excite_fpga.h rename to trunk/arch/mips/basler/excite/excite_fpga.h diff --git a/trunk/arch/mips/configs/atlas_defconfig b/trunk/arch/mips/configs/atlas_defconfig index d3705284de39..54274065e9a5 100644 --- a/trunk/arch/mips/configs/atlas_defconfig +++ b/trunk/arch/mips/configs/atlas_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -1192,7 +1193,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/bigsur_defconfig b/trunk/arch/mips/configs/bigsur_defconfig index e12a475dcbf4..887fd959482a 100644 --- a/trunk/arch/mips/configs/bigsur_defconfig +++ b/trunk/arch/mips/configs/bigsur_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/capcella_defconfig b/trunk/arch/mips/configs/capcella_defconfig index bfade9abb767..a01344f3a4c2 100644 --- a/trunk/arch/mips/configs/capcella_defconfig +++ b/trunk/arch/mips/configs/capcella_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/cobalt_defconfig b/trunk/arch/mips/configs/cobalt_defconfig index 4baf2ff1128a..c95682445a28 100644 --- a/trunk/arch/mips/configs/cobalt_defconfig +++ b/trunk/arch/mips/configs/cobalt_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y CONFIG_MIPS_COBALT=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -827,7 +828,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/db1000_defconfig b/trunk/arch/mips/configs/db1000_defconfig index 93cca1585bc3..c2f33d3af62c 100644 --- a/trunk/arch/mips/configs/db1000_defconfig +++ b/trunk/arch/mips/configs/db1000_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1000=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/db1100_defconfig b/trunk/arch/mips/configs/db1100_defconfig index ffd99252a837..8c44d16ae9a2 100644 --- a/trunk/arch/mips/configs/db1100_defconfig +++ b/trunk/arch/mips/configs/db1100_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1100=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/db1200_defconfig b/trunk/arch/mips/configs/db1200_defconfig index 63eac5e89b9c..c13768e75ac5 100644 --- a/trunk/arch/mips/configs/db1200_defconfig +++ b/trunk/arch/mips/configs/db1200_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1200=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/db1500_defconfig b/trunk/arch/mips/configs/db1500_defconfig index 25a095f7dc4e..8aea73fae7fb 100644 --- a/trunk/arch/mips/configs/db1500_defconfig +++ b/trunk/arch/mips/configs/db1500_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1500=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/db1550_defconfig b/trunk/arch/mips/configs/db1550_defconfig index dda469c842b3..90ccb7359630 100644 --- a/trunk/arch/mips/configs/db1550_defconfig +++ b/trunk/arch/mips/configs/db1550_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1550=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/ddb5477_defconfig b/trunk/arch/mips/configs/ddb5477_defconfig index fcd3dd19bc74..b598cf08f156 100644 --- a/trunk/arch/mips/configs/ddb5477_defconfig +++ b/trunk/arch/mips/configs/ddb5477_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/decstation_defconfig b/trunk/arch/mips/configs/decstation_defconfig index 8683e0df12e0..597150b14077 100644 --- a/trunk/arch/mips/configs/decstation_defconfig +++ b/trunk/arch/mips/configs/decstation_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set CONFIG_MACH_DECSTATION=y # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/e55_defconfig b/trunk/arch/mips/configs/e55_defconfig index 4ace61c95778..fa2996bb4b7c 100644 --- a/trunk/arch/mips/configs/e55_defconfig +++ b/trunk/arch/mips/configs/e55_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc2 -# Tue Jul 25 23:15:03 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:02 2006 # CONFIG_MIPS=y @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -226,6 +227,7 @@ CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support # +# CONFIG_PCCARD is not set # # PCI Hotplug Support @@ -252,6 +254,7 @@ CONFIG_TRAD_SIGNALS=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set # @@ -281,7 +284,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set @@ -641,7 +643,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -649,7 +650,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x1f0,0x3f6,40 mem=8M" +CONFIG_CMDLINE="console=ttyVR0,19200 mem=8M" # # Security options diff --git a/trunk/arch/mips/configs/emma2rh_defconfig b/trunk/arch/mips/configs/emma2rh_defconfig index 5847c916c130..375b2ac24a49 100644 --- a/trunk/arch/mips/configs/emma2rh_defconfig +++ b/trunk/arch/mips/configs/emma2rh_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/ev64120_defconfig b/trunk/arch/mips/configs/ev64120_defconfig index bc4c4f125c48..b0afc118bd5c 100644 --- a/trunk/arch/mips/configs/ev64120_defconfig +++ b/trunk/arch/mips/configs/ev64120_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set CONFIG_MIPS_EV64120=y +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/ev96100_defconfig b/trunk/arch/mips/configs/ev96100_defconfig new file mode 100644 index 000000000000..0bdc10f11610 --- /dev/null +++ b/trunk/arch/mips/configs/ev96100_defconfig @@ -0,0 +1,850 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:05 2006 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MIPS_MTX1 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_PB1550 is not set +# CONFIG_MIPS_PB1200 is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_DB1550 is not set +# CONFIG_MIPS_DB1200 is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +CONFIG_MIPS_EV96100=y +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_WR_PPMC is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_3 is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_PNX8550_V2PCI is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_DDB5477 is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_MARKEINS is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_MIPS_GT64120=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_MIPS_GT96100=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +CONFIG_CPU_RM7000=y +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_R5000=y +CONFIG_SYS_HAS_CPU_RM7000=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_RM7000_CPU_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMTC is not set +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_VPE_LOADER is not set +# CONFIG_64BIT_PHYS_ADDR is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +CONFIG_HZ_1000=y +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=1000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_RELAY=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_HOTPLUG is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +# CONFIG_KMOD is not set + +# +# Block layer +# +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +# CONFIG_PCI is not set +CONFIG_MMU=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +# CONFIG_PACKET is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_NETWORK_SECMARK=y +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_WIRELESS_EXT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +CONFIG_CONNECTOR=m + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_RAID_ATTRS=m +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_MIPS_GT96100ETH=y +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +CONFIG_SERIO_RAW=m +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_FS is not set +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="" + +# +# Security options +# +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC16=m +CONFIG_CRC32=m +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_PLIST=y diff --git a/trunk/arch/mips/configs/excite_defconfig b/trunk/arch/mips/configs/excite_defconfig index eb87cbbfd037..045ebd089893 100644 --- a/trunk/arch/mips/configs/excite_defconfig +++ b/trunk/arch/mips/configs/excite_defconfig @@ -26,6 +26,7 @@ CONFIG_BASLER_EXCITE=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/ip22_defconfig b/trunk/arch/mips/configs/ip22_defconfig index cc9b24eda9e8..ef16d1fb5071 100644 --- a/trunk/arch/mips/configs/ip22_defconfig +++ b/trunk/arch/mips/configs/ip22_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -1012,7 +1013,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/ip27_defconfig b/trunk/arch/mips/configs/ip27_defconfig index 50092ba8aa71..4bf1ee7f5f00 100644 --- a/trunk/arch/mips/configs/ip27_defconfig +++ b/trunk/arch/mips/configs/ip27_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -899,7 +900,7 @@ CONFIG_FUSE_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/ip32_defconfig b/trunk/arch/mips/configs/ip32_defconfig index dec2ba6ba03f..f83dc09c3ca9 100644 --- a/trunk/arch/mips/configs/ip32_defconfig +++ b/trunk/arch/mips/configs/ip32_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/it8172_defconfig b/trunk/arch/mips/configs/it8172_defconfig index 37f9dd7187b1..a91d72a9ca86 100644 --- a/trunk/arch/mips/configs/it8172_defconfig +++ b/trunk/arch/mips/configs/it8172_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set CONFIG_MIPS_ITE8172=y # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/ivr_defconfig b/trunk/arch/mips/configs/ivr_defconfig index 18874a4c24fe..cebc67212d06 100644 --- a/trunk/arch/mips/configs/ivr_defconfig +++ b/trunk/arch/mips/configs/ivr_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set CONFIG_MIPS_IVR=y # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/jaguar-atx_defconfig b/trunk/arch/mips/configs/jaguar-atx_defconfig index 9f1e3048d623..5d9eb11aba3d 100644 --- a/trunk/arch/mips/configs/jaguar-atx_defconfig +++ b/trunk/arch/mips/configs/jaguar-atx_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -730,7 +731,7 @@ CONFIG_FUSE_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y diff --git a/trunk/arch/mips/configs/jmr3927_defconfig b/trunk/arch/mips/configs/jmr3927_defconfig index fded3f73815f..be45a9044d06 100644 --- a/trunk/arch/mips/configs/jmr3927_defconfig +++ b/trunk/arch/mips/configs/jmr3927_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/lasat200_defconfig b/trunk/arch/mips/configs/lasat200_defconfig index 320b8cdd6e58..64dc9f45a19c 100644 --- a/trunk/arch/mips/configs/lasat200_defconfig +++ b/trunk/arch/mips/configs/lasat200_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -904,7 +905,7 @@ CONFIG_FUSE_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/malta_defconfig b/trunk/arch/mips/configs/malta_defconfig index 0ba1ef5048fb..2690baf15a85 100644 --- a/trunk/arch/mips/configs/malta_defconfig +++ b/trunk/arch/mips/configs/malta_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -1229,7 +1230,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/mipssim_defconfig b/trunk/arch/mips/configs/mipssim_defconfig index adbeeadddb8f..c298979c18ae 100644 --- a/trunk/arch/mips/configs/mipssim_defconfig +++ b/trunk/arch/mips/configs/mipssim_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/mpc30x_defconfig b/trunk/arch/mips/configs/mpc30x_defconfig index 79fd544fcb2a..938b38ab5239 100644 --- a/trunk/arch/mips/configs/mpc30x_defconfig +++ b/trunk/arch/mips/configs/mpc30x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc2 -# Tue Jul 25 23:16:46 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:15 2006 # CONFIG_MIPS=y @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -70,6 +71,7 @@ CONFIG_MACH_VR41XX=y CONFIG_VICTOR_MPC30X=y # CONFIG_ZAO_CAPCELLA is not set CONFIG_PCI_VR41XX=y +CONFIG_VRC4173=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y @@ -166,7 +168,6 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set @@ -840,7 +841,7 @@ CONFIG_USB_PEGASUS=m # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set @@ -981,6 +982,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1005,7 +1007,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1013,7 +1014,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="mem=32M console=ttyVR0,19200 ide0=0x170,0x376,73" +CONFIG_CMDLINE="mem=32M console=ttyVR0,19200" # # Security options diff --git a/trunk/arch/mips/configs/ocelot_3_defconfig b/trunk/arch/mips/configs/ocelot_3_defconfig index 4d87da2b99fd..ec5758f22676 100644 --- a/trunk/arch/mips/configs/ocelot_3_defconfig +++ b/trunk/arch/mips/configs/ocelot_3_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/ocelot_c_defconfig b/trunk/arch/mips/configs/ocelot_c_defconfig index a7ac2b0a8273..0d33d87de1a1 100644 --- a/trunk/arch/mips/configs/ocelot_c_defconfig +++ b/trunk/arch/mips/configs/ocelot_c_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -773,7 +774,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/ocelot_defconfig b/trunk/arch/mips/configs/ocelot_defconfig index 853e7bba5122..4b999102715e 100644 --- a/trunk/arch/mips/configs/ocelot_defconfig +++ b/trunk/arch/mips/configs/ocelot_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -722,7 +723,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/ocelot_g_defconfig b/trunk/arch/mips/configs/ocelot_g_defconfig index 8524efa23a49..827b344f6010 100644 --- a/trunk/arch/mips/configs/ocelot_g_defconfig +++ b/trunk/arch/mips/configs/ocelot_g_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -776,7 +777,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/pb1100_defconfig b/trunk/arch/mips/configs/pb1100_defconfig index 1a16e92900cb..9ed60fef69e0 100644 --- a/trunk/arch/mips/configs/pb1100_defconfig +++ b/trunk/arch/mips/configs/pb1100_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_PB1100=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/pb1500_defconfig b/trunk/arch/mips/configs/pb1500_defconfig index 9ea8edea6f29..6774254b1be6 100644 --- a/trunk/arch/mips/configs/pb1500_defconfig +++ b/trunk/arch/mips/configs/pb1500_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_PB1500=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/pb1550_defconfig b/trunk/arch/mips/configs/pb1550_defconfig index c4a158976f8f..1afe5bf6e765 100644 --- a/trunk/arch/mips/configs/pb1550_defconfig +++ b/trunk/arch/mips/configs/pb1550_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_PB1550=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/pnx8550-jbs_defconfig b/trunk/arch/mips/configs/pnx8550-jbs_defconfig index 1cbf270c301c..ac616c82d348 100644 --- a/trunk/arch/mips/configs/pnx8550-jbs_defconfig +++ b/trunk/arch/mips/configs/pnx8550-jbs_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig index bec30b15b9bd..a8eb51bae3f3 100644 --- a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig +++ b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/qemu_defconfig b/trunk/arch/mips/configs/qemu_defconfig index f5f799e93707..6a63a113b7ea 100644 --- a/trunk/arch/mips/configs/qemu_defconfig +++ b/trunk/arch/mips/configs/qemu_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -686,7 +687,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y diff --git a/trunk/arch/mips/configs/rbhma4500_defconfig b/trunk/arch/mips/configs/rbhma4500_defconfig index 2f5650227ba3..6779f449bd2d 100644 --- a/trunk/arch/mips/configs/rbhma4500_defconfig +++ b/trunk/arch/mips/configs/rbhma4500_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/rm200_defconfig b/trunk/arch/mips/configs/rm200_defconfig index 4fee90b2b100..b7826d3a2b77 100644 --- a/trunk/arch/mips/configs/rm200_defconfig +++ b/trunk/arch/mips/configs/rm200_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -1441,7 +1442,7 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/sb1250-swarm_defconfig b/trunk/arch/mips/configs/sb1250-swarm_defconfig index 9041f095f96f..625c1c619b6b 100644 --- a/trunk/arch/mips/configs/sb1250-swarm_defconfig +++ b/trunk/arch/mips/configs/sb1250-swarm_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/sead_defconfig b/trunk/arch/mips/configs/sead_defconfig index 02abb2f1bfaf..4401b602118f 100644 --- a/trunk/arch/mips/configs/sead_defconfig +++ b/trunk/arch/mips/configs/sead_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/tb0226_defconfig b/trunk/arch/mips/configs/tb0226_defconfig index ca3d0c4ba15b..2ba4e25e8c34 100644 --- a/trunk/arch/mips/configs/tb0226_defconfig +++ b/trunk/arch/mips/configs/tb0226_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/tb0229_defconfig b/trunk/arch/mips/configs/tb0229_defconfig index 4e2009ace278..fc8a407c1add 100644 --- a/trunk/arch/mips/configs/tb0229_defconfig +++ b/trunk/arch/mips/configs/tb0229_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/tb0287_defconfig b/trunk/arch/mips/configs/tb0287_defconfig index 535a813d01a9..effcb63b81a3 100644 --- a/trunk/arch/mips/configs/tb0287_defconfig +++ b/trunk/arch/mips/configs/tb0287_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/workpad_defconfig b/trunk/arch/mips/configs/workpad_defconfig index 3a3ef20b21cc..4891d02ef8ca 100644 --- a/trunk/arch/mips/configs/workpad_defconfig +++ b/trunk/arch/mips/configs/workpad_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc2 -# Tue Jul 25 23:13:04 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:21 2006 # CONFIG_MIPS=y @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -165,7 +166,6 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set @@ -379,7 +379,6 @@ CONFIG_CONNECTOR=m CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -856,6 +855,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -880,7 +880,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -888,7 +887,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M" +CONFIG_CMDLINE="console=ttyVR0,19200 mem=16M" # # Security options diff --git a/trunk/arch/mips/configs/wrppmc_defconfig b/trunk/arch/mips/configs/wrppmc_defconfig index e6b1dea55842..3e4b16b39827 100644 --- a/trunk/arch/mips/configs/wrppmc_defconfig +++ b/trunk/arch/mips/configs/wrppmc_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/configs/yosemite_defconfig b/trunk/arch/mips/configs/yosemite_defconfig index 06a072b77b1c..3a68d8a25b66 100644 --- a/trunk/arch/mips/configs/yosemite_defconfig +++ b/trunk/arch/mips/configs/yosemite_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set diff --git a/trunk/arch/mips/defconfig b/trunk/arch/mips/defconfig index cc9b24eda9e8..fff6fcc96212 100644 --- a/trunk/arch/mips/defconfig +++ b/trunk/arch/mips/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.18-rc1 -# Thu Jul 6 10:04:10 2006 +# Thu Jul 6 09:49:33 2006 # CONFIG_MIPS=y @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -1012,7 +1013,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/galileo-boards/ev96100/Makefile b/trunk/arch/mips/galileo-boards/ev96100/Makefile new file mode 100644 index 000000000000..cd868ec78cbc --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2000 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Galileo EV96100 board. +# + +obj-y += init.o irq.o puts.o reset.o time.o setup.o diff --git a/trunk/arch/mips/galileo-boards/ev96100/init.c b/trunk/arch/mips/galileo-boards/ev96100/init.c new file mode 100644 index 000000000000..a01fe9b36f2c --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/init.c @@ -0,0 +1,173 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/generic.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* Environment variable */ + +typedef struct { + char *name; + char *val; +} t_env_var; + +int prom_argc; +char **prom_argv, **prom_envp; + +int init_debug = 0; + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +unsigned long __init prom_free_prom_memory(void) +{ + return 0; +} + +void __init prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + *cp = '\0'; +} + +char *prom_getenv(char *envname) +{ + /* + * Return a pointer to the given environment variable. + */ + + t_env_var *env = (t_env_var *) prom_envp; + int i; + + i = strlen(envname); + + while (env->name) { + if (strncmp(envname, env->name, i) == 0) { + return (env->val); + } + env++; + } + return (NULL); +} + +static inline unsigned char str2hexnum(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; /* foo */ +} + +static inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for (i = 0; i < 6; i++) { + unsigned char num; + + if ((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + + if (init_debug > 1) { + int i; + printk("get_ethernet_addr: "); + for (i = 0; i < 5; i++) + printk("%02x:", + (unsigned char) *(ethernet_addr + i)); + printk("%02x\n", *(ethernet_addr + i)); + } + + return 0; +} + +const char *get_system_type(void) +{ + return "Galileo EV96100"; +} + +void __init prom_init(void) +{ + volatile unsigned char *uart; + char ppbuf[8]; + + prom_argc = fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + mips_machgroup = MACH_GROUP_GALILEO; + mips_machtype = MACH_EV96100; + + prom_init_cmdline(); + + /* 32 MB upgradable */ + add_memory_region(0, 32 << 20, BOOT_MEM_RAM); +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/irq.c b/trunk/arch/mips/galileo-boards/ev96100/irq.c new file mode 100644 index 000000000000..ee5d6720f23b --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/irq.c @@ -0,0 +1,77 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/atlas/atlas_int.c. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline unsigned int ffz8(unsigned int word) +{ + unsigned long k; + + k = 7; + if (word & 0x0fUL) { k -= 4; word <<= 4; } + if (word & 0x30UL) { k -= 2; word <<= 2; } + if (word & 0x40UL) { k -= 1; } + + return k; +} + +extern void mips_timer_interrupt(struct pt_regs *regs); + +asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs) +{ + do_IRQ(ffz8(pending >> 8), regs); +} + +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if (pending & CAUSEF_IP7) + mips_timer_interrupt(regs); + else if (pending) + ev96100_cpu_irq(pending, regs); + else + spurious_interrupt(regs); +} + +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(0); +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/puts.c b/trunk/arch/mips/galileo-boards/ev96100/puts.c new file mode 100644 index 000000000000..49dc6d137b9c --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/puts.c @@ -0,0 +1,138 @@ + +/* + * Debug routines which directly access the uart. + */ + +#include +#include + + +//#define SERIAL_BASE EV96100_UART0_REGS_BASE +#define SERIAL_BASE 0xBD000020 +#define NS16550_BASE SERIAL_BASE + +#define SERA_CMD 0x0D +#define SERA_DATA 0x08 +//#define SERB_CMD 0x05 +#define SERB_CMD 20 +#define SERB_DATA 0x00 +#define TX_BUSY 0x20 + +#define TIMEOUT 0xffff +#undef SLOW_DOWN + +static const char digits[16] = "0123456789abcdef"; +static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE; + + +#ifdef SLOW_DOWN +static inline void slow_down() +{ + int k; + for (k = 0; k < 10000; k++); +} +#else +#define slow_down() +#endif + +void putch(const unsigned char c) +{ + unsigned char ch; + int i = 0; + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void putchar(const unsigned char c) +{ + unsigned char ch; + int i = 0; + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void puts(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } + putch('\r'); + putch('\n'); +} + +void fputs(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } +} + + +void put64(uint64_t ul) +{ + int cnt; + unsigned ch; + + cnt = 16; /* 16 nibbles in a 64 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char) (ul >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} + +void put32(unsigned u) +{ + int cnt; + unsigned ch; + + cnt = 8; /* 8 nibbles in a 32 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char) (u >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/reset.c b/trunk/arch/mips/galileo-boards/ev96100/reset.c new file mode 100644 index 000000000000..5ef9b7f896e6 --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/reset.c @@ -0,0 +1,70 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 reset routines. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/reset.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static void mips_machine_restart(char *command); +static void mips_machine_halt(void); + +static void mips_machine_restart(char *command) +{ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); + while (1); +} + +static void mips_machine_halt(void) +{ + printk(KERN_NOTICE "You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void mips_reboot_setup(void) +{ + _machine_restart = mips_machine_restart; + _machine_halt = mips_machine_halt; +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/setup.c b/trunk/arch/mips/galileo-boards/ev96100/setup.c new file mode 100644 index 000000000000..639ad5562c63 --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/setup.c @@ -0,0 +1,159 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/atlas/atlas_setup.c. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +extern char *__init prom_getcmdline(void); + +extern void mips_reboot_setup(void); + +unsigned char mac_0_1[12]; + +void __init plat_mem_setup(void) +{ + unsigned int config = read_c0_config(); + unsigned int status = read_c0_status(); + unsigned int info = read_c0_info(); + u32 tmp; + + char *argptr; + + clear_c0_status(ST0_FR); + + if (config & 0x8) + printk("Secondary cache is enabled\n"); + else + printk("Secondary cache is disabled\n"); + + if (status & (1 << 27)) + printk("User-mode cache ops enabled\n"); + else + printk("User-mode cache ops disabled\n"); + + printk("CP0 info reg: %x\n", (unsigned) info); + if (info & (1 << 28)) + printk("burst mode Scache RAMS\n"); + else + printk("pipelined Scache RAMS\n"); + + if (info & 0x1) + printk("Atomic Enable is set\n"); + + argptr = prom_getcmdline(); +#ifdef CONFIG_SERIAL_CONSOLE + if (strstr(argptr, "console=") == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS0,115200"); + } +#endif + + mips_reboot_setup(); + + set_io_port_base(KSEG1); + ioport_resource.start = GT_PCI_IO_BASE; + ioport_resource.end = GT_PCI_IO_BASE + 0x01ffffff; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); +#endif + + + /* + * Setup GT controller master bit so we can do config cycles + */ + + /* Clear cause register bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(2); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); + + tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SERR); + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + udelay(2); + GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(2); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); +} + +unsigned short get_gt_devid(void) +{ + u32 gt_devid; + + /* Figure out if this is a gt96100 or gt96100A */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(4); + gt_devid = GT_READ(GT_PCI0_CFGDATA_OFS); + + return gt_devid >> 16; +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/time.c b/trunk/arch/mips/galileo-boards/ev96100/time.c new file mode 100644 index 000000000000..8cbe8426491a --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/time.c @@ -0,0 +1,88 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 rtc routines. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/atlas/atlas_rtc.c. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) + +extern volatile unsigned long wall_jiffies; +unsigned long missed_heart_beats = 0; + +static unsigned long r4k_offset; /* Amount to increment compare reg each time */ +static unsigned long r4k_cur; /* What counter should be at next timer irq */ + +static inline void ack_r4ktimer(unsigned long newval) +{ + write_c0_compare(newval); +} + +/* + * There are a lot of conceptually broken versions of the MIPS timer interrupt + * handler floating around. This one is rather different, but the algorithm + * is probably more robust. + */ +void mips_timer_interrupt(struct pt_regs *regs) +{ + int irq = 7; /* FIX ME */ + + if (r4k_offset == 0) { + goto null; + } + + do { + kstat_this_cpu.irqs[irq]++; + do_timer(regs); +#ifndef CONFIG_SMP + update_process_times(user_mode(regs)); +#endif + r4k_cur += r4k_offset; + ack_r4ktimer(r4k_cur); + + } while (((unsigned long)read_c0_count() + - r4k_cur) < 0x7fffffff); + return; + +null: + ack_r4ktimer(0); +} diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index 9fbf8430c849..aa2caa67299a 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -38,40 +38,15 @@ static void r3081_wait(void) static void r39xx_wait(void) { - local_irq_disable(); - if (!need_resched()) - write_c0_conf(read_c0_conf() | TX39_CONF_HALT); - local_irq_enable(); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | TX39_CONF_HALT); } -/* - * There is a race when WAIT instruction executed with interrupt - * enabled. - * But it is implementation-dependent wheter the pipelie restarts when - * a non-enabled interrupt is requested. - */ static void r4k_wait(void) { - __asm__(" .set mips3 \n" - " wait \n" - " .set mips0 \n"); -} - -/* - * This variant is preferable as it allows testing need_resched and going to - * sleep depending on the outcome atomically. Unfortunately the "It is - * implementation-dependent whether the pipeline restarts when a non-enabled - * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes - * using this version a gamble. - */ -static void r4k_wait_irqoff(void) -{ - local_irq_disable(); - if (!need_resched()) - __asm__(" .set mips3 \n" - " wait \n" - " .set mips0 \n"); - local_irq_enable(); + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); } /* The Au1xxx wait is available only if using 32khz counter or @@ -81,17 +56,17 @@ int allow_au1k_wait; static void au1k_wait(void) { /* using the wait instruction makes CP0 counter unusable */ - __asm__(" .set mips3 \n" - " cache 0x14, 0(%0) \n" - " cache 0x14, 32(%0) \n" - " sync \n" - " nop \n" - " wait \n" - " nop \n" - " nop \n" - " nop \n" - " nop \n" - " .set mips0 \n" + __asm__(".set mips3\n\t" + "cache 0x14, 0(%0)\n\t" + "cache 0x14, 32(%0)\n\t" + "sync\n\t" + "nop\n\t" + "wait\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set mips0\n\t" : : "r" (au1k_wait)); } @@ -136,6 +111,7 @@ static inline void check_wait(void) case CPU_NEVADA: case CPU_RM7000: case CPU_RM9000: + case CPU_TX49XX: case CPU_4KC: case CPU_4KEC: case CPU_4KSC: @@ -149,10 +125,6 @@ static inline void check_wait(void) cpu_wait = r4k_wait; printk(" available.\n"); break; - case CPU_TX49XX: - cpu_wait = r4k_wait_irqoff; - printk(" available.\n"); - break; case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: diff --git a/trunk/arch/mips/kernel/irixsig.c b/trunk/arch/mips/kernel/irixsig.c index 2132485caa74..676e868d26fb 100644 --- a/trunk/arch/mips/kernel/irixsig.c +++ b/trunk/arch/mips/kernel/irixsig.c @@ -17,7 +17,6 @@ #include #include -#include #undef DEBUG_SIG @@ -173,12 +172,11 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info, return ret; } -void do_irix_signal(struct pt_regs *regs) +asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; int signr; - sigset_t *oldset; /* * We want the common case to go fast, which is why we may in certain @@ -186,28 +184,19 @@ void do_irix_signal(struct pt_regs *regs) * if so. */ if (!user_mode(regs)) - return; + return 1; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else + if (try_to_freeze()) + goto no_signal; + + if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { - /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } - - return; - } + if (signr > 0) + return handle_signal(signr, &info, &ka, oldset, regs); +no_signal: /* * Who's code doesn't conform to the restartable syscall convention * dies here!!! The li instruction, a single machine instruction, @@ -219,22 +208,8 @@ void do_irix_signal(struct pt_regs *regs) regs->regs[2] == ERESTARTNOINTR) { regs->cp0_epc -= 8; } - if (regs->regs[2] == ERESTART_RESTARTBLOCK) { - regs->regs[2] = __NR_restart_syscall; - regs->regs[7] = regs->regs[26]; - regs->cp0_epc -= 4; - } - regs->regs[0] = 0; /* Don't deal with this again. */ - } - - /* - * If there's no signal to deliver, we just put the saved sigmask - * back - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } + return 0; } asmlinkage void @@ -323,9 +298,6 @@ struct sigact_irix5 { int _unused0[2]; }; -#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility: - set only the low 32 bit of the sigset. */ - #ifdef DEBUG_SIG static inline void dump_sigact_irix5(struct sigact_irix5 *p) { @@ -441,7 +413,7 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new, asmlinkage int irix_sigsuspend(struct pt_regs *regs) { - sigset_t newset; + sigset_t saveset, newset; sigset_t __user *uset; uset = (sigset_t __user *) regs->regs[4]; @@ -450,15 +422,18 @@ asmlinkage int irix_sigsuspend(struct pt_regs *regs) sigdelsetmask(&newset, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; + saveset = current->blocked; current->blocked = newset; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; + regs->regs[2] = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_irix_signal(&saveset, regs)) + return -EINTR; + } } /* hate hate hate... */ diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index dc500e20cf14..450ac592da57 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -1296,3 +1296,9 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs) return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); } + +extern asmlinkage void sys_set_thread_area(u32 addr); +asmlinkage void sys32_set_thread_area(u32 addr) +{ + sys_set_thread_area(AA(addr)); +} diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index 2613a0dd4b82..7ab67f786bfe 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -273,107 +273,104 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } -/* - * - */ -struct mips_frame_info { - void *func; - unsigned long func_size; - int frame_size; - int pc_offset; -}; - -static inline int is_ra_save_ins(union mips_instruction *ip) -{ - /* sw / sd $ra, offset($sp) */ - return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) && - ip->i_format.rs == 29 && - ip->i_format.rt == 31; -} - -static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) -{ - if (ip->j_format.opcode == jal_op) - return 1; - if (ip->r_format.opcode != spec_op) - return 0; - return ip->r_format.func == jalr_op || ip->r_format.func == jr_op; -} - -static inline int is_sp_move_ins(union mips_instruction *ip) +static struct mips_frame_info { + void *func; + unsigned long func_size; + int frame_size; + int pc_offset; +} *schedule_frame, mfinfo[64]; +static int mfinfo_num; + +static int __init get_frame_info(struct mips_frame_info *info) { - /* addiu/daddiu sp,sp,-imm */ - if (ip->i_format.rs != 29 || ip->i_format.rt != 29) - return 0; - if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) - return 1; - return 0; -} - -static int get_frame_info(struct mips_frame_info *info) -{ - union mips_instruction *ip = info->func; - unsigned max_insns = info->func_size / sizeof(union mips_instruction); - unsigned i; - + int i; + void *func = info->func; + union mips_instruction *ip = (union mips_instruction *)func; info->pc_offset = -1; info->frame_size = 0; + for (i = 0; i < 128; i++, ip++) { + /* if jal, jalr, jr, stop. */ + if (ip->j_format.opcode == jal_op || + (ip->r_format.opcode == spec_op && + (ip->r_format.func == jalr_op || + ip->r_format.func == jr_op))) + break; - if (!ip) - goto err; - - if (max_insns == 0) - max_insns = 128U; /* unknown function size */ - max_insns = min(128U, max_insns); - - for (i = 0; i < max_insns; i++, ip++) { - - if (is_jal_jalr_jr_ins(ip)) + if (info->func_size && i >= info->func_size / 4) break; - if (!info->frame_size) { - if (is_sp_move_ins(ip)) - info->frame_size = - ip->i_format.simmediate; - continue; + if ( +#ifdef CONFIG_32BIT + ip->i_format.opcode == addiu_op && +#endif +#ifdef CONFIG_64BIT + ip->i_format.opcode == daddiu_op && +#endif + ip->i_format.rs == 29 && + ip->i_format.rt == 29) { + /* addiu/daddiu sp,sp,-imm */ + if (info->frame_size) + continue; + info->frame_size = - ip->i_format.simmediate; } - if (info->pc_offset == -1 && is_ra_save_ins(ip)) { + + if ( +#ifdef CONFIG_32BIT + ip->i_format.opcode == sw_op && +#endif +#ifdef CONFIG_64BIT + ip->i_format.opcode == sd_op && +#endif + ip->i_format.rs == 29 && + ip->i_format.rt == 31) { + /* sw / sd $ra, offset($sp) */ + if (info->pc_offset != -1) + continue; info->pc_offset = ip->i_format.simmediate / sizeof(long); - break; } } - if (info->frame_size && info->pc_offset >= 0) /* nested */ - return 0; - if (info->pc_offset < 0) /* leaf */ - return 1; - /* prologue seems boggus... */ -err: - return -1; -} + if (info->pc_offset == -1 || info->frame_size == 0) { + if (func == schedule) + printk("Can't analyze prologue code at %p\n", func); + info->pc_offset = -1; + info->frame_size = 0; + } -static struct mips_frame_info schedule_mfi __read_mostly; + return 0; +} static int __init frame_info_init(void) { - unsigned long size = 0; + int i; #ifdef CONFIG_KALLSYMS - unsigned long ofs; char *modname; char namebuf[KSYM_NAME_LEN + 1]; - - kallsyms_lookup((unsigned long)schedule, &size, &ofs, &modname, namebuf); + unsigned long start, size, ofs; + extern char __sched_text_start[], __sched_text_end[]; + extern char __lock_text_start[], __lock_text_end[]; + + start = (unsigned long)__sched_text_start; + for (i = 0; i < ARRAY_SIZE(mfinfo); i++) { + if (start == (unsigned long)schedule) + schedule_frame = &mfinfo[i]; + if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf)) + break; + mfinfo[i].func = (void *)(start + ofs); + mfinfo[i].func_size = size; + start += size - ofs; + if (start >= (unsigned long)__lock_text_end) + break; + if (start == (unsigned long)__sched_text_end) + start = (unsigned long)__lock_text_start; + } +#else + mfinfo[0].func = schedule; + schedule_frame = &mfinfo[0]; #endif - schedule_mfi.func = schedule; - schedule_mfi.func_size = size; - - get_frame_info(&schedule_mfi); - - /* - * Without schedule() frame info, result given by - * thread_saved_pc() and get_wchan() are not reliable. - */ - if (schedule_mfi.pc_offset < 0) - printk("Can't analyze schedule() prologue at %p\n", schedule); + for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++) + get_frame_info(&mfinfo[i]); + mfinfo_num = i; return 0; } @@ -389,86 +386,54 @@ unsigned long thread_saved_pc(struct task_struct *tsk) /* New born processes are a special case */ if (t->reg31 == (unsigned long) ret_from_fork) return t->reg31; - if (schedule_mfi.pc_offset < 0) + + if (!schedule_frame || schedule_frame->pc_offset < 0) return 0; - return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset]; + return ((unsigned long *)t->reg29)[schedule_frame->pc_offset]; } - -#ifdef CONFIG_KALLSYMS -/* used by show_backtrace() */ -unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, - unsigned long pc, unsigned long ra) +/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ +unsigned long get_wchan(struct task_struct *p) { unsigned long stack_page; - struct mips_frame_info info; - char *modname; - char namebuf[KSYM_NAME_LEN + 1]; - unsigned long size, ofs; - int leaf; - - stack_page = (unsigned long)task_stack_page(task); - if (!stack_page) - return 0; - - if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) - return 0; - /* - * Return ra if an exception occured at the first instruction - */ - if (unlikely(ofs == 0)) - return ra; + unsigned long pc; +#ifdef CONFIG_KALLSYMS + unsigned long frame; +#endif - info.func = (void *)(pc - ofs); - info.func_size = ofs; /* analyze from start to ofs */ - leaf = get_frame_info(&info); - if (leaf < 0) + if (!p || p == current || p->state == TASK_RUNNING) return 0; - if (*sp < stack_page || - *sp + info.frame_size > stack_page + THREAD_SIZE - 32) + stack_page = (unsigned long)task_stack_page(p); + if (!stack_page || !mfinfo_num) return 0; - if (leaf) - /* - * For some extreme cases, get_frame_info() can - * consider wrongly a nested function as a leaf - * one. In that cases avoid to return always the - * same value. - */ - pc = pc != ra ? ra : 0; - else - pc = ((unsigned long *)(*sp))[info.pc_offset]; - - *sp += info.frame_size; - return __kernel_text_address(pc) ? pc : 0; -} -#endif - -/* - * get_wchan - a maintenance nightmare^W^Wpain in the ass ... - */ -unsigned long get_wchan(struct task_struct *task) -{ - unsigned long pc = 0; + pc = thread_saved_pc(p); #ifdef CONFIG_KALLSYMS - unsigned long sp; -#endif + if (!in_sched_functions(pc)) + return pc; - if (!task || task == current || task->state == TASK_RUNNING) - goto out; - if (!task_stack_page(task)) - goto out; + frame = p->thread.reg29 + schedule_frame->frame_size; + do { + int i; - pc = thread_saved_pc(task); + if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32) + return 0; -#ifdef CONFIG_KALLSYMS - sp = task->thread.reg29 + schedule_mfi.frame_size; + for (i = mfinfo_num - 1; i >= 0; i--) { + if (pc >= (unsigned long) mfinfo[i].func) + break; + } + if (i < 0) + break; - while (in_sched_functions(pc)) - pc = unwind_stack(task, &sp, pc, 0); + pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; + if (!mfinfo[i].frame_size) + break; + frame += mfinfo[i].frame_size; + } while (in_sched_functions(pc)); #endif -out: return pc; } + diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index e71785102206..ba1bcd83c7d3 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -662,8 +662,6 @@ einval: li v0, -EINVAL sys sys_tee 4 sys sys_vmsplice 4 sys sys_move_pages 6 - sys sys_set_robust_list 2 - sys sys_get_robust_list 3 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/trunk/arch/mips/kernel/scall64-64.S b/trunk/arch/mips/kernel/scall64-64.S index 4c22d0b4825d..939e172db953 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -466,5 +466,3 @@ sys_call_table: PTR sys_tee /* 5265 */ PTR sys_vmsplice PTR sys_move_pages - PTR sys_set_robust_list - PTR sys_get_robust_list diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index f25c2a2f1038..98abbc5a9f13 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -247,7 +247,7 @@ EXPORT(sysn32_call_table) PTR sys_capset PTR sys32_rt_sigpending /* 6125 */ PTR compat_sys_rt_sigtimedwait - PTR sys32_rt_sigqueueinfo + PTR sys_rt_sigqueueinfo PTR sysn32_rt_sigsuspend PTR sys32_sigaltstack PTR compat_sys_utime /* 6130 */ @@ -390,7 +390,5 @@ EXPORT(sysn32_call_table) PTR sys_splice PTR sys_sync_file_range PTR sys_tee - PTR sys_vmsplice /* 6270 */ + PTR sys_vmsplice /* 6271 */ PTR sys_move_pages - PTR compat_sys_set_robust_list - PTR compat_sys_get_robust_list diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 288ee4ac4dbb..505c9ee54009 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -498,7 +498,7 @@ sys_call_table: PTR sys_mknodat /* 4290 */ PTR sys_fchownat PTR compat_sys_futimesat - PTR sys_newfstatat + PTR compat_sys_newfstatat PTR sys_unlinkat PTR sys_renameat /* 4295 */ PTR sys_linkat @@ -514,6 +514,4 @@ sys_call_table: PTR sys_tee PTR sys_vmsplice PTR compat_sys_move_pages - PTR compat_sys_set_robust_list - PTR compat_sys_get_robust_list /* 4310 */ .size sys_call_table,.-sys_call_table diff --git a/trunk/arch/mips/kernel/setup.c b/trunk/arch/mips/kernel/setup.c index fdbb508661c5..8c2b596a136f 100644 --- a/trunk/arch/mips/kernel/setup.c +++ b/trunk/arch/mips/kernel/setup.c @@ -10,15 +10,29 @@ * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 2000 2001, 2002 Maciej W. Rozycki */ +#include #include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include #include #include #include +#include #include #include @@ -82,12 +96,6 @@ void __init add_memory_region(phys_t start, phys_t size, long type) int x = boot_mem_map.nr_map; struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; - /* Sanity check */ - if (start + size < start) { - printk("Trying to add an invalid memory region, skipped\n"); - return; - } - /* * Try to merge with previous entry if any. This is far less than * perfect but is sufficient for most real world cases. @@ -135,132 +143,167 @@ static void __init print_memory_map(void) } } -/* - * Manage initrd - */ -#ifdef CONFIG_BLK_DEV_INITRD - -static int __init rd_start_early(char *p) +static inline void parse_cmdline_early(void) { - unsigned long start = memparse(p, &p); - -#ifdef CONFIG_64BIT - /* HACK: Guess if the sign extension was forgotten */ - if (start > 0x0000000080000000 && start < 0x00000000ffffffff) - start |= 0xffffffff00000000UL; -#endif - initrd_start = start; - initrd_end += start; + char c = ' ', *to = command_line, *from = saved_command_line; + unsigned long start_at, mem_size; + int len = 0; + int usermem = 0; - return 0; -} -early_param("rd_start", rd_start_early); + printk("Determined physical RAM map:\n"); + print_memory_map(); -static int __init rd_size_early(char *p) -{ - initrd_end += memparse(p, &p); + for (;;) { + /* + * "mem=XXX[kKmM]" defines a memory region from + * 0 to , overriding the determined size. + * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from + * to +, overriding the determined size. + */ + if (c == ' ' && !memcmp(from, "mem=", 4)) { + if (to != command_line) + to--; + /* + * If a user specifies memory size, we + * blow away any automatically generated + * size. + */ + if (usermem == 0) { + boot_mem_map.nr_map = 0; + usermem = 1; + } + mem_size = memparse(from + 4, &from); + if (*from == '@') + start_at = memparse(from + 1, &from); + else + start_at = 0; + add_memory_region(start_at, mem_size, BOOT_MEM_RAM); + } + c = *(from++); + if (!c) + break; + if (CL_SIZE <= ++len) + break; + *(to++) = c; + } + *to = '\0'; - return 0; + if (usermem) { + printk("User-defined physical RAM map:\n"); + print_memory_map(); + } } -early_param("rd_size", rd_size_early); -static unsigned long __init init_initrd(void) +static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_end) { - unsigned long tmp, end, size; - u32 *initrd_header; - - ROOT_DEV = Root_RAM0; - /* - * Board specific code or command line parser should have - * already set up initrd_start and initrd_end. In these cases - * perfom sanity checks and use them if all looks good. + * "rd_start=0xNNNNNNNN" defines the memory address of an initrd + * "rd_size=0xNN" it's size */ - size = initrd_end - initrd_start; - if (initrd_end == 0 || size == 0) { - initrd_start = 0; - initrd_end = 0; - } else - return initrd_end; - - end = (unsigned long)&_end; - tmp = PAGE_ALIGN(end) - sizeof(u32) * 2; - if (tmp < end) - tmp += PAGE_SIZE; - - initrd_header = (u32 *)tmp; - if (initrd_header[0] == 0x494E5244) { - initrd_start = (unsigned long)&initrd_header[2]; - initrd_end = initrd_start + initrd_header[1]; + unsigned long start = 0; + unsigned long size = 0; + unsigned long end; + char cmd_line[CL_SIZE]; + char *start_str; + char *size_str; + char *tmp; + + strcpy(cmd_line, command_line); + *command_line = 0; + tmp = cmd_line; + /* Ignore "rd_start=" strings in other parameters. */ + start_str = strstr(cmd_line, "rd_start="); + if (start_str && start_str != cmd_line && *(start_str - 1) != ' ') + start_str = strstr(start_str, " rd_start="); + while (start_str) { + if (start_str != cmd_line) + strncat(command_line, tmp, start_str - tmp); + start = memparse(start_str + 9, &start_str); + tmp = start_str + 1; + start_str = strstr(start_str, " rd_start="); } - return initrd_end; -} - -static void __init finalize_initrd(void) -{ - unsigned long size = initrd_end - initrd_start; - - if (size == 0) { - printk(KERN_INFO "Initrd not found or empty"); - goto disable; - } - if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { - printk("Initrd extends beyond end of memory"); - goto disable; + if (*tmp) + strcat(command_line, tmp); + + strcpy(cmd_line, command_line); + *command_line = 0; + tmp = cmd_line; + /* Ignore "rd_size" strings in other parameters. */ + size_str = strstr(cmd_line, "rd_size="); + if (size_str && size_str != cmd_line && *(size_str - 1) != ' ') + size_str = strstr(size_str, " rd_size="); + while (size_str) { + if (size_str != cmd_line) + strncat(command_line, tmp, size_str - tmp); + size = memparse(size_str + 8, &size_str); + tmp = size_str + 1; + size_str = strstr(size_str, " rd_size="); } + if (*tmp) + strcat(command_line, tmp); - reserve_bootmem(CPHYSADDR(initrd_start), size); - initrd_below_start_ok = 1; - - printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n", - initrd_start, size); - return; -disable: - printk(" - disabling initrd\n"); - initrd_start = 0; - initrd_end = 0; -} - -#else /* !CONFIG_BLK_DEV_INITRD */ - -#define init_initrd() 0 -#define finalize_initrd() do {} while (0) - +#ifdef CONFIG_64BIT + /* HACK: Guess if the sign extension was forgotten */ + if (start > 0x0000000080000000 && start < 0x00000000ffffffff) + start |= 0xffffffff00000000UL; #endif -/* - * Initialize the bootmem allocator. It also setup initrd related data - * if needed. - */ -#ifdef CONFIG_SGI_IP27 - -static void __init bootmem_init(void) -{ - init_initrd(); - finalize_initrd(); + end = start + size; + if (start && end) { + *rd_start = start; + *rd_end = end; + return 1; + } + return 0; } -#else /* !CONFIG_SGI_IP27 */ +#define MAXMEM HIGHMEM_START +#define MAXMEM_PFN PFN_DOWN(MAXMEM) -static void __init bootmem_init(void) +static inline void bootmem_init(void) { - unsigned long reserved_end; - unsigned long highest = 0; - unsigned long mapstart = -1UL; + unsigned long start_pfn; + unsigned long reserved_end = (unsigned long)&_end; +#ifndef CONFIG_SGI_IP27 + unsigned long first_usable_pfn; unsigned long bootmap_size; int i; +#endif +#ifdef CONFIG_BLK_DEV_INITRD + int initrd_reserve_bootmem = 0; + + /* Board specific code should have set up initrd_start and initrd_end */ + ROOT_DEV = Root_RAM0; + if (parse_rd_cmdline(&initrd_start, &initrd_end)) { + reserved_end = max(reserved_end, initrd_end); + initrd_reserve_bootmem = 1; + } else { + unsigned long tmp; + u32 *initrd_header; + + tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - sizeof(u32) * 2; + if (tmp < reserved_end) + tmp += PAGE_SIZE; + initrd_header = (u32 *)tmp; + if (initrd_header[0] == 0x494E5244) { + initrd_start = (unsigned long)&initrd_header[2]; + initrd_end = initrd_start + initrd_header[1]; + reserved_end = max(reserved_end, initrd_end); + initrd_reserve_bootmem = 1; + } + } +#endif /* CONFIG_BLK_DEV_INITRD */ /* - * Init any data related to initrd. It's a nop if INITRD is - * not selected. Once that done we can determine the low bound - * of usable memory. + * Partially used pages are not usable - thus + * we are rounding upwards. */ - reserved_end = init_initrd(); - reserved_end = PFN_UP(CPHYSADDR(max(reserved_end, (unsigned long)&_end))); + start_pfn = PFN_UP(CPHYSADDR(reserved_end)); - /* - * Find the highest page frame number we have available. - */ +#ifndef CONFIG_SGI_IP27 + /* Find the highest page frame number we have available. */ + max_pfn = 0; + first_usable_pfn = -1UL; for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; @@ -269,38 +312,56 @@ static void __init bootmem_init(void) start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr - + boot_mem_map.map[i].size); + + boot_mem_map.map[i].size); - if (end > highest) - highest = end; - if (end <= reserved_end) - continue; - if (start >= mapstart) + if (start >= end) continue; - mapstart = max(reserved_end, start); + if (end > max_pfn) + max_pfn = end; + if (start < first_usable_pfn) { + if (start > start_pfn) { + first_usable_pfn = start; + } else if (end > start_pfn) { + first_usable_pfn = start_pfn; + } + } } /* * Determine low and high memory ranges */ - if (highest > PFN_DOWN(HIGHMEM_START)) { -#ifdef CONFIG_HIGHMEM - highstart_pfn = PFN_DOWN(HIGHMEM_START); - highend_pfn = highest; + max_low_pfn = max_pfn; + if (max_low_pfn > MAXMEM_PFN) { + max_low_pfn = MAXMEM_PFN; +#ifndef CONFIG_HIGHMEM + /* Maximum memory usable is what is directly addressable */ + printk(KERN_WARNING "Warning only %ldMB will be used.\n", + MAXMEM >> 20); + printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); #endif - highest = PFN_DOWN(HIGHMEM_START); } +#ifdef CONFIG_HIGHMEM /* - * Initialize the boot-time allocator with low memory only. + * Crude, we really should make a better attempt at detecting + * highstart_pfn */ - bootmap_size = init_bootmem(mapstart, highest); + highstart_pfn = highend_pfn = max_pfn; + if (max_pfn > MAXMEM_PFN) { + highstart_pfn = MAXMEM_PFN; + printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", + (highend_pfn - highstart_pfn) >> (20 - PAGE_SHIFT)); + } +#endif + + /* Initialize the boot-time allocator with low memory only. */ + bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); /* * Register fully available low RAM pages with the bootmem allocator. */ for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long start, end, size; + unsigned long curr_pfn, last_pfn, size; /* * Reserve usable memory. @@ -308,50 +369,85 @@ static void __init bootmem_init(void) if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; - start = PFN_UP(boot_mem_map.map[i].addr); - end = PFN_DOWN(boot_mem_map.map[i].addr + /* + * We are rounding up the start address of usable memory: + */ + curr_pfn = PFN_UP(boot_mem_map.map[i].addr); + if (curr_pfn >= max_low_pfn) + continue; + if (curr_pfn < start_pfn) + curr_pfn = start_pfn; + + /* + * ... and at the end of the usable range downwards: + */ + last_pfn = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); + + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; + /* - * We are rounding up the start address of usable memory - * and at the end of the usable range downwards. + * Only register lowmem part of lowmem segment with bootmem. */ - if (start >= max_low_pfn) + size = last_pfn - curr_pfn; + if (curr_pfn > PFN_DOWN(HIGHMEM_START)) + continue; + if (curr_pfn + size - 1 > PFN_DOWN(HIGHMEM_START)) + size = PFN_DOWN(HIGHMEM_START) - curr_pfn; + if (!size) continue; - if (start < reserved_end) - start = reserved_end; - if (end > max_low_pfn) - end = max_low_pfn; /* - * ... finally, is the area going away? + * ... finally, did all the rounding and playing + * around just make the area go away? */ - if (end <= start) + if (last_pfn <= curr_pfn) continue; - size = end - start; /* Register lowmem ranges */ - free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT); - memory_present(0, start, end); + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + memory_present(0, curr_pfn, curr_pfn + size - 1); } - /* - * Reserve the bootmap memory. - */ - reserve_bootmem(PFN_PHYS(mapstart), bootmap_size); + /* Reserve the bootmap memory. */ + reserve_bootmem(PFN_PHYS(first_usable_pfn), bootmap_size); +#endif /* CONFIG_SGI_IP27 */ - /* - * Reserve initrd memory if needed. - */ - finalize_initrd(); -} +#ifdef CONFIG_BLK_DEV_INITRD + initrd_below_start_ok = 1; + if (initrd_start) { + unsigned long initrd_size = ((unsigned char *)initrd_end) - + ((unsigned char *)initrd_start); + const int width = sizeof(long) * 2; + + printk("Initial ramdisk at: 0x%p (%lu bytes)\n", + (void *)initrd_start, initrd_size); + + if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { + printk("initrd extends beyond end of memory " + "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n", + width, + (unsigned long long) CPHYSADDR(initrd_end), + width, + (unsigned long long) PFN_PHYS(max_low_pfn)); + initrd_start = initrd_end = 0; + initrd_reserve_bootmem = 0; + } -#endif /* CONFIG_SGI_IP27 */ + if (initrd_reserve_bootmem) + reserve_bootmem(CPHYSADDR(initrd_start), initrd_size); + } +#endif /* CONFIG_BLK_DEV_INITRD */ +} /* * arch_mem_init - initialize memory managment subsystem * * o plat_mem_setup() detects the memory configuration and will record detected * memory areas using add_memory_region. + * o parse_cmdline_early() parses the command line for mem= options which, + * iff detected, will override the results of the automatic detection. * * At this stage the memory configuration of the system is known to the * kernel but generic memory managment system is still entirely uninitialized. @@ -369,59 +465,25 @@ static void __init bootmem_init(void) * initialization hook for anything else was introduced. */ -static int usermem __initdata = 0; - -static int __init early_parse_mem(char *p) -{ - unsigned long start, size; - - /* - * If a user specifies memory size, we - * blow away any automatically generated - * size. - */ - if (usermem == 0) { - boot_mem_map.nr_map = 0; - usermem = 1; - } - start = 0; - size = memparse(p, &p); - if (*p == '@') - start = memparse(p + 1, &p); - - add_memory_region(start, size, BOOT_MEM_RAM); - return 0; -} -early_param("mem", early_parse_mem); +extern void plat_mem_setup(void); static void __init arch_mem_init(char **cmdline_p) { - extern void plat_mem_setup(void); - /* call board setup routine */ plat_mem_setup(); - printk("Determined physical RAM map:\n"); - print_memory_map(); - strlcpy(command_line, arcs_cmdline, sizeof(command_line)); strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; - parse_early_param(); - - if (usermem) { - printk("User-defined physical RAM map:\n"); - print_memory_map(); - } - + parse_cmdline_early(); bootmem_init(); sparse_init(); paging_init(); } -static void __init resource_init(void) +static inline void resource_init(void) { int i; @@ -442,10 +504,10 @@ static void __init resource_init(void) start = boot_mem_map.map[i].addr; end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1; - if (start >= HIGHMEM_START) + if (start >= MAXMEM) continue; - if (end >= HIGHMEM_START) - end = HIGHMEM_START - 1; + if (end >= MAXMEM) + end = MAXMEM - 1; res = alloc_bootmem(sizeof(struct resource)); switch (boot_mem_map.map[i].type) { @@ -474,6 +536,9 @@ static void __init resource_init(void) } } +#undef MAXMEM +#undef MAXMEM_PFN + void __init setup_arch(char **cmdline_p) { cpu_probe(); diff --git a/trunk/arch/mips/kernel/signal.c b/trunk/arch/mips/kernel/signal.c index b9d358e05214..6b4d9be31615 100644 --- a/trunk/arch/mips/kernel/signal.c +++ b/trunk/arch/mips/kernel/signal.c @@ -424,11 +424,15 @@ void do_signal(struct pt_regs *regs) if (!user_mode(regs)) return; + if (try_to_freeze()) + goto no_signal; + if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; + signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ @@ -442,10 +446,9 @@ void do_signal(struct pt_regs *regs) if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); } - - return; } +no_signal: /* * Who's code doesn't conform to the restartable syscall convention * dies here!!! The li instruction, a single machine instruction, @@ -463,7 +466,6 @@ void do_signal(struct pt_regs *regs) regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; } - regs->regs[0] = 0; /* Don't deal with this again. */ } /* diff --git a/trunk/arch/mips/kernel/signal32.c b/trunk/arch/mips/kernel/signal32.c index c86a5ddff050..f32a22997c3d 100644 --- a/trunk/arch/mips/kernel/signal32.c +++ b/trunk/arch/mips/kernel/signal32.c @@ -815,6 +815,9 @@ void do_signal32(struct pt_regs *regs) if (!user_mode(regs)) return; + if (try_to_freeze()) + goto no_signal; + if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else @@ -833,10 +836,9 @@ void do_signal32(struct pt_regs *regs) if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); } - - return; } +no_signal: /* * Who's code doesn't conform to the restartable syscall convention * dies here!!! The li instruction, a single machine instruction, @@ -854,7 +856,6 @@ void do_signal32(struct pt_regs *regs) regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; } - regs->regs[0] = 0; /* Don't deal with this again. */ } /* diff --git a/trunk/arch/mips/kernel/smp-mt.c b/trunk/arch/mips/kernel/smp-mt.c index 766253c44f3f..93429a4d3012 100644 --- a/trunk/arch/mips/kernel/smp-mt.c +++ b/trunk/arch/mips/kernel/smp-mt.c @@ -203,7 +203,7 @@ void plat_smp_setup(void) write_vpe_c0_config( read_c0_config()); /* make sure there are no software interrupts pending */ - write_vpe_c0_cause(0); + write_vpe_c0_cause(read_vpe_c0_cause() & ~(C_SW1|C_SW0)); /* Propagate Config7 */ write_vpe_c0_config7(read_c0_config7()); diff --git a/trunk/arch/mips/kernel/smtc-asm.S b/trunk/arch/mips/kernel/smtc-asm.S index 76cb31d57482..4cc3dea36612 100644 --- a/trunk/arch/mips/kernel/smtc-asm.S +++ b/trunk/arch/mips/kernel/smtc-asm.S @@ -8,7 +8,7 @@ #include #include #include -#include +#include /* * "Software Interrupt" linkage. diff --git a/trunk/arch/mips/kernel/syscall.c b/trunk/arch/mips/kernel/syscall.c index 9951240cc3fd..0721314db657 100644 --- a/trunk/arch/mips/kernel/syscall.c +++ b/trunk/arch/mips/kernel/syscall.c @@ -263,7 +263,7 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) return error; } -asmlinkage int sys_set_thread_area(unsigned long addr) +void sys_set_thread_area(unsigned long addr) { struct thread_info *ti = task_thread_info(current); @@ -271,8 +271,6 @@ asmlinkage int sys_set_thread_area(unsigned long addr) /* If some future MIPS implementation has this register in hardware, * we will need to update it here (and in context switches). */ - - return 0; } asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index e51d8fd9a152..954a198494ef 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -73,68 +72,28 @@ void (*board_nmi_handler_setup)(void); void (*board_ejtag_handler_setup)(void); void (*board_bind_eic_interrupt)(int irq, int regset); - -static void show_raw_backtrace(unsigned long reg29) -{ - unsigned long *sp = (unsigned long *)reg29; - unsigned long addr; - - printk("Call Trace:"); -#ifdef CONFIG_KALLSYMS - printk("\n"); -#endif - while (!kstack_end(sp)) { - addr = *sp++; - if (__kernel_text_address(addr)) - print_ip_sym(addr); - } - printk("\n"); -} - -#ifdef CONFIG_KALLSYMS -static int raw_show_trace; -static int __init set_raw_show_trace(char *str) -{ - raw_show_trace = 1; - return 1; -} -__setup("raw_show_trace", set_raw_show_trace); - -extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, - unsigned long pc, unsigned long ra); - -static void show_backtrace(struct task_struct *task, struct pt_regs *regs) -{ - unsigned long sp = regs->regs[29]; - unsigned long ra = regs->regs[31]; - unsigned long pc = regs->cp0_epc; - - if (raw_show_trace || !__kernel_text_address(pc)) { - show_raw_backtrace(sp); - return; - } - printk("Call Trace:\n"); - do { - print_ip_sym(pc); - pc = unwind_stack(task, &sp, pc, ra); - ra = 0; - } while (pc); - printk("\n"); -} -#else -#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]); -#endif +/* + * These constant is for searching for possible module text segments. + * MODULE_RANGE is a guess of how much space is likely to be vmalloced. + */ +#define MODULE_RANGE (8*1024*1024) /* * This routine abuses get_user()/put_user() to reference pointers * with at least a bit of error checking ... */ -static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) +void show_stack(struct task_struct *task, unsigned long *sp) { const int field = 2 * sizeof(unsigned long); long stackdata; int i; - unsigned long *sp = (unsigned long *)regs->regs[29]; + + if (!sp) { + if (task && task != current) + sp = (unsigned long *) task->thread.reg29; + else + sp = (unsigned long *) &sp; + } printk("Stack :"); i = 0; @@ -155,48 +114,32 @@ static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) i++; } printk("\n"); - show_backtrace(task, regs); } -static __always_inline void prepare_frametrace(struct pt_regs *regs) +void show_trace(struct task_struct *task, unsigned long *stack) { - __asm__ __volatile__( - ".set push\n\t" - ".set noat\n\t" -#ifdef CONFIG_64BIT - "1: dla $1, 1b\n\t" - "sd $1, %0\n\t" - "sd $29, %1\n\t" - "sd $31, %2\n\t" -#else - "1: la $1, 1b\n\t" - "sw $1, %0\n\t" - "sw $29, %1\n\t" - "sw $31, %2\n\t" -#endif - ".set pop\n\t" - : "=m" (regs->cp0_epc), - "=m" (regs->regs[29]), "=m" (regs->regs[31]) - : : "memory"); -} + const int field = 2 * sizeof(unsigned long); + unsigned long addr; -void show_stack(struct task_struct *task, unsigned long *sp) -{ - struct pt_regs regs; - if (sp) { - regs.regs[29] = (unsigned long)sp; - regs.regs[31] = 0; - regs.cp0_epc = 0; - } else { - if (task && task != current) { - regs.regs[29] = task->thread.reg29; - regs.regs[31] = 0; - regs.cp0_epc = task->thread.reg31; - } else { - prepare_frametrace(®s); + if (!stack) { + if (task && task != current) + stack = (unsigned long *) task->thread.reg29; + else + stack = (unsigned long *) &stack; + } + + printk("Call Trace:"); +#ifdef CONFIG_KALLSYMS + printk("\n"); +#endif + while (!kstack_end(stack)) { + addr = *stack++; + if (__kernel_text_address(addr)) { + printk(" [<%0*lx>] ", field, addr); + print_symbol("%s\n", addr); } } - show_stacktrace(task, ®s); + printk("\n"); } /* @@ -204,15 +147,9 @@ void show_stack(struct task_struct *task, unsigned long *sp) */ void dump_stack(void) { - struct pt_regs regs; + unsigned long stack; - /* - * Remove any garbage that may be in regs (specially func - * addresses) to avoid show_raw_backtrace() to report them - */ - memset(®s, 0, sizeof(regs)); - prepare_frametrace(®s); - show_backtrace(current, ®s); + show_trace(current, &stack); } EXPORT_SYMBOL(dump_stack); @@ -331,7 +268,8 @@ void show_registers(struct pt_regs *regs) print_modules(); printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", current->comm, current->pid, current_thread_info(), current); - show_stacktrace(current, regs); + show_stack(current, (long *) regs->regs[29]); + show_trace(current, (long *) regs->regs[29]); show_code((unsigned int *) regs->cp0_epc); printk("\n"); } @@ -354,16 +292,6 @@ NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) printk("%s[#%d]:\n", str, ++die_counter); show_registers(regs); spin_unlock_irq(&die_lock); - - if (in_interrupt()) - panic("Fatal exception in interrupt"); - - if (panic_on_oops) { - printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); - ssleep(5); - panic("Fatal exception"); - } - do_exit(SIGSEGV); } diff --git a/trunk/arch/mips/kernel/vpe.c b/trunk/arch/mips/kernel/vpe.c index 51ddd2166898..9ee0ec2cd067 100644 --- a/trunk/arch/mips/kernel/vpe.c +++ b/trunk/arch/mips/kernel/vpe.c @@ -768,16 +768,10 @@ int vpe_run(struct vpe * v) */ write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | v->minor); - write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~(VPECONF0_VPA)); - - back_to_back_c0_hazard(); - /* Set up the XTC bit in vpeconf0 to point at our tc */ write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC)) | (t->index << VPECONF0_XTC_SHIFT)); - back_to_back_c0_hazard(); - /* enable this VPE */ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); diff --git a/trunk/arch/mips/mips-boards/atlas/atlas_int.c b/trunk/arch/mips/mips-boards/atlas/atlas_int.c index a020a3cb4f4b..fb25e0377f11 100644 --- a/trunk/arch/mips/mips-boards/atlas/atlas_int.c +++ b/trunk/arch/mips/mips-boards/atlas/atlas_int.c @@ -1,8 +1,6 @@ /* - * Copyright (C) 1999, 2000, 2006 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard - * Maciej W. Rozycki + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * * ######################################################################## * @@ -27,20 +25,17 @@ */ #include #include -#include #include #include #include #include -#include +#include #include -#include -#include - #include #include -#include +#include + static struct atlas_ictrl_regs *atlas_hw0_icregs; @@ -52,13 +47,13 @@ static struct atlas_ictrl_regs *atlas_hw0_icregs; void disable_atlas_irq(unsigned int irq_nr) { - atlas_hw0_icregs->intrsten = 1 << (irq_nr - ATLAS_INT_BASE); + atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE)); iob(); } void enable_atlas_irq(unsigned int irq_nr) { - atlas_hw0_icregs->intseten = 1 << (irq_nr - ATLAS_INT_BASE); + atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE)); iob(); } @@ -112,7 +107,7 @@ static inline void atlas_hw0_irqdispatch(struct pt_regs *regs) if (unlikely(int_status == 0)) return; - irq = ATLAS_INT_BASE + ls1bit32(int_status); + irq = ATLASINT_BASE + ls1bit32(int_status); DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); @@ -166,14 +161,15 @@ static inline unsigned int irq_ffs(unsigned int pending) } /* - * IRQs on the Atlas board look basically like (all external interrupt - * sources are combined together on hardware interrupt 0 (MIPS IRQ 2)): + * IRQs on the Atlas board look basically (barring software IRQs which we + * don't use at all and all external interrupt sources are combined together + * on hardware interrupt 0 (MIPS IRQ 2)) like: * - * MIPS IRQ Source + * MIPS IRQ Source * -------- ------ - * 0 Software 0 (reschedule IPI on MT) - * 1 Software 1 (remote call IPI on MT) - * 2 Combined Atlas hardware interrupt (hw0) + * 0 Software (ignored) + * 1 Software (ignored) + * 2 Combined hardware interrupt (hw0) * 3 Hardware (ignored) * 4 Hardware (ignored) * 5 Hardware (ignored) @@ -183,7 +179,7 @@ static inline unsigned int irq_ffs(unsigned int pending) * We handle the IRQ according to _our_ priority which is: * * Highest ---- R4k Timer - * Lowest ---- Software 0 + * Lowest ---- Combined hardware interrupt * * then we just return, if multiple IRQs are pending then we will just take * another exception, big deal. @@ -197,19 +193,17 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) if (irq == MIPSCPU_INT_ATLAS) atlas_hw0_irqdispatch(regs); - else if (irq >= 0) + else if (irq > 0) do_IRQ(MIPSCPU_INT_BASE + irq, regs); else spurious_interrupt(regs); } -static inline void init_atlas_irqs (int base) +void __init arch_init_irq(void) { int i; - atlas_hw0_icregs = (struct atlas_ictrl_regs *) - ioremap(ATLAS_ICTRL_REGS_BASE, - sizeof(struct atlas_ictrl_regs *)); + atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *)); /* * Mask out all interrupt by writing "1" to all bit position in @@ -217,7 +211,7 @@ static inline void init_atlas_irqs (int base) */ atlas_hw0_icregs->intrsten = 0xffffffff; - for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) { + for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; @@ -225,62 +219,3 @@ static inline void init_atlas_irqs (int base) spin_lock_init(&irq_desc[i].lock); } } - -static struct irqaction atlasirq = { - .handler = no_action, - .name = "Atlas cascade" -}; - -msc_irqmap_t __initdata msc_irqmap[] = { - {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, - {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, -}; -int __initdata msc_nr_irqs = sizeof(msc_irqmap) / sizeof(*msc_irqmap); - -msc_irqmap_t __initdata msc_eicirqmap[] = { - {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_ATLAS, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, - {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} -}; -int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap) / sizeof(*msc_eicirqmap); - -void __init arch_init_irq(void) -{ - init_atlas_irqs(ATLAS_INT_BASE); - - if (!cpu_has_veic) - mips_cpu_irq_init(MIPSCPU_INT_BASE); - - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_CORE_MSC: - case MIPS_REVISION_CORID_CORE_FPGA2: - case MIPS_REVISION_CORID_CORE_FPGA3: - case MIPS_REVISION_CORID_CORE_24K: - case MIPS_REVISION_CORID_CORE_EMUL_MSC: - if (cpu_has_veic) - init_msc_irqs (MSC01E_INT_BASE, - msc_eicirqmap, msc_nr_eicirqs); - else - init_msc_irqs (MSC01C_INT_BASE, - msc_irqmap, msc_nr_irqs); - } - - - if (cpu_has_veic) { - set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch); - setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq); - } else if (cpu_has_vint) { - set_vi_handler (MIPSCPU_INT_ATLAS, atlas_hw0_irqdispatch); -#ifdef CONFIG_MIPS_MT_SMTC - setup_irq_smtc (MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, - &atlasirq, (0x100 << MIPSCPU_INT_ATLAS)); -#else /* Not SMTC */ - setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq); -#endif /* CONFIG_MIPS_MT_SMTC */ - } else - setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq); -} diff --git a/trunk/arch/mips/mips-boards/atlas/atlas_setup.c b/trunk/arch/mips/mips-boards/atlas/atlas_setup.c index 0c6b0ce15028..9871a91fdb07 100644 --- a/trunk/arch/mips/mips-boards/atlas/atlas_setup.c +++ b/trunk/arch/mips/mips-boards/atlas/atlas_setup.c @@ -77,7 +77,7 @@ static void __init serial_init(void) #else s.iobase = ATLAS_UART_REGS_BASE+3; #endif - s.irq = ATLAS_INT_UART; + s.irq = ATLASINT_UART; s.uartclk = ATLAS_BASE_BAUD * 16; s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; s.iotype = UPIO_PORT; diff --git a/trunk/arch/mips/mips-boards/generic/time.c b/trunk/arch/mips/mips-boards/generic/time.c index 8d15861fce61..557bf961f36a 100644 --- a/trunk/arch/mips/mips-boards/generic/time.c +++ b/trunk/arch/mips/mips-boards/generic/time.c @@ -41,13 +41,8 @@ #include #include - -#ifdef CONFIG_MIPS_ATLAS -#include -#endif -#ifdef CONFIG_MIPS_MALTA #include -#endif +#include unsigned long cpu_khz; @@ -97,9 +92,10 @@ extern int (*perf_irq)(struct pt_regs *regs); irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int cpu = smp_processor_id(); + int r2 = cpu_has_mips_r2; #ifdef CONFIG_MIPS_MT_SMTC - /* + /* * In an SMTC system, one Count/Compare set exists per VPE. * Which TC within a VPE gets the interrupt is essentially * random - we only know that it shouldn't be one with @@ -112,46 +108,29 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * the general MIPS timer_interrupt routine. */ - int vpflags; - /* - * We could be here due to timer interrupt, - * perf counter overflow, or both. + * DVPE is necessary so long as cross-VPE interrupts + * are done via read-modify-write of Cause register. */ - if (read_c0_cause() & (1 << 26)) - perf_irq(regs); + int vpflags = dvpe(); + write_c0_compare (read_c0_count() - 1); + clear_c0_cause(CPUCTR_IMASKBIT); + evpe(vpflags); - if (read_c0_cause() & (1 << 30)) { - /* If timer interrupt, make it de-assert */ - write_c0_compare (read_c0_count() - 1); - /* - * DVPE is necessary so long as cross-VPE interrupts - * are done via read-modify-write of Cause register. - */ - vpflags = dvpe(); - clear_c0_cause(CPUCTR_IMASKBIT); - evpe(vpflags); + if (cpu_data[cpu].vpe_id == 0) { + timer_interrupt(irq, dev_id, regs); + scroll_display_message(); + } else + write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); + smtc_timer_broadcast(cpu_data[cpu].vpe_id); + + if (cpu != 0) /* - * There are things we only want to do once per tick - * in an "MP" system. One TC of each VPE will take - * the actual timer interrupt. The others will get - * timer broadcast IPIs. We use whoever it is that takes - * the tick on VPE 0 to run the full timer_interrupt(). + * Other CPUs should do profiling and process accounting */ - if (cpu_data[cpu].vpe_id == 0) { - timer_interrupt(irq, NULL, regs); - smtc_timer_broadcast(cpu_data[cpu].vpe_id); - scroll_display_message(); - } else { - write_c0_compare(read_c0_count() + - (mips_hpt_frequency/HZ)); - local_timer_interrupt(irq, dev_id, regs); - smtc_timer_broadcast(cpu_data[cpu].vpe_id); - } - } -#else /* CONFIG_MIPS_MT_SMTC */ - int r2 = cpu_has_mips_r2; + local_timer_interrupt(irq, dev_id, regs); +#else /* CONFIG_MIPS_MT_SMTC */ if (cpu == 0) { /* * CPU 0 handles the global timer interrupt job and process @@ -182,8 +161,9 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ local_timer_interrupt(irq, dev_id, regs); } -out: #endif /* CONFIG_MIPS_MT_SMTC */ + +out: return IRQ_HANDLED; } diff --git a/trunk/arch/mips/mm/c-r3k.c b/trunk/arch/mips/mm/c-r3k.c index e1f35ef81145..bb041a22f20a 100644 --- a/trunk/arch/mips/mm/c-r3k.c +++ b/trunk/arch/mips/mm/c-r3k.c @@ -335,7 +335,7 @@ void __init r3k_cache_init(void) flush_cache_mm = r3k_flush_cache_mm; flush_cache_range = r3k_flush_cache_range; flush_cache_page = r3k_flush_cache_page; - __flush_icache_page = r3k_flush_icache_page; + flush_icache_page = r3k_flush_icache_page; flush_icache_range = r3k_flush_icache_range; flush_cache_sigtramp = r3k_flush_cache_sigtramp; diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index 0b2da53750bd..069803f58f3b 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -89,7 +89,7 @@ static inline void r4k_blast_dcache_page_dc32(unsigned long addr) blast_dcache32_page(addr); } -static void __init r4k_blast_dcache_page_setup(void) +static inline void r4k_blast_dcache_page_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -103,7 +103,7 @@ static void __init r4k_blast_dcache_page_setup(void) static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); -static void __init r4k_blast_dcache_page_indexed_setup(void) +static inline void r4k_blast_dcache_page_indexed_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -117,7 +117,7 @@ static void __init r4k_blast_dcache_page_indexed_setup(void) static void (* r4k_blast_dcache)(void); -static void __init r4k_blast_dcache_setup(void) +static inline void r4k_blast_dcache_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -202,7 +202,7 @@ static inline void tx49_blast_icache32_page_indexed(unsigned long page) static void (* r4k_blast_icache_page)(unsigned long addr); -static void __init r4k_blast_icache_page_setup(void) +static inline void r4k_blast_icache_page_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -219,7 +219,7 @@ static void __init r4k_blast_icache_page_setup(void) static void (* r4k_blast_icache_page_indexed)(unsigned long addr); -static void __init r4k_blast_icache_page_indexed_setup(void) +static inline void r4k_blast_icache_page_indexed_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -243,7 +243,7 @@ static void __init r4k_blast_icache_page_indexed_setup(void) static void (* r4k_blast_icache)(void); -static void __init r4k_blast_icache_setup(void) +static inline void r4k_blast_icache_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -264,7 +264,7 @@ static void __init r4k_blast_icache_setup(void) static void (* r4k_blast_scache_page)(unsigned long addr); -static void __init r4k_blast_scache_page_setup(void) +static inline void r4k_blast_scache_page_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -282,7 +282,7 @@ static void __init r4k_blast_scache_page_setup(void) static void (* r4k_blast_scache_page_indexed)(unsigned long addr); -static void __init r4k_blast_scache_page_indexed_setup(void) +static inline void r4k_blast_scache_page_indexed_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -300,7 +300,7 @@ static void __init r4k_blast_scache_page_indexed_setup(void) static void (* r4k_blast_scache)(void); -static void __init r4k_blast_scache_setup(void) +static inline void r4k_blast_scache_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -475,7 +475,7 @@ static inline void local_r4k_flush_cache_page(void *args) } } if (exec) { - if (cpu_has_vtag_icache && mm == current->active_mm) { + if (cpu_has_vtag_icache) { int cpu = smp_processor_id(); if (cpu_context(cpu, mm) != 0) @@ -599,7 +599,7 @@ static inline void local_r4k_flush_icache_page(void *args) * We're not sure of the virtual address(es) involved here, so * we have to flush the entire I-cache. */ - if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) { + if (cpu_has_vtag_icache) { int cpu = smp_processor_id(); if (cpu_context(cpu, vma->vm_mm) != 0) @@ -1221,7 +1221,7 @@ void au1x00_fixup_config_od(void) } } -static void __init coherency_setup(void) +static inline void coherency_setup(void) { change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); @@ -1242,7 +1242,7 @@ static void __init coherency_setup(void) clear_c0_config(CONF_CU); break; /* - * We need to catch the early Alchemy SOCs with + * We need to catch the ealry Alchemy SOCs with * the write-only co_config.od bit and set it back to one... */ case CPU_AU1000: /* rev. DA, HA, HB */ @@ -1291,7 +1291,7 @@ void __init r4k_cache_init(void) __flush_cache_all = r4k___flush_cache_all; flush_cache_mm = r4k_flush_cache_mm; flush_cache_page = r4k_flush_cache_page; - __flush_icache_page = r4k_flush_icache_page; + flush_icache_page = r4k_flush_icache_page; flush_cache_range = r4k_flush_cache_range; flush_cache_sigtramp = r4k_flush_cache_sigtramp; diff --git a/trunk/arch/mips/mm/c-sb1.c b/trunk/arch/mips/mm/c-sb1.c index 16bad7c0a63f..2d71efb82ac5 100644 --- a/trunk/arch/mips/mm/c-sb1.c +++ b/trunk/arch/mips/mm/c-sb1.c @@ -154,26 +154,6 @@ static inline void __sb1_flush_icache_all(void) } } -/* - * Invalidate a range of the icache. The addresses are virtual, and - * the cache is virtually indexed and tagged. However, we don't - * necessarily have the right ASID context, so use index ops instead - * of hit ops. - */ -static inline void __sb1_flush_icache_range(unsigned long start, - unsigned long end) -{ - start &= ~(icache_line_size - 1); - end = (end + icache_line_size - 1) & ~(icache_line_size - 1); - - while (start != end) { - cache_set_op(Index_Invalidate_I, start & icache_index_mask); - start += icache_line_size; - } - mispredict(); - sync(); -} - /* * Flush the icache for a given physical page. Need to writeback the * dcache first, then invalidate the icache. If the page isn't @@ -193,11 +173,8 @@ static void local_sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long /* * Bumping the ASID is probably cheaper than the flush ... */ - if (vma->vm_mm == current->active_mm) { - if (cpu_context(cpu, vma->vm_mm) != 0) - drop_mmu_context(vma->vm_mm, cpu); - } else - __sb1_flush_icache_range(addr, addr + PAGE_SIZE); + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); } #ifdef CONFIG_SMP @@ -233,6 +210,26 @@ void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsign __attribute__((alias("local_sb1_flush_cache_page"))); #endif +/* + * Invalidate a range of the icache. The addresses are virtual, and + * the cache is virtually indexed and tagged. However, we don't + * necessarily have the right ASID context, so use index ops instead + * of hit ops. + */ +static inline void __sb1_flush_icache_range(unsigned long start, + unsigned long end) +{ + start &= ~(icache_line_size - 1); + end = (end + icache_line_size - 1) & ~(icache_line_size - 1); + + while (start != end) { + cache_set_op(Index_Invalidate_I, start & icache_index_mask); + start += icache_line_size; + } + mispredict(); + sync(); +} + /* * Invalidate all caches on this CPU @@ -329,12 +326,9 @@ static void local_sb1_flush_icache_page(struct vm_area_struct *vma, * If there's a context, bump the ASID (cheaper than a flush, * since we don't know VAs!) */ - if (vma->vm_mm == current->active_mm) { - if (cpu_context(cpu, vma->vm_mm) != 0) - drop_mmu_context(vma->vm_mm, cpu); - } else - __sb1_flush_icache_range(start, start + PAGE_SIZE); - + if (cpu_context(cpu, vma->vm_mm) != 0) { + drop_mmu_context(vma->vm_mm, cpu); + } } #ifdef CONFIG_SMP @@ -526,7 +520,7 @@ void sb1_cache_init(void) /* These routines are for Icache coherence with the Dcache */ flush_icache_range = sb1_flush_icache_range; - __flush_icache_page = sb1_flush_icache_page; + flush_icache_page = sb1_flush_icache_page; flush_icache_all = __sb1_flush_icache_all; /* local only */ /* This implies an Icache flush too, so can't be nop'ed */ diff --git a/trunk/arch/mips/mm/c-tx39.c b/trunk/arch/mips/mm/c-tx39.c index 932a09d7ef84..5dfc9b1901f6 100644 --- a/trunk/arch/mips/mm/c-tx39.c +++ b/trunk/arch/mips/mm/c-tx39.c @@ -382,7 +382,7 @@ void __init tx39_cache_init(void) flush_cache_mm = (void *) tx39h_flush_icache_all; flush_cache_range = (void *) tx39h_flush_icache_all; flush_cache_page = (void *) tx39h_flush_icache_all; - __flush_icache_page = (void *) tx39h_flush_icache_all; + flush_icache_page = (void *) tx39h_flush_icache_all; flush_icache_range = (void *) tx39h_flush_icache_all; flush_cache_sigtramp = (void *) tx39h_flush_icache_all; @@ -408,7 +408,7 @@ void __init tx39_cache_init(void) flush_cache_mm = tx39_flush_cache_mm; flush_cache_range = tx39_flush_cache_range; flush_cache_page = tx39_flush_cache_page; - __flush_icache_page = tx39_flush_icache_page; + flush_icache_page = tx39_flush_icache_page; flush_icache_range = tx39_flush_icache_range; flush_cache_sigtramp = tx39_flush_cache_sigtramp; diff --git a/trunk/arch/mips/mm/cache.c b/trunk/arch/mips/mm/cache.c index 40c8b0235183..ddd3a2de1d73 100644 --- a/trunk/arch/mips/mm/cache.c +++ b/trunk/arch/mips/mm/cache.c @@ -25,7 +25,7 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); void (*flush_icache_range)(unsigned long start, unsigned long end); -void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page); +void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); /* MIPS specific cache operations */ void (*flush_cache_sigtramp)(unsigned long addr); @@ -70,8 +70,6 @@ void __flush_dcache_page(struct page *page) struct address_space *mapping = page_mapping(page); unsigned long addr; - if (PageHighMem(page)) - return; if (mapping && !mapping_mapped(mapping)) { SetPageDcacheDirty(page); return; @@ -93,16 +91,16 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address, { struct page *page; unsigned long pfn, addr; - int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc; pfn = pte_pfn(pte); - if (unlikely(!pfn_valid(pfn))) - return; - page = pfn_to_page(pfn); - if (page_mapping(page) && Page_dcache_dirty(page)) { - addr = (unsigned long) page_address(page); - if (exec || pages_do_alias(addr, address & PAGE_MASK)) + if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) && + Page_dcache_dirty(page)) { + if (pages_do_alias((unsigned long)page_address(page), + address & PAGE_MASK)) { + addr = (unsigned long) page_address(page); flush_data_cache_page(addr); + } + ClearPageDcacheDirty(page); } } diff --git a/trunk/arch/mips/mm/fault.c b/trunk/arch/mips/mm/fault.c index a4f8c45c4e8e..e3a617224868 100644 --- a/trunk/arch/mips/mm/fault.c +++ b/trunk/arch/mips/mm/fault.c @@ -89,7 +89,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { - if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } diff --git a/trunk/arch/mips/mm/tlb-r4k.c b/trunk/arch/mips/mm/tlb-r4k.c index 2e0e21ef433e..2cde1b772443 100644 --- a/trunk/arch/mips/mm/tlb-r4k.c +++ b/trunk/arch/mips/mm/tlb-r4k.c @@ -26,6 +26,11 @@ extern void build_tlb_refill_handler(void); */ #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + /* Atomicity and interruptability */ #ifdef CONFIG_MIPS_MT_SMTC @@ -121,7 +126,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -163,7 +168,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -197,7 +202,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) write_c0_entryhi(page | newpid); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -230,7 +235,7 @@ void local_flush_tlb_one(unsigned long page) write_c0_entryhi(page); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -274,7 +279,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) pgdp = pgd_offset(vma->vm_mm, address); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; pudp = pud_offset(pgdp, address); pmdp = pmd_offset(pudp, address); idx = read_c0_index(); @@ -315,7 +320,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, pgdp = pgd_offset(vma->vm_mm, address); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; pmdp = pmd_offset(pgdp, address); idx = read_c0_index(); ptep = pte_offset_map(pmdp, address); @@ -346,7 +351,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, wired = read_c0_wired(); write_c0_wired(wired + 1); write_c0_index(wired); - tlbw_use_hazard(); /* What is the hazard here? */ + BARRIER; write_c0_pagemask(pagemask); write_c0_entryhi(entryhi); write_c0_entrylo0(entrylo0); @@ -356,7 +361,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, tlbw_use_hazard(); write_c0_entryhi(old_ctx); - tlbw_use_hazard(); /* What is the hazard here? */ + BARRIER; write_c0_pagemask(old_pagemask); local_flush_tlb_all(); EXIT_CRITICAL(flags); diff --git a/trunk/arch/mips/pci/Makefile b/trunk/arch/mips/pci/Makefile index edefa97b2330..35d5927706ea 100644 --- a/trunk/arch/mips/pci/Makefile +++ b/trunk/arch/mips/pci/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_ITE_BOARD_GEN) += ops-it8172.o obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o obj-$(CONFIG_MIPS_GT64111) += ops-gt64111.o obj-$(CONFIG_MIPS_GT64120) += ops-gt64120.o +obj-$(CONFIG_MIPS_GT96100) += ops-gt96100.o obj-$(CONFIG_PCI_MARVELL) += ops-marvell.o obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o @@ -27,7 +28,8 @@ obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o -obj-$(CONFIG_MIPS_EV64120) += fixup-ev64120.o +obj-$(CONFIG_MIPS_EV96100) += fixup-ev64120.o +obj-$(CONFIG_MIPS_EV96100) += fixup-ev96100.o pci-ev96100.o obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o diff --git a/trunk/arch/mips/pci/fixup-atlas.c b/trunk/arch/mips/pci/fixup-atlas.c index c6cd6e9cdfbc..439510af3037 100644 --- a/trunk/arch/mips/pci/fixup-atlas.c +++ b/trunk/arch/mips/pci/fixup-atlas.c @@ -21,16 +21,16 @@ #include -#define PCIA ATLAS_INT_PCIA -#define PCIB ATLAS_INT_PCIB -#define PCIC ATLAS_INT_PCIC -#define PCID ATLAS_INT_PCID -#define INTA ATLAS_INT_INTA -#define INTB ATLAS_INT_INTB -#define ETH ATLAS_INT_ETH -#define INTC ATLAS_INT_INTC -#define SCSI ATLAS_INT_SCSI -#define INTD ATLAS_INT_INTD +#define PCIA ATLASINT_PCIA +#define PCIB ATLASINT_PCIB +#define PCIC ATLASINT_PCIC +#define PCID ATLASINT_PCID +#define INTA ATLASINT_INTA +#define INTB ATLASINT_INTB +#define ETH ATLASINT_ETH +#define INTC ATLASINT_INTC +#define SCSI ATLASINT_SCSI +#define INTD ATLASINT_INTD static char irq_tab[][5] __initdata = { /* INTA INTB INTC INTD */ diff --git a/trunk/arch/mips/pci/fixup-ev96100.c b/trunk/arch/mips/pci/fixup-ev96100.c new file mode 100644 index 000000000000..e2bc977b6d58 --- /dev/null +++ b/trunk/arch/mips/pci/fixup-ev96100.c @@ -0,0 +1,48 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * EV96100 Board specific pci fixups. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include + +static char irq_tab_ev96100[][5] __initdata = { + [8] = { 0, 5, 5, 5, 5 }, + [9] = { 0, 2, 2, 2, 2 } +}; + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + return irq_tab_ev96100[slot][pin]; +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} diff --git a/trunk/arch/mips/pci/ops-au1000.c b/trunk/arch/mips/pci/ops-au1000.c index 8ae46481fcb7..0c0c1e6519f9 100644 --- a/trunk/arch/mips/pci/ops-au1000.c +++ b/trunk/arch/mips/pci/ops-au1000.c @@ -110,7 +110,7 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, if (first_cfg) { /* reserve a wired entry for pci config accesses */ first_cfg = 0; - pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP); + pci_cfg_vm = get_vm_area(0x2000, 0); if (!pci_cfg_vm) panic (KERN_ERR "PCI unable to get vm area\n"); pci_cfg_wired_entry = read_c0_wired(); diff --git a/trunk/arch/mips/pci/ops-gt96100.c b/trunk/arch/mips/pci/ops-gt96100.c new file mode 100644 index 000000000000..9e4ea6627e21 --- /dev/null +++ b/trunk/arch/mips/pci/ops-gt96100.c @@ -0,0 +1,169 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 board specific pci support. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/pci.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +static int static gt96100_config_access(unsigned char access_type, + struct pci_bus *bus, unsigned int devfn, int where, u32 * data) +{ + unsigned char bus = bus->number; + u32 intr; + + /* + * Because of a bug in the galileo (for slot 31). + */ + if (bus == 0 && devfn >= PCI_DEVFN(31, 0)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* Clear cause register bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + udelay(2); + + + if (access_type == PCI_ACCESS_WRITE) { + if (devfn != 0) + *data = le32_to_cpu(*data); + GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else { + *data = GT_READ(GT_PCI0_CFGDATA_OFS); + if (devfn != 0) + *data = le32_to_cpu(*data); + } + + udelay(2); + + /* Check for master or target abort */ + intr = GT_READ(GT_INTRCAUSE_OFS); + + if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) { + /* Error occured */ + + /* Clear bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + return -1; + } + return 0; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int gt96100_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + u32 data = 0; + + if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + switch (size) { + case 1: + *val = (data >> ((where & 3) << 3)) & 0xff; + break; + + case 2: + *val = (data >> ((where & 3) << 3)) & 0xffff; + break; + + case 4: + *val = data; + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int gt96100_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + + switch (size) { + case 1: + if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (gt96100_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; + + case 2: + if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; + + case 4: + if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; + } +} + +struct pci_ops gt96100_pci_ops = { + .read = gt96100_pcibios_read, + .write = gt96100_pcibios_write +}; diff --git a/trunk/arch/mips/pci/pci-ev96100.c b/trunk/arch/mips/pci/pci-ev96100.c new file mode 100644 index 000000000000..f9457ea00def --- /dev/null +++ b/trunk/arch/mips/pci/pci-ev96100.c @@ -0,0 +1,63 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +static struct resource pci_io_resource = { + .name = "io pci IO space", + .start = 0x10000000, + .end = 0x11ffffff, + .flags = IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + .name = "ext pci memory space", + .start = 0x12000000, + .end = 0x13ffffff, + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops gt96100_pci_ops; + +struct pci_controller ev96100_controller = { + .pci_ops = >96100_pci_ops, + .io_resource = &pci_io_resource, + .mem_resource = &pci_mem_resource, +}; + +static void ev96100_pci_init(void) +{ + register_pci_controller(&ev96100_controller); +} + +arch_initcall(ev96100_pci_init); diff --git a/trunk/arch/mips/pci/pci-ip27.c b/trunk/arch/mips/pci/pci-ip27.c index 405ce0152739..80eb9af9ecdf 100644 --- a/trunk/arch/mips/pci/pci-ip27.c +++ b/trunk/arch/mips/pci/pci-ip27.c @@ -16,6 +16,8 @@ #include #include +extern unsigned int allocate_irqno(void); + /* * Max #PCI busses we can handle; ie, max #PCI bridges. */ diff --git a/trunk/arch/mips/sibyte/bcm1480/irq.c b/trunk/arch/mips/sibyte/bcm1480/irq.c index a0222fa4416c..ed325f0ab28a 100644 --- a/trunk/arch/mips/sibyte/bcm1480/irq.c +++ b/trunk/arch/mips/sibyte/bcm1480/irq.c @@ -469,6 +469,21 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs) #endif /* CONFIG_KGDB */ +static inline int dclz(unsigned long long x) +{ + int lz; + + __asm__ ( + " .set push \n" + " .set mips64 \n" + " dclz %0, %1 \n" + " .set pop \n" + : "=r" (lz) + : "r" (x)); + + return lz; +} + extern void bcm1480_timer_interrupt(struct pt_regs *regs); extern void bcm1480_mailbox_interrupt(struct pt_regs *regs); extern void bcm1480_kgdb_interrupt(struct pt_regs *regs); @@ -521,9 +536,9 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) if (mask_h) { if (mask_h ^ 1) - do_IRQ(fls64(mask_h) - 1, regs); + do_IRQ(63 - dclz(mask_h), regs); else - do_IRQ(63 + fls64(mask_l), regs); + do_IRQ(127 - dclz(mask_l), regs); } } } diff --git a/trunk/arch/mips/sibyte/sb1250/irq.c b/trunk/arch/mips/sibyte/sb1250/irq.c index a451b4c7732d..1de71adec6c6 100644 --- a/trunk/arch/mips/sibyte/sb1250/irq.c +++ b/trunk/arch/mips/sibyte/sb1250/irq.c @@ -419,6 +419,21 @@ static void sb1250_kgdb_interrupt(struct pt_regs *regs) #endif /* CONFIG_KGDB */ +static inline int dclz(unsigned long long x) +{ + int lz; + + __asm__ ( + " .set push \n" + " .set mips64 \n" + " dclz %0, %1 \n" + " .set pop \n" + : "=r" (lz) + : "r" (x)); + + return lz; +} + extern void sb1250_timer_interrupt(struct pt_regs *regs); extern void sb1250_mailbox_interrupt(struct pt_regs *regs); extern void sb1250_kgdb_interrupt(struct pt_regs *regs); @@ -475,6 +490,6 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(), R_IMR_INTERRUPT_STATUS_BASE))); if (mask) - do_IRQ(fls64(mask) - 1, regs); + do_IRQ(63 - dclz(mask), regs); } } diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index 723972bb5bd9..b604926401f5 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -339,7 +339,7 @@ static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase, for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0; pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) { u8 id = readb(devbase + pos + PCI_CAP_LIST_ID); - if (id == PCI_CAP_ID_HT) { + if (id == PCI_CAP_ID_HT_IRQCONF) { id = readb(devbase + pos + 3); if (id == 0x80) break; diff --git a/trunk/arch/s390/kernel/stacktrace.c b/trunk/arch/s390/kernel/stacktrace.c index d9428a0fc8fb..de83f38288d0 100644 --- a/trunk/arch/s390/kernel/stacktrace.c +++ b/trunk/arch/s390/kernel/stacktrace.c @@ -59,7 +59,9 @@ static inline unsigned long save_context_stack(struct stack_trace *trace, } } -void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +void save_stack_trace(struct stack_trace *trace, + struct task_struct *task, int all_contexts, + unsigned int skip) { register unsigned long sp asm ("15"); unsigned long orig_sp; @@ -67,23 +69,22 @@ void save_stack_trace(struct stack_trace *trace, struct task_struct *task) sp &= PSW_ADDR_INSN; orig_sp = sp; - sp = save_context_stack(trace, &trace->skip, sp, + sp = save_context_stack(trace, &skip, sp, S390_lowcore.panic_stack - PAGE_SIZE, S390_lowcore.panic_stack); - if ((sp != orig_sp) && !trace->all_contexts) + if ((sp != orig_sp) && !all_contexts) return; - sp = save_context_stack(trace, &trace->skip, sp, + sp = save_context_stack(trace, &skip, sp, S390_lowcore.async_stack - ASYNC_SIZE, S390_lowcore.async_stack); - if ((sp != orig_sp) && !trace->all_contexts) + if ((sp != orig_sp) && !all_contexts) return; if (task) - save_context_stack(trace, &trace->skip, sp, + save_context_stack(trace, &skip, sp, (unsigned long) task_stack_page(task), (unsigned long) task_stack_page(task) + THREAD_SIZE); else - save_context_stack(trace, &trace->skip, sp, - S390_lowcore.thread_info, + save_context_stack(trace, &skip, sp, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE); return; } diff --git a/trunk/arch/um/sys-i386/Makefile b/trunk/arch/um/sys-i386/Makefile index 0e32adf03be1..59cc70275754 100644 --- a/trunk/arch/um/sys-i386/Makefile +++ b/trunk/arch/um/sys-i386/Makefile @@ -4,7 +4,7 @@ obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o -subarch-obj-y = lib/bitops.o lib/semaphore.o +subarch-obj-y = lib/bitops.o kernel/semaphore.o subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index efe249e7d6b3..581ce9af0ec8 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -109,7 +109,6 @@ config X86_PC config X86_VSMP bool "Support for ScaleMP vSMP" - depends on PCI help Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is supposed to run on these EM64T-based machines. Only choose this option @@ -296,7 +295,7 @@ config NUMA config K8_NUMA bool "Old style AMD Opteron NUMA detection" - depends on NUMA && PCI + depends on NUMA default y help Enable K8 NUMA node topology detection. You should say Y here if @@ -426,6 +425,7 @@ config IOMMU config CALGARY_IOMMU bool "IBM Calgary IOMMU support" + default y select SWIOTLB depends on PCI && EXPERIMENTAL help @@ -472,7 +472,8 @@ config X86_MCE_AMD the DRAM Error Threshold. config KEXEC - bool "kexec system call" + bool "kexec system call (EXPERIMENTAL)" + depends on EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -491,14 +492,7 @@ config CRASH_DUMP bool "kernel crash dumps (EXPERIMENTAL)" depends on EXPERIMENTAL help - Generate crash dump after being started by kexec. - This should be normally only set in special crash dump kernels - which are loaded in the main kernel with kexec-tools into - a specially reserved region and then later executed after - a crash by kdump/kexec. The crash dump kernel must be compiled - to a memory address not used by the main kernel or BIOS using - PHYSICAL_START. - For more details see Documentation/kdump/kdump.txt + Generate crash dump after being started by kexec. config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) @@ -536,30 +530,6 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPRIMENTAL)" - depends on EXPERIMENTAL - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of critical functions, a canary - value on the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above, or a distribution - gcc with the feature backported. Older versions are automatically - detected and for those versions, this configuration option is ignored. - -config CC_STACKPROTECTOR_ALL - bool "Use stack-protector for all functions" - depends on CC_STACKPROTECTOR - help - Normally, GCC only inserts the canary value protection for - functions that use large-ish on-stack buffers. By enabling - this option, GCC will be asked to do this for ALL functions. - source kernel/Kconfig.hz config REORDER diff --git a/trunk/arch/x86_64/Makefile b/trunk/arch/x86_64/Makefile index 1c0f18d4f887..431bb4bc36cd 100644 --- a/trunk/arch/x86_64/Makefile +++ b/trunk/arch/x86_64/Makefile @@ -54,16 +54,6 @@ endif cflags-y += $(call cc-option,-funit-at-a-time) # prevent gcc from generating any FP code by mistake cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) -# do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) - -# is .cfi_signal_frame supported too? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) - -cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector ) -cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector-all ) CFLAGS += $(cflags-y) CFLAGS_KERNEL += $(cflags-kernel-y) diff --git a/trunk/arch/x86_64/boot/compressed/Makefile b/trunk/arch/x86_64/boot/compressed/Makefile index e70fa6e1da08..f89d96f11a9f 100644 --- a/trunk/arch/x86_64/boot/compressed/Makefile +++ b/trunk/arch/x86_64/boot/compressed/Makefile @@ -7,8 +7,7 @@ # targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o -EXTRA_AFLAGS := -traditional -AFLAGS := $(subst -m64,-m32,$(AFLAGS)) +EXTRA_AFLAGS := -traditional -m32 # cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with # -m32 diff --git a/trunk/arch/x86_64/boot/setup.S b/trunk/arch/x86_64/boot/setup.S index c3bfd223ab49..a50b631f4d2b 100644 --- a/trunk/arch/x86_64/boot/setup.S +++ b/trunk/arch/x86_64/boot/setup.S @@ -526,12 +526,12 @@ is_disk1: movw %cs, %ax # aka SETUPSEG subw $DELTA_INITSEG, %ax # aka INITSEG movw %ax, %ds - movb $0, (0x1ff) # default is no pointing device + movw $0, (0x1ff) # default is no pointing device int $0x11 # int 0x11: equipment list testb $0x04, %al # check if mouse installed jz no_psmouse - movb $0xAA, (0x1ff) # device present + movw $0xAA, (0x1ff) # device present no_psmouse: #include "../../i386/boot/edd.S" diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 647610ecb580..5fb970715941 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-git5 -# Tue Sep 26 09:30:47 2006 +# Linux kernel version: 2.6.18-rc4 +# Thu Aug 24 21:05:55 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -19,7 +19,6 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_DMI=y -CONFIG_AUDIT_ARCH=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -39,16 +38,16 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set -CONFIG_UID16=y -CONFIG_SYSCTL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -57,12 +56,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -161,7 +160,6 @@ CONFIG_X86_MCE_AMD=y # CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x200000 CONFIG_SECCOMP=y -# CONFIG_CC_STACKPROTECTOR is not set # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set @@ -309,23 +307,18 @@ CONFIG_IP_PNP_DHCP=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set # CONFIG_INET6_XFRM_MODE_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set # CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -352,6 +345,7 @@ CONFIG_IPV6=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -493,7 +487,6 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y # CONFIG_SCSI_PROC_FS is not set # @@ -515,13 +508,12 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_ISCSI_ATTRS is not set CONFIG_SCSI_SAS_ATTRS=y -# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers @@ -540,14 +532,29 @@ CONFIG_AIC79XX_RESET_DELAY_MS=4000 # CONFIG_AIC79XX_DEBUG_ENABLE is not set CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_ARCMSR is not set CONFIG_MEGARAID_NEWGEN=y CONFIG_MEGARAID_MM=y CONFIG_MEGARAID_MAILBOX=y # CONFIG_MEGARAID_LEGACY is not set CONFIG_MEGARAID_SAS=y +CONFIG_SCSI_SATA=y +CONFIG_SCSI_SATA_AHCI=y +CONFIG_SCSI_SATA_SVW=y +CONFIG_SCSI_ATA_PIIX=y +# CONFIG_SCSI_SATA_MV is not set +CONFIG_SCSI_SATA_NV=y +# CONFIG_SCSI_PDC_ADMA is not set # CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SATA_QSTOR is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +CONFIG_SCSI_SATA_SIL=y +# CONFIG_SCSI_SATA_SIL24 is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +CONFIG_SCSI_SATA_VIA=y +# CONFIG_SCSI_SATA_VITESSE is not set +CONFIG_SCSI_SATA_INTEL_COMBINED=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set @@ -556,7 +563,6 @@ CONFIG_MEGARAID_SAS=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -566,62 +572,6 @@ CONFIG_MEGARAID_SAS=y # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_SATA_SVW=y -CONFIG_ATA_PIIX=y -# CONFIG_SATA_MV is not set -CONFIG_SATA_NV=y -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -CONFIG_SATA_SIL=y -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -CONFIG_SATA_VIA=y -# CONFIG_SATA_VITESSE is not set -CONFIG_SATA_INTEL_COMBINED=y -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_LEGACY is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_QDI is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set - # # Multi-device support (RAID and LVM) # @@ -728,7 +678,6 @@ CONFIG_NET_PCI=y # CONFIG_ADAPTEC_STARFIRE is not set CONFIG_B44=y CONFIG_FORCEDETH=y -# CONFIG_FORCEDETH_NAPI is not set # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y @@ -765,7 +714,6 @@ CONFIG_E1000=y # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y CONFIG_BNX2=y -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -1088,7 +1036,6 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -CONFIG_OSS_OBSOLETE_DRIVER=y # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set @@ -1099,6 +1046,7 @@ CONFIG_SOUND_ICH=y # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support @@ -1255,6 +1203,7 @@ CONFIG_USB_MON=y # InfiniBand support # # CONFIG_INFINIBAND is not set +# CONFIG_IPATH_CORE is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -1499,6 +1448,10 @@ CONFIG_DEBUG_STACKOVERFLOW=y # # CONFIG_CRYPTO is not set +# +# Hardware crypto devices +# + # # Library routines # diff --git a/trunk/arch/x86_64/ia32/ia32_aout.c b/trunk/arch/x86_64/ia32/ia32_aout.c index 396d3c100011..3bf58af98936 100644 --- a/trunk/arch/x86_64/ia32/ia32_aout.c +++ b/trunk/arch/x86_64/ia32/ia32_aout.c @@ -333,8 +333,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) return error; } - error = bprm->file->f_op->read(bprm->file, - (char __user *)text_addr, + error = bprm->file->f_op->read(bprm->file, (char *)text_addr, ex.a_text+ex.a_data, &pos); if ((signed long)error < 0) { send_sig(SIGKILL, current, 0); @@ -367,8 +366,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) down_write(¤t->mm->mmap_sem); do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); up_write(¤t->mm->mmap_sem); - bprm->file->f_op->read(bprm->file, - (char __user *)N_TXTADDR(ex), + bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); flush_icache_range((unsigned long) N_TXTADDR(ex), (unsigned long) N_TXTADDR(ex) + @@ -479,7 +477,7 @@ static int load_aout_library(struct file *file) do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); up_write(¤t->mm->mmap_sem); - file->f_op->read(file, (char __user *)start_addr, + file->f_op->read(file, (char *)start_addr, ex.a_text + ex.a_data, &pos); flush_icache_range((unsigned long) start_addr, (unsigned long) start_addr + ex.a_text + ex.a_data); diff --git a/trunk/arch/x86_64/ia32/ia32_signal.c b/trunk/arch/x86_64/ia32/ia32_signal.c index a6ba9951e86c..25e5ca22204c 100644 --- a/trunk/arch/x86_64/ia32/ia32_signal.c +++ b/trunk/arch/x86_64/ia32/ia32_signal.c @@ -113,19 +113,25 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) } asmlinkage long -sys32_sigsuspend(int history0, int history1, old_sigset_t mask) +sys32_sigsuspend(int history0, int history1, old_sigset_t mask, + struct pt_regs *regs) { + sigset_t saveset; + mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; + saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; + regs->rax = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(regs, &saveset)) + return -EINTR; + } } asmlinkage long @@ -431,7 +437,15 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; - err |= __put_user(sig, &frame->sig); + { + struct exec_domain *ed = current_thread_info()->exec_domain; + err |= __put_user((ed + && ed->signal_invmap + && sig < 32 + ? ed->signal_invmap[sig] + : sig), + &frame->sig); + } if (err) goto give_sigsegv; @@ -478,11 +492,6 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, regs->rsp = (unsigned long) frame; regs->rip = (unsigned long) ka->sa.sa_handler; - /* Make -mregparm=3 work */ - regs->rax = sig; - regs->rdx = 0; - regs->rcx = 0; - asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); @@ -490,20 +499,20 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, regs->ss = __USER32_DS; set_fs(USER_DS); - regs->eflags &= ~TF_MASK; - if (test_thread_flag(TIF_SINGLESTEP)) - ptrace_notify(SIGTRAP); + regs->eflags &= ~TF_MASK; + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); #if DEBUG_SIG printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif - return 0; + return 1; give_sigsegv: force_sigsegv(sig, current); - return -EFAULT; + return 0; } int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, @@ -586,18 +595,18 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->ss = __USER32_DS; set_fs(USER_DS); - regs->eflags &= ~TF_MASK; - if (test_thread_flag(TIF_SINGLESTEP)) - ptrace_notify(SIGTRAP); + regs->eflags &= ~TF_MASK; + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); #if DEBUG_SIG printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif - return 0; + return 1; give_sigsegv: force_sigsegv(sig, current); - return -EFAULT; + return 0; } diff --git a/trunk/arch/x86_64/ia32/ia32entry.S b/trunk/arch/x86_64/ia32/ia32entry.S index b4aa875e175b..5d4a7d125ed0 100644 --- a/trunk/arch/x86_64/ia32/ia32entry.S +++ b/trunk/arch/x86_64/ia32/ia32entry.S @@ -71,7 +71,6 @@ */ ENTRY(ia32_sysenter_target) CFI_STARTPROC32 simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp swapgs @@ -187,7 +186,6 @@ ENDPROC(ia32_sysenter_target) */ ENTRY(ia32_cstar_target) CFI_STARTPROC32 simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,PDA_STACKOFFSET CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ @@ -295,7 +293,6 @@ ia32_badarg: ENTRY(ia32_syscall) CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8-RIP /*CFI_REL_OFFSET ss,SS-RIP*/ CFI_REL_OFFSET rsp,RSP-RIP @@ -373,7 +370,6 @@ ENTRY(ia32_ptregs_common) popq %r11 CFI_ENDPROC CFI_STARTPROC32 simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8-ARGOFFSET CFI_REL_OFFSET rax,RAX-ARGOFFSET CFI_REL_OFFSET rcx,RCX-ARGOFFSET @@ -707,8 +703,8 @@ ia32_sys_call_table: .quad sys_readlinkat /* 305 */ .quad sys_fchmodat .quad sys_faccessat - .quad compat_sys_pselect6 - .quad compat_sys_ppoll + .quad quiet_ni_syscall /* pselect6 for now */ + .quad quiet_ni_syscall /* ppoll for now */ .quad sys_unshare /* 310 */ .quad compat_sys_set_robust_list .quad compat_sys_get_robust_list @@ -717,5 +713,4 @@ ia32_sys_call_table: .quad sys_tee .quad compat_sys_vmsplice .quad compat_sys_move_pages - .quad sys_getcpu ia32_syscall_end: diff --git a/trunk/arch/x86_64/ia32/ptrace32.c b/trunk/arch/x86_64/ia32/ptrace32.c index d18198ed636b..659c0722f6b8 100644 --- a/trunk/arch/x86_64/ia32/ptrace32.c +++ b/trunk/arch/x86_64/ia32/ptrace32.c @@ -117,10 +117,6 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 val) if ((0x5454 >> ((val >> (16 + 4*i)) & 0xf)) & 1) return -EIO; child->thread.debugreg7 = val; - if (val) - set_tsk_thread_flag(child, TIF_DEBUG); - else - clear_tsk_thread_flag(child, TIF_DEBUG); break; default: @@ -375,10 +371,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) ret = -EIO; if (!access_ok(VERIFY_READ, u, sizeof(*u))) break; - /* no checking to be bug-to-bug compatible with i386. */ - /* but silence warning */ - if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u))) - ; + /* no checking to be bug-to-bug compatible with i386 */ + __copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)); set_stopped_child_used_math(child); child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask; ret = 0; diff --git a/trunk/arch/x86_64/ia32/sys_ia32.c b/trunk/arch/x86_64/ia32/sys_ia32.c index b0e82c7947dc..9c130993380d 100644 --- a/trunk/arch/x86_64/ia32/sys_ia32.c +++ b/trunk/arch/x86_64/ia32/sys_ia32.c @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -390,9 +389,7 @@ sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, } } set_fs (KERNEL_DS); - ret = sys_rt_sigprocmask(how, - set ? (sigset_t __user *)&s : NULL, - oset ? (sigset_t __user *)&s : NULL, + ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize); set_fs (old_fs); if (ret) return ret; @@ -544,7 +541,7 @@ sys32_sysinfo(struct sysinfo32 __user *info) int bitcount = 0; set_fs (KERNEL_DS); - ret = sys_sysinfo((struct sysinfo __user *)&s); + ret = sys_sysinfo(&s); set_fs (old_fs); /* Check to see if any memory value is too large for 32-bit and scale @@ -592,7 +589,7 @@ sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *int mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); - ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t); + ret = sys_sched_rr_get_interval(pid, &t); set_fs (old_fs); if (put_compat_timespec(&t, interval)) return -EFAULT; @@ -608,7 +605,7 @@ sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) mm_segment_t old_fs = get_fs(); set_fs (KERNEL_DS); - ret = sys_rt_sigpending((sigset_t __user *)&s, sigsetsize); + ret = sys_rt_sigpending(&s, sigsetsize); set_fs (old_fs); if (!ret) { switch (_NSIG_WORDS) { @@ -633,7 +630,7 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) if (copy_siginfo_from_user32(&info, uinfo)) return -EFAULT; set_fs (KERNEL_DS); - ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info); + ret = sys_rt_sigqueueinfo(pid, sig, &info); set_fs (old_fs); return ret; } @@ -669,6 +666,9 @@ sys32_sysctl(struct sysctl_ia32 __user *args32) size_t oldlen; int __user *namep; long ret; + extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp, + void *newval, size_t newlen); + if (copy_from_user(&a32, args32, sizeof (a32))) return -EFAULT; @@ -692,8 +692,7 @@ sys32_sysctl(struct sysctl_ia32 __user *args32) set_fs(KERNEL_DS); lock_kernel(); - ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *)&oldlen, - newvalp, (size_t) a32.newlen); + ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen); unlock_kernel(); set_fs(old_fs); @@ -744,8 +743,7 @@ sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) return -EFAULT; set_fs(KERNEL_DS); - ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, - count); + ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); set_fs(old_fs); if (offset && put_user(of, offset)) @@ -780,7 +778,7 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, asmlinkage long sys32_olduname(struct oldold_utsname __user * name) { - int err; + int error; if (!name) return -EFAULT; @@ -789,31 +787,27 @@ asmlinkage long sys32_olduname(struct oldold_utsname __user * name) down_read(&uts_sem); - err = __copy_to_user(&name->sysname,&system_utsname.sysname, - __OLD_UTS_LEN); - err |= __put_user(0,name->sysname+__OLD_UTS_LEN); - err |= __copy_to_user(&name->nodename,&system_utsname.nodename, - __OLD_UTS_LEN); - err |= __put_user(0,name->nodename+__OLD_UTS_LEN); - err |= __copy_to_user(&name->release,&system_utsname.release, - __OLD_UTS_LEN); - err |= __put_user(0,name->release+__OLD_UTS_LEN); - err |= __copy_to_user(&name->version,&system_utsname.version, - __OLD_UTS_LEN); - err |= __put_user(0,name->version+__OLD_UTS_LEN); + error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); + __put_user(0,name->sysname+__OLD_UTS_LEN); + __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); + __put_user(0,name->nodename+__OLD_UTS_LEN); + __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); + __put_user(0,name->release+__OLD_UTS_LEN); + __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); + __put_user(0,name->version+__OLD_UTS_LEN); { char *arch = "x86_64"; if (personality(current->personality) == PER_LINUX32) arch = "i686"; - err |= __copy_to_user(&name->machine,arch,strlen(arch)+1); + __copy_to_user(&name->machine,arch,strlen(arch)+1); } up_read(&uts_sem); - err = err ? -EFAULT : 0; + error = error ? -EFAULT : 0; - return err; + return error; } long sys32_uname(struct old_utsname __user * name) @@ -837,7 +831,7 @@ long sys32_ustat(unsigned dev, struct ustat32 __user *u32p) seg = get_fs(); set_fs(KERNEL_DS); - ret = sys_ustat(dev, (struct ustat __user *)&u); + ret = sys_ustat(dev,&u); set_fs(seg); if (ret >= 0) { if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) || diff --git a/trunk/arch/x86_64/kernel/Makefile b/trunk/arch/x86_64/kernel/Makefile index 3c7cbff04d3d..b5aaeafc1cd3 100644 --- a/trunk/arch/x86_64/kernel/Makefile +++ b/trunk/arch/x86_64/kernel/Makefile @@ -11,7 +11,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ pci-dma.o pci-nommu.o alternative.o obj-$(CONFIG_STACKTRACE) += stacktrace.o -obj-$(CONFIG_X86_MCE) += mce.o therm_throt.o +obj-$(CONFIG_X86_MCE) += mce.o obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o obj-$(CONFIG_X86_MCE_AMD) += mce_amd.o obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/ @@ -20,8 +20,8 @@ obj-$(CONFIG_X86_MSR) += msr.o obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o -obj-y += apic.o nmi.o -obj-y += io_apic.o mpparse.o \ +obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o +obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \ genapic.o genapic_cluster.o genapic_flat.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o @@ -39,14 +39,12 @@ obj-$(CONFIG_K8_NB) += k8.o obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_MODULES) += module.o -obj-$(CONFIG_PCI) += early-quirks.o obj-y += topology.o obj-y += intel_cacheinfo.o CFLAGS_vsyscall.o := $(PROFILING) -g0 -therm_throt-y += ../../i386/kernel/cpu/mcheck/therm_throt.o bootflag-y += ../../i386/kernel/bootflag.o cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o topology-y += ../../i386/kernel/topology.o @@ -56,3 +54,4 @@ quirks-y += ../../i386/kernel/quirks.o i8237-y += ../../i386/kernel/i8237.o msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o alternative-y += ../../i386/kernel/alternative.o + diff --git a/trunk/arch/x86_64/kernel/aperture.c b/trunk/arch/x86_64/kernel/aperture.c index b487396c4c5b..58af8e73738b 100644 --- a/trunk/arch/x86_64/kernel/aperture.c +++ b/trunk/arch/x86_64/kernel/aperture.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -34,18 +33,6 @@ int fallback_aper_force __initdata = 0; int fix_aperture __initdata = 1; -static struct resource gart_resource = { - .name = "GART", - .flags = IORESOURCE_MEM, -}; - -static void __init insert_aperture_resource(u32 aper_base, u32 aper_size) -{ - gart_resource.start = aper_base; - gart_resource.end = aper_base + aper_size - 1; - insert_resource(&iomem_resource, &gart_resource); -} - /* This code runs before the PCI subsystem is initialized, so just access the northbridge directly. */ @@ -61,7 +48,7 @@ static u32 __init allocate_aperture(void) /* * Aperture has to be naturally aligned. This means an 2GB aperture won't - * have much chance of finding a place in the lower 4GB of memory. + * have much chances to find a place in the lower 4GB of memory. * Unfortunately we cannot move it up because that would make the * IOMMU useless. */ @@ -75,7 +62,6 @@ static u32 __init allocate_aperture(void) } printk("Mapping aperture over %d KB of RAM @ %lx\n", aper_size >> 10, __pa(p)); - insert_aperture_resource((u32)__pa(p), aper_size); return (u32)__pa(p); } @@ -212,7 +198,7 @@ void __init iommu_hole_init(void) u64 aper_base, last_aper_base = 0; int valid_agp = 0; - if (iommu_aperture_disabled || !fix_aperture || !early_pci_allowed()) + if (iommu_aperture_disabled || !fix_aperture) return; printk("Checking aperture...\n"); @@ -247,13 +233,8 @@ void __init iommu_hole_init(void) last_aper_base = aper_base; } - if (!fix && !fallback_aper_force) { - if (last_aper_base) { - unsigned long n = (32 * 1024 * 1024) << last_aper_order; - insert_aperture_resource((u32)last_aper_base, n); - } + if (!fix && !fallback_aper_force) return; - } if (!fallback_aper_force) aper_alloc = search_agp_bridge(&aper_order, &valid_agp); diff --git a/trunk/arch/x86_64/kernel/apic.c b/trunk/arch/x86_64/kernel/apic.c index 135ff25e6b44..2b8cef037a65 100644 --- a/trunk/arch/x86_64/kernel/apic.c +++ b/trunk/arch/x86_64/kernel/apic.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -37,20 +36,13 @@ #include #include #include -#include -int apic_mapped; int apic_verbosity; int apic_runs_main_timer; int apic_calibrate_pmtmr __initdata; int disable_apic_timer __initdata; -static struct resource lapic_resource = { - .name = "Local APIC", - .flags = IORESOURCE_MEM | IORESOURCE_BUSY, -}; - /* * cpu_mask that denotes the CPUs that needs timer interrupt coming in as * IPIs in place of local APIC timers @@ -144,40 +136,72 @@ void clear_local_APIC(void) apic_read(APIC_ESR); } -void disconnect_bsp_APIC(int virt_wire_setup) +void __init connect_bsp_APIC(void) { - /* Go back to Virtual Wire compatibility mode */ - unsigned long value; - - /* For the spurious interrupt use vector F, and enable it */ - value = apic_read(APIC_SPIV); - value &= ~APIC_VECTOR_MASK; - value |= APIC_SPIV_APIC_ENABLED; - value |= 0xf; - apic_write(APIC_SPIV, value); + if (pic_mode) { + /* + * Do not trust the local APIC being empty at bootup. + */ + clear_local_APIC(); + /* + * PIC mode, enable APIC mode in the IMCR, i.e. + * connect BSP's local APIC to INT and NMI lines. + */ + apic_printk(APIC_VERBOSE, "leaving PIC mode, enabling APIC mode.\n"); + outb(0x70, 0x22); + outb(0x01, 0x23); + } +} - if (!virt_wire_setup) { - /* For LVT0 make it edge triggered, active high, external and enabled */ - value = apic_read(APIC_LVT0); - value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | - APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | - APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); - value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; - value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); - apic_write(APIC_LVT0, value); - } else { - /* Disable LVT0 */ - apic_write(APIC_LVT0, APIC_LVT_MASKED); +void disconnect_bsp_APIC(int virt_wire_setup) +{ + if (pic_mode) { + /* + * Put the board back into PIC mode (has an effect + * only on certain older boards). Note that APIC + * interrupts, including IPIs, won't work beyond + * this point! The only exception are INIT IPIs. + */ + apic_printk(APIC_QUIET, "disabling APIC mode, entering PIC mode.\n"); + outb(0x70, 0x22); + outb(0x00, 0x23); } + else { + /* Go back to Virtual Wire compatibility mode */ + unsigned long value; + + /* For the spurious interrupt use vector F, and enable it */ + value = apic_read(APIC_SPIV); + value &= ~APIC_VECTOR_MASK; + value |= APIC_SPIV_APIC_ENABLED; + value |= 0xf; + apic_write(APIC_SPIV, value); + + if (!virt_wire_setup) { + /* For LVT0 make it edge triggered, active high, external and enabled */ + value = apic_read(APIC_LVT0); + value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | + APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | + APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); + apic_write(APIC_LVT0, value); + } + else { + /* Disable LVT0 */ + apic_write(APIC_LVT0, APIC_LVT_MASKED); + } - /* For LVT1 make it edge triggered, active high, nmi and enabled */ - value = apic_read(APIC_LVT1); - value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | + /* For LVT1 make it edge triggered, active high, nmi and enabled */ + value = apic_read(APIC_LVT1); + value &= ~( + APIC_MODE_MASK | APIC_SEND_PENDING | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); - value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; - value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); - apic_write(APIC_LVT1, value); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); + apic_write(APIC_LVT1, value); + } } void disable_local_APIC(void) @@ -273,6 +297,8 @@ void __init sync_Arb_IDs(void) | APIC_DM_INIT); } +extern void __error_in_apic_c (void); + /* * An initial setup of the virtual wire mode. */ @@ -319,7 +345,8 @@ void __cpuinit setup_local_APIC (void) value = apic_read(APIC_LVR); - BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f); + if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f) + __error_in_apic_c(); /* * Double-check whether this APIC is really registered. @@ -372,8 +399,32 @@ void __cpuinit setup_local_APIC (void) */ value |= APIC_SPIV_APIC_ENABLED; - /* We always use processor focus */ - + /* + * Some unknown Intel IO/APIC (or APIC) errata is biting us with + * certain networking cards. If high frequency interrupts are + * happening on a particular IOAPIC pin, plus the IOAPIC routing + * entry is masked/unmasked at a high rate as well then sooner or + * later IOAPIC line gets 'stuck', no more interrupts are received + * from the device. If focus CPU is disabled then the hang goes + * away, oh well :-( + * + * [ This bug can be reproduced easily with a level-triggered + * PCI Ne2000 networking cards and PII/PIII processors, dual + * BX chipset. ] + */ + /* + * Actually disabling the focus CPU check just makes the hang less + * frequent as it makes the interrupt distributon model be more + * like LRU than MRU (the short-term load is more even across CPUs). + * See also the comment in end_level_ioapic_irq(). --macro + */ +#if 1 + /* Enable focus processor (bit==0) */ + value &= ~APIC_SPIV_FOCUS_DISABLED; +#else + /* Disable focus processor (bit==1) */ + value |= APIC_SPIV_FOCUS_DISABLED; +#endif /* * Set spurious IRQ vector */ @@ -391,7 +442,7 @@ void __cpuinit setup_local_APIC (void) * TODO: set up through-local-APIC from through-I/O-APIC? --macro */ value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; - if (!smp_processor_id() && !value) { + if (!smp_processor_id() && (pic_mode || !value)) { value = APIC_DM_EXTINT; apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", smp_processor_id()); } else { @@ -428,7 +479,8 @@ void __cpuinit setup_local_APIC (void) } nmi_watchdog_default(); - setup_apic_nmi_watchdog(NULL); + if (nmi_watchdog == NMI_LOCAL_APIC) + setup_apic_nmi_watchdog(); apic_pm_activate(); } @@ -475,7 +527,8 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state) apic_pm_state.apic_tmict = apic_read(APIC_TMICT); apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); - local_irq_save(flags); + local_save_flags(flags); + local_irq_disable(); disable_local_APIC(); local_irq_restore(flags); return 0; @@ -553,24 +606,18 @@ static void apic_pm_activate(void) { } static int __init apic_set_verbosity(char *str) { - if (str == NULL) { - skip_ioapic_setup = 0; - ioapic_force = 1; - return 0; - } if (strcmp("debug", str) == 0) apic_verbosity = APIC_DEBUG; else if (strcmp("verbose", str) == 0) apic_verbosity = APIC_VERBOSE; - else { + else printk(KERN_WARNING "APIC Verbosity level %s not recognised" - " use apic=verbose or apic=debug\n", str); - return -EINVAL; - } + " use apic=verbose or apic=debug", str); - return 0; + return 1; } -early_param("apic", apic_set_verbosity); + +__setup("apic=", apic_set_verbosity); /* * Detect and enable local APICs on non-SMP boards. @@ -591,40 +638,6 @@ static int __init detect_init_APIC (void) return 0; } -#ifdef CONFIG_X86_IO_APIC -static struct resource * __init ioapic_setup_resources(void) -{ -#define IOAPIC_RESOURCE_NAME_SIZE 11 - unsigned long n; - struct resource *res; - char *mem; - int i; - - if (nr_ioapics <= 0) - return NULL; - - n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource); - n *= nr_ioapics; - - res = alloc_bootmem(n); - - if (!res) - return NULL; - - memset(res, 0, n); - mem = (void *)&res[nr_ioapics]; - - for (i = 0; i < nr_ioapics; i++) { - res[i].name = mem; - res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; - snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i); - mem += IOAPIC_RESOURCE_NAME_SIZE; - } - - return res; -} -#endif - void __init init_apic_mappings(void) { unsigned long apic_phys; @@ -641,26 +654,19 @@ void __init init_apic_mappings(void) apic_phys = mp_lapic_addr; set_fixmap_nocache(FIX_APIC_BASE, apic_phys); - apic_mapped = 1; apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); - /* Put local APIC into the resource map. */ - lapic_resource.start = apic_phys; - lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1; - insert_resource(&iomem_resource, &lapic_resource); - /* * Fetch the APIC ID of the BSP in case we have a * default configuration (or the MP table is broken). */ boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID)); +#ifdef CONFIG_X86_IO_APIC { unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; int i; - struct resource *ioapic_res; - ioapic_res = ioapic_setup_resources(); for (i = 0; i < nr_ioapics; i++) { if (smp_found_config) { ioapic_phys = mp_ioapics[i].mpc_apicaddr; @@ -672,15 +678,9 @@ void __init init_apic_mappings(void) apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", __fix_to_virt(idx), ioapic_phys); idx++; - - if (ioapic_res) { - ioapic_res->start = ioapic_phys; - ioapic_res->end = ioapic_phys + (4 * 1024) - 1; - insert_resource(&iomem_resource, ioapic_res); - ioapic_res++; - } } } +#endif } /* @@ -951,7 +951,7 @@ void smp_local_timer_interrupt(struct pt_regs *regs) * We take the 'long' return path, and there every subsystem * grabs the appropriate locks (kernel lock/ irq lock). * - * We might want to decouple profiling from the 'long path', + * we might want to decouple profiling from the 'long path', * and do the profiling totally in assembly. * * Currently this isn't too much of an issue (performance wise), @@ -1123,15 +1123,19 @@ int __init APIC_init_uniprocessor (void) verify_local_APIC(); + connect_bsp_APIC(); + phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id); apic_write(APIC_ID, SET_APIC_ID(boot_cpu_id)); setup_local_APIC(); +#ifdef CONFIG_X86_IO_APIC if (smp_found_config && !skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); + setup_IO_APIC(); else nr_ioapics = 0; +#endif setup_boot_APIC_clock(); check_nmi_watchdog(); return 0; @@ -1140,17 +1144,14 @@ int __init APIC_init_uniprocessor (void) static __init int setup_disableapic(char *str) { disable_apic = 1; - clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); - return 0; -} -early_param("disableapic", setup_disableapic); + return 1; +} -/* same as disableapic, for compatibility */ static __init int setup_nolapic(char *str) { - return setup_disableapic(str); + disable_apic = 1; + return 1; } -early_param("nolapic", setup_nolapic); static __init int setup_noapictimer(char *str) { @@ -1183,5 +1184,11 @@ static __init int setup_apicpmtimer(char *s) } __setup("apicpmtimer", setup_apicpmtimer); +/* dummy parsing: see setup.c */ + +__setup("disableapic", setup_disableapic); +__setup("nolapic", setup_nolapic); /* same as disableapic, for compatibility */ + __setup("noapictimer", setup_noapictimer); +/* no "lapic" flag - we only use the lapic when the BIOS tells us so. */ diff --git a/trunk/arch/x86_64/kernel/crash.c b/trunk/arch/x86_64/kernel/crash.c index 3525f884af82..d8d5750d6106 100644 --- a/trunk/arch/x86_64/kernel/crash.c +++ b/trunk/arch/x86_64/kernel/crash.c @@ -23,7 +23,6 @@ #include #include #include -#include /* This keeps a track of which one is crashing cpu. */ static int crashing_cpu; @@ -69,7 +68,7 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) * for the data I pass, and I need tags * on the data to indicate what information I have * squirrelled away. ELF notes happen to provide - * all of that, no need to invent something new. + * all of that that no need to invent something new. */ buf = (u32*)per_cpu_ptr(crash_notes, cpu); @@ -96,25 +95,15 @@ static void crash_save_self(struct pt_regs *regs) #ifdef CONFIG_SMP static atomic_t waiting_for_crash_ipi; -static int crash_nmi_callback(struct notifier_block *self, - unsigned long val, void *data) +static int crash_nmi_callback(struct pt_regs *regs, int cpu) { - struct pt_regs *regs; - int cpu; - - if (val != DIE_NMI_IPI) - return NOTIFY_OK; - - regs = ((struct die_args *)data)->regs; - cpu = raw_smp_processor_id(); - /* * Don't do anything if this handler is invoked on crashing cpu. * Otherwise, system will completely hang. Crashing cpu can get * an NMI if system was initially booted with nmi_watchdog parameter. */ if (cpu == crashing_cpu) - return NOTIFY_STOP; + return 1; local_irq_disable(); crash_save_this_cpu(regs, cpu); @@ -138,17 +127,12 @@ static void smp_send_nmi_allbutself(void) * cpu hotplug shouldn't matter. */ -static struct notifier_block crash_nmi_nb = { - .notifier_call = crash_nmi_callback, -}; - static void nmi_shootdown_cpus(void) { unsigned long msecs; atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); - if (register_die_notifier(&crash_nmi_nb)) - return; /* return what? */ + set_nmi_callback(crash_nmi_callback); /* * Ensure the new callback function is set before sending @@ -194,7 +178,9 @@ void machine_crash_shutdown(struct pt_regs *regs) if(cpu_has_apic) disable_local_APIC(); +#if defined(CONFIG_X86_IO_APIC) disable_IO_APIC(); +#endif crash_save_self(regs); } diff --git a/trunk/arch/x86_64/kernel/e820.c b/trunk/arch/x86_64/kernel/e820.c index c0af3828df45..708a3cd9a27e 100644 --- a/trunk/arch/x86_64/kernel/e820.c +++ b/trunk/arch/x86_64/kernel/e820.c @@ -25,8 +25,6 @@ #include #include -struct e820map e820 __initdata; - /* * PFN of last memory page. */ @@ -43,7 +41,7 @@ unsigned long end_pfn_map; /* * Last pfn which the user wants to use. */ -static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT; +unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT; extern struct resource code_resource, data_resource; @@ -72,7 +70,12 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) return 1; } #endif - /* kernel code */ + /* kernel code + 640k memory hole (later should not be needed, but + be paranoid for now) */ + if (last >= 640*1024 && addr < 1024*1024) { + *addrp = 1024*1024; + return 1; + } if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) { *addrp = __pa_symbol(&_end); return 1; @@ -562,6 +565,13 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) * If we're lucky and live on a modern system, the setup code * will have given us a memory map that we can use to properly * set up memory. If we aren't, we'll fake a memory map. + * + * We check to see that the memory map contains at least 2 elements + * before we'll use it, because the detection code in setup.S may + * not be perfect and most every PC known to man has two memory + * regions: one from 0 to 640k, and one from 1mb up. (The IBM + * thinkpad 560x, for example, does not cooperate with the memory + * detection code.) */ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) { @@ -579,19 +589,34 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) if (start > end) return -1; + /* + * Some BIOSes claim RAM in the 640k - 1M region. + * Not right. Fix it up. + * + * This should be removed on Hammer which is supposed to not + * have non e820 covered ISA mappings there, but I had some strange + * problems so it stays for now. -AK + */ + if (type == E820_RAM) { + if (start < 0x100000ULL && end > 0xA0000ULL) { + if (start < 0xA0000ULL) + add_memory_region(start, 0xA0000ULL-start, type); + if (end <= 0x100000ULL) + continue; + start = 0x100000ULL; + size = end - start; + } + } + add_memory_region(start, size, type); } while (biosmap++,--nr_map); return 0; } -void early_panic(char *msg) -{ - early_printk(msg); - panic(msg); -} - void __init setup_memory_region(void) { + char *who = "BIOS-e820"; + /* * Try to copy the BIOS-supplied E820-map. * @@ -599,70 +624,51 @@ void __init setup_memory_region(void) * the next section from 1mb->appropriate_mem_k */ sanitize_e820_map(E820_MAP, &E820_MAP_NR); - if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) - early_panic("Cannot find a valid memory map"); + if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { + unsigned long mem_size; + + /* compare results from other methods and take the greater */ + if (ALT_MEM_K < EXT_MEM_K) { + mem_size = EXT_MEM_K; + who = "BIOS-88"; + } else { + mem_size = ALT_MEM_K; + who = "BIOS-e801"; + } + + e820.nr_map = 0; + add_memory_region(0, LOWMEMSIZE(), E820_RAM); + add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); + } printk(KERN_INFO "BIOS-provided physical RAM map:\n"); - e820_print_map("BIOS-e820"); + e820_print_map(who); } -static int __init parse_memopt(char *p) -{ - if (!p) - return -EINVAL; - end_user_pfn = memparse(p, &p); +void __init parse_memopt(char *p, char **from) +{ + end_user_pfn = memparse(p, from); end_user_pfn >>= PAGE_SHIFT; - return 0; } -early_param("mem", parse_memopt); -static int userdef __initdata; - -static int __init parse_memmap_opt(char *p) +void __init parse_memmapopt(char *p, char **from) { - char *oldp; unsigned long long start_at, mem_size; - if (!strcmp(p, "exactmap")) { -#ifdef CONFIG_CRASH_DUMP - /* If we are doing a crash dump, we - * still need to know the real mem - * size before original memory map is - * reset. - */ - saved_max_pfn = e820_end_of_ram(); -#endif - end_pfn_map = 0; - e820.nr_map = 0; - userdef = 1; - return 0; - } - - oldp = p; - mem_size = memparse(p, &p); - if (p == oldp) - return -EINVAL; + mem_size = memparse(p, from); + p = *from; if (*p == '@') { - start_at = memparse(p+1, &p); + start_at = memparse(p+1, from); add_memory_region(start_at, mem_size, E820_RAM); } else if (*p == '#') { - start_at = memparse(p+1, &p); + start_at = memparse(p+1, from); add_memory_region(start_at, mem_size, E820_ACPI); } else if (*p == '$') { - start_at = memparse(p+1, &p); + start_at = memparse(p+1, from); add_memory_region(start_at, mem_size, E820_RESERVED); } else { end_user_pfn = (mem_size >> PAGE_SHIFT); } - return *p == '\0' ? 0 : -EINVAL; -} -early_param("memmap", parse_memmap_opt); - -void finish_e820_parsing(void) -{ - if (userdef) { - printk(KERN_INFO "user-defined physical RAM map:\n"); - e820_print_map("user"); - } + p = *from; } unsigned long pci_mem_start = 0xaeedbabe; diff --git a/trunk/arch/x86_64/kernel/early-quirks.c b/trunk/arch/x86_64/kernel/early-quirks.c deleted file mode 100644 index 208e38a372c1..000000000000 --- a/trunk/arch/x86_64/kernel/early-quirks.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Various workarounds for chipset bugs. - This code runs very early and can't use the regular PCI subsystem - The entries are keyed to PCI bridges which usually identify chipsets - uniquely. - This is only for whole classes of chipsets with specific problems which - need early invasive action (e.g. before the timers are initialized). - Most PCI device specific workarounds can be done later and should be - in standard PCI quirks - Mainboard specific bugs should be handled by DMI entries. - CPU specific bugs in setup.c */ - -#include -#include -#include -#include -#include -#include - -static void via_bugs(void) -{ -#ifdef CONFIG_IOMMU - if ((end_pfn > MAX_DMA32_PFN || force_iommu) && - !iommu_aperture_allowed) { - printk(KERN_INFO - "Looks like a VIA chipset. Disabling IOMMU. Override with iommu=allowed\n"); - iommu_aperture_disabled = 1; - } -#endif -} - -#ifdef CONFIG_ACPI - -static int nvidia_hpet_detected __initdata; - -static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) -{ - nvidia_hpet_detected = 1; - return 0; -} -#endif - -static void nvidia_bugs(void) -{ -#ifdef CONFIG_ACPI - /* - * All timer overrides on Nvidia are - * wrong unless HPET is enabled. - */ - nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_HPET, nvidia_hpet_check); - if (nvidia_hpet_detected == 0) { - acpi_skip_timer_override = 1; - printk(KERN_INFO "Nvidia board " - "detected. Ignoring ACPI " - "timer override.\n"); - } -#endif - /* RED-PEN skip them on mptables too? */ - -} - -static void ati_bugs(void) -{ -#if 1 /* for testing */ - printk("ATI board detected\n"); -#endif - /* No bugs right now */ -} - -struct chipset { - u16 vendor; - void (*f)(void); -}; - -static struct chipset early_qrk[] = { - { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, - { PCI_VENDOR_ID_VIA, via_bugs }, - { PCI_VENDOR_ID_ATI, ati_bugs }, - {} -}; - -void __init early_quirks(void) -{ - int num, slot, func; - - if (!early_pci_allowed()) - return; - - /* Poor man's PCI discovery */ - for (num = 0; num < 32; num++) { - for (slot = 0; slot < 32; slot++) { - for (func = 0; func < 8; func++) { - u32 class; - u32 vendor; - u8 type; - int i; - class = read_pci_config(num,slot,func, - PCI_CLASS_REVISION); - if (class == 0xffffffff) - break; - - if ((class >> 16) != PCI_CLASS_BRIDGE_PCI) - continue; - - vendor = read_pci_config(num, slot, func, - PCI_VENDOR_ID); - vendor &= 0xffff; - - for (i = 0; early_qrk[i].f; i++) - if (early_qrk[i].vendor == vendor) { - early_qrk[i].f(); - return; - } - - type = read_pci_config_byte(num, slot, func, - PCI_HEADER_TYPE); - if (!(type & 0x80)) - break; - } - } - } -} diff --git a/trunk/arch/x86_64/kernel/early_printk.c b/trunk/arch/x86_64/kernel/early_printk.c index e22ecd54870d..140051e07fa6 100644 --- a/trunk/arch/x86_64/kernel/early_printk.c +++ b/trunk/arch/x86_64/kernel/early_printk.c @@ -215,16 +215,20 @@ void early_printk(const char *fmt, ...) static int __initdata keep_early; -static int __init setup_early_printk(char *buf) +int __init setup_early_printk(char *opt) { - if (!buf) - return 0; + char *space; + char buf[256]; if (early_console_initialized) - return 0; - early_console_initialized = 1; + return 1; + + strlcpy(buf,opt,sizeof(buf)); + space = strchr(buf, ' '); + if (space) + *space = 0; - if (!strcmp(buf,"keep")) + if (strstr(buf,"keep")) keep_early = 1; if (!strncmp(buf, "serial", 6)) { @@ -244,12 +248,11 @@ static int __init setup_early_printk(char *buf) early_console = &simnow_console; keep_early = 1; } + early_console_initialized = 1; register_console(early_console); return 0; } -early_param("earlyprintk", setup_early_printk); - void __init disable_early_printk(void) { if (!early_console_initialized || !early_console) @@ -263,3 +266,4 @@ void __init disable_early_printk(void) } } +__setup("earlyprintk=", setup_early_printk); diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index 2802524104f3..aa8d8939abc1 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -4,6 +4,8 @@ * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs * Copyright (C) 2000 Pavel Machek + * + * $Id$ */ /* @@ -20,25 +22,15 @@ * at the top of the kernel process stack. * - partial stack frame: partially saved registers upto R11. * - full stack frame: Like partial stack frame, but all register saved. - * - * Some macro usage: - * - CFI macros are used to generate dwarf2 unwind information for better - * backtraces. They don't change any code. - * - SAVE_ALL/RESTORE_ALL - Save/restore all registers - * - SAVE_ARGS/RESTORE_ARGS - Save/restore registers that C functions modify. - * There are unfortunately lots of special cases where some registers - * not touched. The macro is a big mess that should be cleaned up. - * - SAVE_REST/RESTORE_REST - Handle the registers not saved by SAVE_ARGS. - * Gives a full stack frame. - * - ENTRY/END Define functions in the symbol table. - * - FIXUP_TOP_OF_STACK/RESTORE_TOP_OF_STACK - Fix up the hardware stack - * frame that is otherwise undefined after a SYSCALL - * - TRACE_IRQ_* - Trace hard interrupt state for lock debugging. - * - errorentry/paranoidentry/zeroentry - Define exception entry points. + * + * TODO: + * - schedule it carefully for the final hardware. */ +#define ASSEMBLY 1 #include #include +#include #include #include #include @@ -123,7 +115,6 @@ .macro CFI_DEFAULT_STACK start=1 .if \start CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8 .else CFI_DEF_CFA_OFFSET SS+8 @@ -155,10 +146,6 @@ /* rdi: prev */ ENTRY(ret_from_fork) CFI_DEFAULT_STACK - push kernel_eflags(%rip) - CFI_ADJUST_CFA_OFFSET 4 - popf # reset kernel eflags - CFI_ADJUST_CFA_OFFSET -4 call schedule_tail GET_THREAD_INFO(%rcx) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx) @@ -212,7 +199,6 @@ END(ret_from_fork) ENTRY(system_call) CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,PDA_STACKOFFSET CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ @@ -330,7 +316,6 @@ END(system_call) */ ENTRY(int_ret_from_sys_call) CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8-ARGOFFSET /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/ CFI_REL_OFFSET rsp,RSP-ARGOFFSET @@ -491,7 +476,6 @@ END(stub_rt_sigreturn) */ .macro _frame ref CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8-\ref /*CFI_REL_OFFSET ss,SS-\ref*/ CFI_REL_OFFSET rsp,RSP-\ref @@ -527,12 +511,7 @@ END(stub_rt_sigreturn) testl $3,CS(%rdi) je 1f swapgs - /* irqcount is used to check if a CPU is already on an interrupt - stack or not. While this is essentially redundant with preempt_count - it is a little cheaper to use a separate counter in the PDA - (short of moving irq_enter into assembly, which would be too - much work) */ -1: incl %gs:pda_irqcount +1: incl %gs:pda_irqcount # RED-PEN should check preempt count cmoveq %gs:pda_irqstackptr,%rsp push %rbp # backlink for old unwinder /* @@ -640,7 +619,8 @@ retint_signal: #ifdef CONFIG_PREEMPT /* Returning to kernel space. Check if we need preemption */ /* rcx: threadinfo. interrupts off. */ -ENTRY(retint_kernel) + .p2align +retint_kernel: cmpl $0,threadinfo_preempt_count(%rcx) jnz retint_restore_args bt $TIF_NEED_RESCHED,threadinfo_flags(%rcx) @@ -699,6 +679,7 @@ ENTRY(call_function_interrupt) END(call_function_interrupt) #endif +#ifdef CONFIG_X86_LOCAL_APIC ENTRY(apic_timer_interrupt) apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt END(apic_timer_interrupt) @@ -710,6 +691,7 @@ END(error_interrupt) ENTRY(spurious_interrupt) apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt END(spurious_interrupt) +#endif /* * Exception entry points. @@ -786,9 +768,7 @@ paranoid_exit\trace: testl $3,CS(%rsp) jnz paranoid_userspace\trace paranoid_swapgs\trace: - .if \trace TRACE_IRQS_IRETQ 0 - .endif swapgs paranoid_restore\trace: RESTORE_ALL 8 @@ -834,7 +814,7 @@ paranoid_schedule\trace: * Exception entry point. This expects an error code/orig_rax on the stack * and the exception handler in %rax. */ -KPROBE_ENTRY(error_entry) +ENTRY(error_entry) _frame RDI /* rdi slot contains rax, oldrax contains error code */ cld @@ -918,7 +898,7 @@ error_kernelspace: cmpq $gs_change,RIP(%rsp) je error_swapgs jmp error_sti -KPROBE_END(error_entry) +END(error_entry) /* Reload gs selector with exception handling */ /* edi: new selector */ @@ -1040,7 +1020,8 @@ ENDPROC(execve) KPROBE_ENTRY(page_fault) errorentry do_page_fault -KPROBE_END(page_fault) +END(page_fault) + .previous .text ENTRY(coprocessor_error) zeroentry do_coprocessor_error @@ -1061,7 +1042,8 @@ KPROBE_ENTRY(debug) CFI_ADJUST_CFA_OFFSET 8 paranoidentry do_debug, DEBUG_STACK paranoidexit -KPROBE_END(debug) +END(debug) + .previous .text /* runs on exception stack */ KPROBE_ENTRY(nmi) @@ -1075,7 +1057,8 @@ KPROBE_ENTRY(nmi) jmp paranoid_exit1 CFI_ENDPROC #endif -KPROBE_END(nmi) +END(nmi) + .previous .text KPROBE_ENTRY(int3) INTR_FRAME @@ -1084,7 +1067,8 @@ KPROBE_ENTRY(int3) paranoidentry do_int3, DEBUG_STACK jmp paranoid_exit1 CFI_ENDPROC -KPROBE_END(int3) +END(int3) + .previous .text ENTRY(overflow) zeroentry do_overflow @@ -1132,7 +1116,8 @@ END(stack_segment) KPROBE_ENTRY(general_protection) errorentry do_general_protection -KPROBE_END(general_protection) +END(general_protection) + .previous .text ENTRY(alignment_check) errorentry do_alignment_check diff --git a/trunk/arch/x86_64/kernel/genapic_cluster.c b/trunk/arch/x86_64/kernel/genapic_cluster.c index cdb90e671b88..3020917546de 100644 --- a/trunk/arch/x86_64/kernel/genapic_cluster.c +++ b/trunk/arch/x86_64/kernel/genapic_cluster.c @@ -118,6 +118,7 @@ struct genapic apic_cluster = { .name = "clustered", .int_delivery_mode = dest_Fixed, .int_dest_mode = (APIC_DEST_PHYSICAL != 0), + .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_FIXED, .target_cpus = cluster_target_cpus, .apic_id_registered = cluster_apic_id_registered, .init_apic_ldr = cluster_init_apic_ldr, diff --git a/trunk/arch/x86_64/kernel/genapic_flat.c b/trunk/arch/x86_64/kernel/genapic_flat.c index 50ad153eaac4..eb86d374813a 100644 --- a/trunk/arch/x86_64/kernel/genapic_flat.c +++ b/trunk/arch/x86_64/kernel/genapic_flat.c @@ -49,7 +49,8 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector) unsigned long cfg; unsigned long flags; - local_irq_save(flags); + local_save_flags(flags); + local_irq_disable(); /* * Wait for idle. @@ -120,6 +121,7 @@ struct genapic apic_flat = { .name = "flat", .int_delivery_mode = dest_LowestPrio, .int_dest_mode = (APIC_DEST_LOGICAL != 0), + .int_delivery_dest = APIC_DEST_LOGICAL | APIC_DM_LOWEST, .target_cpus = flat_target_cpus, .apic_id_registered = flat_apic_id_registered, .init_apic_ldr = flat_init_apic_ldr, @@ -178,6 +180,7 @@ struct genapic apic_physflat = { .name = "physical flat", .int_delivery_mode = dest_Fixed, .int_dest_mode = (APIC_DEST_PHYSICAL != 0), + .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_FIXED, .target_cpus = physflat_target_cpus, .apic_id_registered = flat_apic_id_registered, .init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/ diff --git a/trunk/arch/x86_64/kernel/head.S b/trunk/arch/x86_64/kernel/head.S index 1e6f80870679..c9739ca81d06 100644 --- a/trunk/arch/x86_64/kernel/head.S +++ b/trunk/arch/x86_64/kernel/head.S @@ -5,6 +5,8 @@ * Copyright (C) 2000 Pavel Machek * Copyright (C) 2000 Karsten Keil * Copyright (C) 2001,2002 Andi Kleen + * + * $Id: head.S,v 1.49 2002/03/19 17:39:25 ak Exp $ */ @@ -185,15 +187,12 @@ startup_64: /* Finally jump to run C code and to be on real kernel address * Since we are running on identity-mapped space we have to jump - * to the full 64bit address, this is only possible as indirect - * jump. In addition we need to ensure %cs is set so we make this - * a far return. + * to the full 64bit address , this is only possible as indirect + * jump */ movq initial_code(%rip),%rax - pushq $0 # fake return address to stop unwinder - pushq $__KERNEL_CS # set correct cs - pushq %rax # target address in negative space - lretq + pushq $0 # fake return address + jmp *%rax /* SMP bootup changes these two */ .align 8 @@ -372,7 +371,7 @@ ENTRY(cpu_gdt_table) .quad 0,0 /* TSS */ .quad 0,0 /* LDT */ .quad 0,0,0 /* three TLS descriptors */ - .quad 0x0000f40000000000 /* node/CPU stored in limit */ + .quad 0 /* unused */ gdt_end: /* asm/segment.h:GDT_ENTRIES must match this */ /* This should be a multiple of the cache line size */ diff --git a/trunk/arch/x86_64/kernel/head64.c b/trunk/arch/x86_64/kernel/head64.c index 9561eb3c5b5c..36647ce6aecb 100644 --- a/trunk/arch/x86_64/kernel/head64.c +++ b/trunk/arch/x86_64/kernel/head64.c @@ -45,16 +45,38 @@ static void __init copy_bootdata(char *real_mode_data) new_data = *(int *) (x86_boot_params + NEW_CL_POINTER); if (!new_data) { if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) { + printk("so old bootloader that it does not support commandline?!\n"); return; } new_data = OLD_CL_BASE_ADDR + * (u16 *) OLD_CL_OFFSET; + printk("old bootloader convention, maybe loadlin?\n"); } command_line = (char *) ((u64)(new_data)); memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); + printk("Bootdata ok (command line is %s)\n", saved_command_line); +} + +static void __init setup_boot_cpu_data(void) +{ + unsigned int dummy, eax; + + /* get vendor info */ + cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level, + (unsigned int *)&boot_cpu_data.x86_vendor_id[0], + (unsigned int *)&boot_cpu_data.x86_vendor_id[8], + (unsigned int *)&boot_cpu_data.x86_vendor_id[4]); + + /* get cpu type */ + cpuid(1, &eax, &dummy, &dummy, + (unsigned int *) &boot_cpu_data.x86_capability); + boot_cpu_data.x86 = (eax >> 8) & 0xf; + boot_cpu_data.x86_model = (eax >> 4) & 0xf; + boot_cpu_data.x86_mask = eax & 0xf; } void __init x86_64_start_kernel(char * real_mode_data) { + char *s; int i; for (i = 0; i < 256; i++) @@ -62,7 +84,10 @@ void __init x86_64_start_kernel(char * real_mode_data) asm volatile("lidt %0" :: "m" (idt_descr)); clear_bss(); - early_printk("Kernel alive\n"); + /* + * This must be called really, really early: + */ + lockdep_init(); /* * switch to init_level4_pgt from boot_level4_pgt @@ -78,5 +103,22 @@ void __init x86_64_start_kernel(char * real_mode_data) #ifdef CONFIG_SMP cpu_set(0, cpu_online_map); #endif + s = strstr(saved_command_line, "earlyprintk="); + if (s != NULL) + setup_early_printk(strchr(s, '=') + 1); +#ifdef CONFIG_NUMA + s = strstr(saved_command_line, "numa="); + if (s != NULL) + numa_setup(s+5); +#endif +#ifdef CONFIG_X86_IO_APIC + if (strstr(saved_command_line, "disableapic")) + disable_apic = 1; +#endif + /* You need early console to see that */ + if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE) + panic("Kernel too big for kernel mapping\n"); + + setup_boot_cpu_data(); start_kernel(); } diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c index 2dd51f364ea2..0434b1f8e3dd 100644 --- a/trunk/arch/x86_64/kernel/i8259.c +++ b/trunk/arch/x86_64/kernel/i8259.c @@ -55,6 +55,7 @@ */ BUILD_16_IRQS(0x0) +#ifdef CONFIG_X86_LOCAL_APIC /* * The IO-APIC gives us many more interrupt sources. Most of these * are unused but an SMP system is supposed to have enough memory ... @@ -74,6 +75,8 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_15_IRQS(0xe) #endif +#endif + #undef BUILD_16_IRQS #undef BUILD_15_IRQS #undef BI @@ -97,6 +100,7 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x0), +#ifdef CONFIG_X86_IO_APIC IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3), IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), @@ -106,6 +110,7 @@ void (*interrupt[NR_IRQS])(void) = { , IRQLIST_15(0xe) #endif +#endif }; #undef IRQ @@ -123,8 +128,6 @@ void (*interrupt[NR_IRQS])(void) = { DEFINE_SPINLOCK(i8259A_lock); -static int i8259A_auto_eoi; - static void end_8259A_irq (unsigned int irq) { if (irq > 256) { @@ -338,8 +341,6 @@ void init_8259A(int auto_eoi) { unsigned long flags; - i8259A_auto_eoi = auto_eoi; - spin_lock_irqsave(&i8259A_lock, flags); outb(0xff, 0x21); /* mask all of 8259A-1 */ @@ -398,7 +399,7 @@ static void save_ELCR(char *trigger) static int i8259A_resume(struct sys_device *dev) { - init_8259A(i8259A_auto_eoi); + init_8259A(0); restore_ELCR(irq_trigger); return 0; } @@ -452,7 +453,9 @@ void __init init_ISA_irqs (void) { int i; +#ifdef CONFIG_X86_LOCAL_APIC init_bsp_APIC(); +#endif init_8259A(0); for (i = 0; i < NR_IRQS; i++) { @@ -578,12 +581,14 @@ void __init init_IRQ(void) set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); +#ifdef CONFIG_X86_LOCAL_APIC /* self generated IPI for local APIC timer */ set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); /* IPI vectors for APIC spurious and error interrupts */ set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); +#endif /* * Set the clock to HZ Hz, we already have a valid diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c index 0491019d4c8d..924a4a332954 100644 --- a/trunk/arch/x86_64/kernel/io_apic.c +++ b/trunk/arch/x86_64/kernel/io_apic.c @@ -48,7 +48,7 @@ int sis_apic_bug; /* not actually supported, dummy for compile */ static int no_timer_check; -static int disable_timer_pin_1 __initdata; +int disable_timer_pin_1 __initdata; int timer_over_8254 __initdata = 0; @@ -111,33 +111,6 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; FINAL; \ } -union entry_union { - struct { u32 w1, w2; }; - struct IO_APIC_route_entry entry; -}; - -static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) -{ - union entry_union eu; - unsigned long flags; - spin_lock_irqsave(&ioapic_lock, flags); - eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); - eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); - spin_unlock_irqrestore(&ioapic_lock, flags); - return eu.entry; -} - -static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) -{ - unsigned long flags; - union entry_union eu; - eu.entry = e; - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x10 + 2*pin, eu.w1); - io_apic_write(apic, 0x11 + 2*pin, eu.w2); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - #ifdef CONFIG_SMP static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) { @@ -223,9 +196,13 @@ static void unmask_IO_APIC_irq (unsigned int irq) static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) { struct IO_APIC_route_entry entry; + unsigned long flags; /* Check delivery_mode to be sure we're not clearing an SMI pin */ - entry = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); if (entry.delivery_mode == dest_SMI) return; /* @@ -233,7 +210,10 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) */ memset(&entry, 0, sizeof(entry)); entry.mask = 1; - ioapic_write_entry(apic, pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0)); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1)); + spin_unlock_irqrestore(&ioapic_lock, flags); } static void clear_IO_APIC (void) @@ -245,6 +225,14 @@ static void clear_IO_APIC (void) clear_IO_APIC_pin(apic, pin); } +/* + * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to + * specific CPU-side IRQs. + */ + +#define MAX_PIRQS 8 +static int pirq_entries [MAX_PIRQS]; +static int pirqs_enabled; int skip_ioapic_setup; int ioapic_force; @@ -253,17 +241,18 @@ int ioapic_force; static int __init disable_ioapic_setup(char *str) { skip_ioapic_setup = 1; - return 0; + return 1; } -early_param("noapic", disable_ioapic_setup); -/* Actually the next is obsolete, but keep it for paranoid reasons -AK */ -static int __init disable_timer_pin_setup(char *arg) +static int __init enable_ioapic_setup(char *str) { - disable_timer_pin_1 = 1; + ioapic_force = 1; + skip_ioapic_setup = 0; return 1; } -__setup("disable_timer_pin_1", disable_timer_pin_setup); + +__setup("noapic", disable_ioapic_setup); +__setup("apic", enable_ioapic_setup); static int __init setup_disable_8254_timer(char *s) { @@ -279,6 +268,135 @@ static int __init setup_enable_8254_timer(char *s) __setup("disable_8254_timer", setup_disable_8254_timer); __setup("enable_8254_timer", setup_enable_8254_timer); +#include +#include +#include + + +#ifdef CONFIG_ACPI + +static int nvidia_hpet_detected __initdata; + +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) +{ + nvidia_hpet_detected = 1; + return 0; +} +#endif + +/* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC + off. Check for an Nvidia or VIA PCI bridge and turn it off. + Use pci direct infrastructure because this runs before the PCI subsystem. + + Can be overwritten with "apic" + + And another hack to disable the IOMMU on VIA chipsets. + + ... and others. Really should move this somewhere else. + + Kludge-O-Rama. */ +void __init check_ioapic(void) +{ + int num,slot,func; + /* Poor man's PCI discovery */ + for (num = 0; num < 32; num++) { + for (slot = 0; slot < 32; slot++) { + for (func = 0; func < 8; func++) { + u32 class; + u32 vendor; + u8 type; + class = read_pci_config(num,slot,func, + PCI_CLASS_REVISION); + if (class == 0xffffffff) + break; + + if ((class >> 16) != PCI_CLASS_BRIDGE_PCI) + continue; + + vendor = read_pci_config(num, slot, func, + PCI_VENDOR_ID); + vendor &= 0xffff; + switch (vendor) { + case PCI_VENDOR_ID_VIA: +#ifdef CONFIG_IOMMU + if ((end_pfn > MAX_DMA32_PFN || + force_iommu) && + !iommu_aperture_allowed) { + printk(KERN_INFO + "Looks like a VIA chipset. Disabling IOMMU. Override with \"iommu=allowed\"\n"); + iommu_aperture_disabled = 1; + } +#endif + return; + case PCI_VENDOR_ID_NVIDIA: +#ifdef CONFIG_ACPI + /* + * All timer overrides on Nvidia are + * wrong unless HPET is enabled. + */ + nvidia_hpet_detected = 0; + acpi_table_parse(ACPI_HPET, + nvidia_hpet_check); + if (nvidia_hpet_detected == 0) { + acpi_skip_timer_override = 1; + printk(KERN_INFO "Nvidia board " + "detected. Ignoring ACPI " + "timer override.\n"); + } +#endif + /* RED-PEN skip them on mptables too? */ + return; + + /* This should be actually default, but + for 2.6.16 let's do it for ATI only where + it's really needed. */ + case PCI_VENDOR_ID_ATI: + if (timer_over_8254 == 1) { + timer_over_8254 = 0; + printk(KERN_INFO + "ATI board detected. Disabling timer routing over 8254.\n"); + } + return; + } + + + /* No multi-function device? */ + type = read_pci_config_byte(num,slot,func, + PCI_HEADER_TYPE); + if (!(type & 0x80)) + break; + } + } + } +} + +static int __init ioapic_pirq_setup(char *str) +{ + int i, max; + int ints[MAX_PIRQS+1]; + + get_options(str, ARRAY_SIZE(ints), ints); + + for (i = 0; i < MAX_PIRQS; i++) + pirq_entries[i] = -1; + + pirqs_enabled = 1; + apic_printk(APIC_VERBOSE, "PIRQ redirection, working around broken MP-BIOS.\n"); + max = MAX_PIRQS; + if (ints[0] < MAX_PIRQS) + max = ints[0]; + + for (i = 0; i < max; i++) { + apic_printk(APIC_VERBOSE, "... PIRQ%d -> IRQ %d\n", i, ints[i+1]); + /* + * PIRQs are mapped upside down, usually. + */ + pirq_entries[MAX_PIRQS-i-1] = ints[i+1]; + } + return 1; +} + +__setup("pirq=", ioapic_pirq_setup); /* * Find the IRQ entry number of a certain pin. @@ -307,7 +425,9 @@ static int __init find_isa_irq_pin(int irq, int type) for (i = 0; i < mp_irq_entries; i++) { int lbus = mp_irqs[i].mpc_srcbus; - if (test_bit(lbus, mp_bus_not_pci) && + if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || + mp_bus_id_to_type[lbus] == MP_BUS_EISA || + mp_bus_id_to_type[lbus] == MP_BUS_MCA) && (mp_irqs[i].mpc_irqtype == type) && (mp_irqs[i].mpc_srcbusirq == irq)) @@ -323,7 +443,9 @@ static int __init find_isa_irq_apic(int irq, int type) for (i = 0; i < mp_irq_entries; i++) { int lbus = mp_irqs[i].mpc_srcbus; - if (test_bit(lbus, mp_bus_not_pci) && + if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || + mp_bus_id_to_type[lbus] == MP_BUS_EISA || + mp_bus_id_to_type[lbus] == MP_BUS_MCA) && (mp_irqs[i].mpc_irqtype == type) && (mp_irqs[i].mpc_srcbusirq == irq)) break; @@ -363,7 +485,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) mp_irqs[i].mpc_dstapic == MP_APIC_ALL) break; - if (!test_bit(lbus, mp_bus_not_pci) && + if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) && !mp_irqs[i].mpc_irqtype && (bus == lbus) && (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) { @@ -386,6 +508,27 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) return best_guess; } +/* + * EISA Edge/Level control register, ELCR + */ +static int EISA_ELCR(unsigned int irq) +{ + if (irq < 16) { + unsigned int port = 0x4d0 + (irq >> 3); + return (inb(port) >> (irq & 7)) & 1; + } + apic_printk(APIC_VERBOSE, "Broken MPtable reports ISA irq %d\n", irq); + return 0; +} + +/* EISA interrupts are always polarity zero and can be edge or level + * trigger depending on the ELCR value. If an interrupt is listed as + * EISA conforming in the MP table, that means its trigger type must + * be read in from the ELCR */ + +#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq)) +#define default_EISA_polarity(idx) (0) + /* ISA interrupts are always polarity zero edge triggered, * when listed as conforming in the MP table. */ @@ -398,6 +541,12 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) #define default_PCI_trigger(idx) (1) #define default_PCI_polarity(idx) (1) +/* MCA interrupts are always polarity zero level triggered, + * when listed as conforming in the MP table. */ + +#define default_MCA_trigger(idx) (1) +#define default_MCA_polarity(idx) (0) + static int __init MPBIOS_polarity(int idx) { int bus = mp_irqs[idx].mpc_srcbus; @@ -409,11 +558,38 @@ static int __init MPBIOS_polarity(int idx) switch (mp_irqs[idx].mpc_irqflag & 3) { case 0: /* conforms, ie. bus-type dependent polarity */ - if (test_bit(bus, mp_bus_not_pci)) - polarity = default_ISA_polarity(idx); - else - polarity = default_PCI_polarity(idx); + { + switch (mp_bus_id_to_type[bus]) + { + case MP_BUS_ISA: /* ISA pin */ + { + polarity = default_ISA_polarity(idx); + break; + } + case MP_BUS_EISA: /* EISA pin */ + { + polarity = default_EISA_polarity(idx); + break; + } + case MP_BUS_PCI: /* PCI pin */ + { + polarity = default_PCI_polarity(idx); + break; + } + case MP_BUS_MCA: /* MCA pin */ + { + polarity = default_MCA_polarity(idx); + break; + } + default: + { + printk(KERN_WARNING "broken BIOS!!\n"); + polarity = 1; + break; + } + } break; + } case 1: /* high active */ { polarity = 0; @@ -451,11 +627,38 @@ static int MPBIOS_trigger(int idx) switch ((mp_irqs[idx].mpc_irqflag>>2) & 3) { case 0: /* conforms, ie. bus-type dependent */ - if (test_bit(bus, mp_bus_not_pci)) - trigger = default_ISA_trigger(idx); - else - trigger = default_PCI_trigger(idx); + { + switch (mp_bus_id_to_type[bus]) + { + case MP_BUS_ISA: /* ISA pin */ + { + trigger = default_ISA_trigger(idx); + break; + } + case MP_BUS_EISA: /* EISA pin */ + { + trigger = default_EISA_trigger(idx); + break; + } + case MP_BUS_PCI: /* PCI pin */ + { + trigger = default_PCI_trigger(idx); + break; + } + case MP_BUS_MCA: /* MCA pin */ + { + trigger = default_MCA_trigger(idx); + break; + } + default: + { + printk(KERN_WARNING "broken BIOS!!\n"); + trigger = 1; + break; + } + } break; + } case 1: /* edge */ { trigger = 0; @@ -561,17 +764,49 @@ static int pin_2_irq(int idx, int apic, int pin) if (mp_irqs[idx].mpc_dstirq != pin) printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); - if (test_bit(bus, mp_bus_not_pci)) { - irq = mp_irqs[idx].mpc_srcbusirq; - } else { - /* - * PCI IRQs are mapped in order - */ - i = irq = 0; - while (i < apic) - irq += nr_ioapic_registers[i++]; - irq += pin; - irq = gsi_irq_sharing(irq); + switch (mp_bus_id_to_type[bus]) + { + case MP_BUS_ISA: /* ISA pin */ + case MP_BUS_EISA: + case MP_BUS_MCA: + { + irq = mp_irqs[idx].mpc_srcbusirq; + break; + } + case MP_BUS_PCI: /* PCI pin */ + { + /* + * PCI IRQs are mapped in order + */ + i = irq = 0; + while (i < apic) + irq += nr_ioapic_registers[i++]; + irq += pin; + irq = gsi_irq_sharing(irq); + break; + } + default: + { + printk(KERN_ERR "unknown bus type %d.\n",bus); + irq = 0; + break; + } + } + BUG_ON(irq >= NR_IRQS); + + /* + * PCI IRQ command line redirection. Yes, limits are hardcoded. + */ + if ((pin >= 16) && (pin <= 23)) { + if (pirq_entries[pin-16] != -1) { + if (!pirq_entries[pin-16]) { + apic_printk(APIC_VERBOSE, "disabling PIRQ%d\n", pin-16); + } else { + irq = pirq_entries[pin-16]; + apic_printk(APIC_VERBOSE, "using PIRQ%d -> IRQ %d\n", + pin-16, irq); + } + } } BUG_ON(irq >= NR_IRQS); return irq; @@ -708,9 +943,9 @@ static void __init setup_IO_APIC_irqs(void) if (!apic && (irq < 16)) disable_8259A_irq(irq); } - ioapic_write_entry(apic, pin, entry); - spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); set_native_irq_info(irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -848,7 +1083,10 @@ void __apicdebuginit print_IO_APIC(void) for (i = 0; i <= reg_01.bits.entries; i++) { struct IO_APIC_route_entry entry; - entry = ioapic_read_entry(apic, i); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2); + *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2); + spin_unlock_irqrestore(&ioapic_lock, flags); printk(KERN_DEBUG " %02x %03X %02X ", i, @@ -1043,6 +1281,9 @@ static void __init enable_IO_APIC(void) irq_2_pin[i].pin = -1; irq_2_pin[i].next = 0; } + if (!pirqs_enabled) + for (i = 0; i < MAX_PIRQS; i++) + pirq_entries[i] = -1; /* * The number of IO-APIC IRQ registers (== #pins): @@ -1058,7 +1299,11 @@ static void __init enable_IO_APIC(void) /* See if any of the pins is in ExtINT mode */ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { struct IO_APIC_route_entry entry; - entry = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); + /* If the interrupt line is enabled and in ExtInt mode * I have found the pin where the i8259 is connected. @@ -1110,6 +1355,7 @@ void disable_IO_APIC(void) */ if (ioapic_i8259.pin != -1) { struct IO_APIC_route_entry entry; + unsigned long flags; memset(&entry, 0, sizeof(entry)); entry.mask = 0; /* Enabled */ @@ -1126,12 +1372,83 @@ void disable_IO_APIC(void) /* * Add it to the IO-APIC irq-routing table: */ - ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin, + *(((int *)&entry)+1)); + io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin, + *(((int *)&entry)+0)); + spin_unlock_irqrestore(&ioapic_lock, flags); } disconnect_bsp_APIC(ioapic_i8259.pin != -1); } +/* + * function to set the IO-APIC physical IDs based on the + * values stored in the MPC table. + * + * by Matt Domsch Tue Dec 21 12:25:05 CST 1999 + */ + +static void __init setup_ioapic_ids_from_mpc (void) +{ + union IO_APIC_reg_00 reg_00; + int apic; + int i; + unsigned char old_id; + unsigned long flags; + + /* + * Set the IOAPIC ID to the value stored in the MPC table. + */ + for (apic = 0; apic < nr_ioapics; apic++) { + + /* Read the register 0 value */ + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(apic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + + old_id = mp_ioapics[apic].mpc_apicid; + + + printk(KERN_INFO "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid); + + + /* + * We need to adjust the IRQ routing table + * if the ID changed. + */ + if (old_id != mp_ioapics[apic].mpc_apicid) + for (i = 0; i < mp_irq_entries; i++) + if (mp_irqs[i].mpc_dstapic == old_id) + mp_irqs[i].mpc_dstapic + = mp_ioapics[apic].mpc_apicid; + + /* + * Read the right value from the MPC table and + * write it into the ID register. + */ + apic_printk(APIC_VERBOSE,KERN_INFO "...changing IO-APIC physical APIC ID to %d ...", + mp_ioapics[apic].mpc_apicid); + + reg_00.bits.ID = mp_ioapics[apic].mpc_apicid; + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0, reg_00.raw); + spin_unlock_irqrestore(&ioapic_lock, flags); + + /* + * Sanity check + */ + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(apic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid) + printk("could not set ID!\n"); + else + apic_printk(APIC_VERBOSE," ok.\n"); + } +} + /* * There is a nasty bug in some older SMP boards, their mptable lies * about the timer IRQ. We do the following to work around the situation: @@ -1647,6 +1964,11 @@ void __init setup_IO_APIC(void) apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); + /* + * Set up the IO-APIC IRQ routing table. + */ + if (!acpi_ioapic) + setup_ioapic_ids_from_mpc(); sync_Arb_IDs(); setup_IO_APIC_irqs(); init_IO_APIC_traps(); @@ -1665,12 +1987,17 @@ static int ioapic_suspend(struct sys_device *dev, pm_message_t state) { struct IO_APIC_route_entry *entry; struct sysfs_ioapic_data *data; + unsigned long flags; int i; data = container_of(dev, struct sysfs_ioapic_data, dev); entry = data->entry; - for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) - *entry = ioapic_read_entry(dev->id, i); + spin_lock_irqsave(&ioapic_lock, flags); + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i); + *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i); + } + spin_unlock_irqrestore(&ioapic_lock, flags); return 0; } @@ -1692,9 +2019,11 @@ static int ioapic_resume(struct sys_device *dev) reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; io_apic_write(dev->id, 0, reg_00.raw); } + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1)); + io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0)); + } spin_unlock_irqrestore(&ioapic_lock, flags); - for (i = 0; i < nr_ioapic_registers[dev->id]; i++) - ioapic_write_entry(dev->id, i, entry[i]); return 0; } @@ -1748,6 +2077,19 @@ device_initcall(ioapic_init_sysfs); #define IO_APIC_MAX_ID 0xFE +int __init io_apic_get_version (int ioapic) +{ + union IO_APIC_reg_01 reg_01; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + reg_01.raw = io_apic_read(ioapic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return reg_01.bits.version; +} + + int __init io_apic_get_redir_entries (int ioapic) { union IO_APIC_reg_01 reg_01; @@ -1806,10 +2148,10 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p if (!ioapic && (irq < 16)) disable_8259A_irq(irq); - ioapic_write_entry(ioapic, pin, entry); - spin_lock_irqsave(&ioapic_lock, flags); - set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); + io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); + set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); return 0; diff --git a/trunk/arch/x86_64/kernel/ioport.c b/trunk/arch/x86_64/kernel/ioport.c index fe063d3cfe42..b81614970ecc 100644 --- a/trunk/arch/x86_64/kernel/ioport.c +++ b/trunk/arch/x86_64/kernel/ioport.c @@ -56,7 +56,6 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) memset(bitmap, 0xff, IO_BITMAP_BYTES); t->io_bitmap_ptr = bitmap; - set_thread_flag(TIF_IO_BITMAP); } /* diff --git a/trunk/arch/x86_64/kernel/irq.c b/trunk/arch/x86_64/kernel/irq.c index b3677e6ccc6e..5221a53e90c1 100644 --- a/trunk/arch/x86_64/kernel/irq.c +++ b/trunk/arch/x86_64/kernel/irq.c @@ -20,6 +20,11 @@ #include atomic_t irq_err_count; +#ifdef CONFIG_X86_IO_APIC +#ifdef APIC_MISMATCH_DEBUG +atomic_t irq_mis_count; +#endif +#endif #ifdef CONFIG_DEBUG_STACKOVERFLOW /* @@ -87,11 +92,18 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count); seq_putc(p, '\n'); +#ifdef CONFIG_X86_LOCAL_APIC seq_printf(p, "LOC: "); for_each_online_cpu(j) seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs); seq_putc(p, '\n'); +#endif seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); +#ifdef CONFIG_X86_IO_APIC +#ifdef APIC_MISMATCH_DEBUG + seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); +#endif +#endif } return 0; } diff --git a/trunk/arch/x86_64/kernel/machine_kexec.c b/trunk/arch/x86_64/kernel/machine_kexec.c index 0497e3bd5bff..106076b370fc 100644 --- a/trunk/arch/x86_64/kernel/machine_kexec.c +++ b/trunk/arch/x86_64/kernel/machine_kexec.c @@ -15,15 +15,6 @@ #include #include -#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) -static u64 kexec_pgd[512] PAGE_ALIGNED; -static u64 kexec_pud0[512] PAGE_ALIGNED; -static u64 kexec_pmd0[512] PAGE_ALIGNED; -static u64 kexec_pte0[512] PAGE_ALIGNED; -static u64 kexec_pud1[512] PAGE_ALIGNED; -static u64 kexec_pmd1[512] PAGE_ALIGNED; -static u64 kexec_pte1[512] PAGE_ALIGNED; - static void init_level2_page(pmd_t *level2p, unsigned long addr) { unsigned long end_addr; @@ -153,19 +144,32 @@ static void load_segments(void) ); } +typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, + unsigned long control_code_buffer, + unsigned long start_address, + unsigned long pgtable) ATTRIB_NORET; + +extern const unsigned char relocate_new_kernel[]; +extern const unsigned long relocate_new_kernel_size; + int machine_kexec_prepare(struct kimage *image) { - unsigned long start_pgtable; + unsigned long start_pgtable, control_code_buffer; int result; /* Calculate the offsets */ start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; + control_code_buffer = start_pgtable + PAGE_SIZE; /* Setup the identity mapped 64bit page table */ result = init_pgtable(image, start_pgtable); if (result) return result; + /* Place the code in the reboot code buffer */ + memcpy(__va(control_code_buffer), relocate_new_kernel, + relocate_new_kernel_size); + return 0; } @@ -180,34 +184,28 @@ void machine_kexec_cleanup(struct kimage *image) */ NORET_TYPE void machine_kexec(struct kimage *image) { - unsigned long page_list[PAGES_NR]; - void *control_page; + unsigned long page_list; + unsigned long control_code_buffer; + unsigned long start_pgtable; + relocate_new_kernel_t rnk; /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); - control_page = page_address(image->control_code_page) + PAGE_SIZE; - memcpy(control_page, relocate_kernel, PAGE_SIZE); - - page_list[PA_CONTROL_PAGE] = __pa(control_page); - page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; - page_list[PA_PGD] = __pa(kexec_pgd); - page_list[VA_PGD] = (unsigned long)kexec_pgd; - page_list[PA_PUD_0] = __pa(kexec_pud0); - page_list[VA_PUD_0] = (unsigned long)kexec_pud0; - page_list[PA_PMD_0] = __pa(kexec_pmd0); - page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; - page_list[PA_PTE_0] = __pa(kexec_pte0); - page_list[VA_PTE_0] = (unsigned long)kexec_pte0; - page_list[PA_PUD_1] = __pa(kexec_pud1); - page_list[VA_PUD_1] = (unsigned long)kexec_pud1; - page_list[PA_PMD_1] = __pa(kexec_pmd1); - page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; - page_list[PA_PTE_1] = __pa(kexec_pte1); - page_list[VA_PTE_1] = (unsigned long)kexec_pte1; - - page_list[PA_TABLE_PAGE] = - (unsigned long)__pa(page_address(image->control_code_page)); + /* Calculate the offsets */ + page_list = image->head; + start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; + control_code_buffer = start_pgtable + PAGE_SIZE; + + /* Set the low half of the page table to my identity mapped + * page table for kexec. Leave the high half pointing at the + * kernel pages. Don't bother to flush the global pages + * as that will happen when I fully switch to my identity mapped + * page table anyway. + */ + memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2); + __flush_tlb(); + /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is @@ -224,36 +222,7 @@ NORET_TYPE void machine_kexec(struct kimage *image) */ set_gdt(phys_to_virt(0),0); set_idt(phys_to_virt(0),0); - /* now call it */ - relocate_kernel((unsigned long)image->head, (unsigned long)page_list, - image->start); + rnk = (relocate_new_kernel_t) control_code_buffer; + (*rnk)(page_list, control_code_buffer, image->start, start_pgtable); } - -/* crashkernel=size@addr specifies the location to reserve for - * a crash kernel. By reserving this memory we guarantee - * that linux never set's it up as a DMA target. - * Useful for holding code to do something appropriate - * after a kernel panic. - */ -static int __init setup_crashkernel(char *arg) -{ - unsigned long size, base; - char *p; - if (!arg) - return -EINVAL; - size = memparse(arg, &p); - if (arg == p) - return -EINVAL; - if (*p == '@') { - base = memparse(p+1, &p); - /* FIXME: Do I want a sanity check to validate the - * memory range? Yes you do, but it's too early for - * e820 -AK */ - crashk_res.start = base; - crashk_res.end = base + size - 1; - } - return 0; -} -early_param("crashkernel", setup_crashkernel); - diff --git a/trunk/arch/x86_64/kernel/mce.c b/trunk/arch/x86_64/kernel/mce.c index bbea88801d88..4e017fb30fb3 100644 --- a/trunk/arch/x86_64/kernel/mce.c +++ b/trunk/arch/x86_64/kernel/mce.c @@ -182,7 +182,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) goto out2; memset(&m, 0, sizeof(struct mce)); - m.cpu = smp_processor_id(); + m.cpu = safe_smp_processor_id(); rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); if (!(m.mcgstatus & MCG_STATUS_RIPV)) kill_it = 1; @@ -274,33 +274,6 @@ void do_machine_check(struct pt_regs * regs, long error_code) atomic_dec(&mce_entry); } -#ifdef CONFIG_X86_MCE_INTEL -/*** - * mce_log_therm_throt_event - Logs the thermal throttling event to mcelog - * @cpu: The CPU on which the event occured. - * @status: Event status information - * - * This function should be called by the thermal interrupt after the - * event has been processed and the decision was made to log the event - * further. - * - * The status parameter will be saved to the 'status' field of 'struct mce' - * and historically has been the register value of the - * MSR_IA32_THERMAL_STATUS (Intel) msr. - */ -void mce_log_therm_throt_event(unsigned int cpu, __u64 status) -{ - struct mce m; - - memset(&m, 0, sizeof(m)); - m.cpu = cpu; - m.bank = MCE_THERMAL_BANK; - m.status = status; - rdtscll(m.tsc); - mce_log(&m); -} -#endif /* CONFIG_X86_MCE_INTEL */ - /* * Periodic polling timer for "silent" machine check errors. */ diff --git a/trunk/arch/x86_64/kernel/mce_intel.c b/trunk/arch/x86_64/kernel/mce_intel.c index 6551505d8a2c..8f533d2c40cb 100644 --- a/trunk/arch/x86_64/kernel/mce_intel.c +++ b/trunk/arch/x86_64/kernel/mce_intel.c @@ -11,21 +11,36 @@ #include #include #include -#include + +static DEFINE_PER_CPU(unsigned long, next_check); asmlinkage void smp_thermal_interrupt(void) { - __u64 msr_val; + struct mce m; ack_APIC_irq(); exit_idle(); irq_enter(); + if (time_before(jiffies, __get_cpu_var(next_check))) + goto done; + + __get_cpu_var(next_check) = jiffies + HZ*300; + memset(&m, 0, sizeof(m)); + m.cpu = smp_processor_id(); + m.bank = MCE_THERMAL_BANK; + rdtscll(m.tsc); + rdmsrl(MSR_IA32_THERM_STATUS, m.status); + if (m.status & 0x1) { + printk(KERN_EMERG + "CPU%d: Temperature above threshold, cpu clock throttled\n", m.cpu); + add_taint(TAINT_MACHINE_CHECK); + } else { + printk(KERN_EMERG "CPU%d: Temperature/speed normal\n", m.cpu); + } - rdmsrl(MSR_IA32_THERM_STATUS, msr_val); - if (therm_throt_process(msr_val & 1)) - mce_log_therm_throt_event(smp_processor_id(), msr_val); - + mce_log(&m); +done: irq_exit(); } @@ -77,9 +92,6 @@ static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n", cpu, tm2 ? "TM2" : "TM1"); - - /* enable thermal throttle processing */ - atomic_set(&therm_throt_en, 1); return; } diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index 20e88f4b564b..a1ab4197f8a1 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -41,7 +41,8 @@ int acpi_found_madt; * Various Linux-internal data structures created from the * MP-table. */ -DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); +unsigned char apic_version [MAX_APICS]; +unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; static int mp_current_pci_id = 0; @@ -55,6 +56,7 @@ struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; int mp_irq_entries; int nr_ioapics; +int pic_mode; unsigned long mp_lapic_addr = 0; @@ -69,6 +71,19 @@ unsigned disabled_cpus __initdata; /* Bitmask of physically existing CPUs */ physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE; +/* ACPI MADT entry parsing functions */ +#ifdef CONFIG_ACPI +extern struct acpi_boot_flags acpi_boot; +#ifdef CONFIG_X86_LOCAL_APIC +extern int acpi_parse_lapic (acpi_table_entry_header *header); +extern int acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header); +extern int acpi_parse_lapic_nmi (acpi_table_entry_header *header); +#endif /*CONFIG_X86_LOCAL_APIC*/ +#ifdef CONFIG_X86_IO_APIC +extern int acpi_parse_ioapic (acpi_table_entry_header *header); +#endif /*CONFIG_X86_IO_APIC*/ +#endif /*CONFIG_ACPI*/ + u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; @@ -93,20 +108,24 @@ static int __init mpf_checksum(unsigned char *mp, int len) static void __cpuinit MP_processor_info (struct mpc_config_processor *m) { int cpu; + unsigned char ver; cpumask_t tmp_map; - char *bootup_cpu = ""; if (!(m->mpc_cpuflag & CPU_ENABLED)) { disabled_cpus++; return; } + + printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK)>>8, + (m->mpc_cpufeature & CPU_MODEL_MASK)>>4, + m->mpc_apicver); + if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { - bootup_cpu = " (Bootup-CPU)"; + Dprintk(" Bootup CPU\n"); boot_cpu_id = m->mpc_apicid; } - - printk(KERN_INFO "Processor #%d%s\n", m->mpc_apicid, bootup_cpu); - if (num_processors >= NR_CPUS) { printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." " Processor ignored.\n", NR_CPUS); @@ -117,7 +136,24 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m) cpus_complement(tmp_map, cpu_present_map); cpu = first_cpu(tmp_map); +#if MAX_APICS < 255 + if ((int)m->mpc_apicid > MAX_APICS) { + printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", + m->mpc_apicid, MAX_APICS); + return; + } +#endif + ver = m->mpc_apicver; + physid_set(m->mpc_apicid, phys_cpu_present_map); + /* + * Validate version + */ + if (ver == 0x0) { + printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid); + ver = 0x10; + } + apic_version[m->mpc_apicid] = ver; if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { /* * bios_cpu_apicid is required to have processors listed @@ -142,11 +178,15 @@ static void __init MP_bus_info (struct mpc_config_bus *m) Dprintk("Bus #%d is %s\n", m->mpc_busid, str); if (strncmp(str, "ISA", 3) == 0) { - set_bit(m->mpc_busid, mp_bus_not_pci); + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; + } else if (strncmp(str, "EISA", 4) == 0) { + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; } else if (strncmp(str, "PCI", 3) == 0) { - clear_bit(m->mpc_busid, mp_bus_not_pci); + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id; mp_current_pci_id++; + } else if (strncmp(str, "MCA", 3) == 0) { + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; } else { printk(KERN_ERR "Unknown bustype %s\n", str); } @@ -157,8 +197,8 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m) if (!(m->mpc_flags & MPC_APIC_USABLE)) return; - printk("I/O APIC #%d at 0x%X.\n", - m->mpc_apicid, m->mpc_apicaddr); + printk("I/O APIC #%d Version %d at 0x%X.\n", + m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr); if (nr_ioapics >= MAX_IO_APICS) { printk(KERN_ERR "Max # of I/O APICs (%d) exceeded (found %d).\n", MAX_IO_APICS, nr_ioapics); @@ -192,6 +232,19 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m) m->mpc_irqtype, m->mpc_irqflag & 3, (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid, m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); + /* + * Well it seems all SMP boards in existence + * use ExtINT/LVT1 == LINT0 and + * NMI/LVT2 == LINT1 - the following check + * will show us if this assumptions is false. + * Until then we do not have to add baggage. + */ + if ((m->mpc_irqtype == mp_ExtINT) && + (m->mpc_destapiclint != 0)) + BUG(); + if ((m->mpc_irqtype == mp_NMI) && + (m->mpc_destapiclint != 1)) + BUG(); } /* @@ -205,7 +258,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) unsigned char *mpt=((unsigned char *)mpc)+count; if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { - printk("MPTABLE: bad signature [%c%c%c%c]!\n", + printk("SMP mptable: bad signature [%c%c%c%c]!\n", mpc->mpc_signature[0], mpc->mpc_signature[1], mpc->mpc_signature[2], @@ -213,31 +266,31 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) return 0; } if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { - printk("MPTABLE: checksum error!\n"); + printk("SMP mptable: checksum error!\n"); return 0; } if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) { - printk(KERN_ERR "MPTABLE: bad table version (%d)!!\n", + printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n", mpc->mpc_spec); return 0; } if (!mpc->mpc_lapic) { - printk(KERN_ERR "MPTABLE: null local APIC address!\n"); + printk(KERN_ERR "SMP mptable: null local APIC address!\n"); return 0; } memcpy(str,mpc->mpc_oem,8); - str[8] = 0; - printk(KERN_INFO "MPTABLE: OEM ID: %s ",str); + str[8]=0; + printk(KERN_INFO "OEM ID: %s ",str); memcpy(str,mpc->mpc_productid,12); - str[12] = 0; - printk("MPTABLE: Product ID: %s ",str); + str[12]=0; + printk("Product ID: %s ",str); - printk("MPTABLE: APIC at: 0x%X\n",mpc->mpc_lapic); + printk("APIC at: 0x%X\n",mpc->mpc_lapic); /* save the local APIC address, it might be non-default */ if (!acpi_lapic) - mp_lapic_addr = mpc->mpc_lapic; + mp_lapic_addr = mpc->mpc_lapic; /* * Now process the configuration blocks. @@ -249,7 +302,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) struct mpc_config_processor *m= (struct mpc_config_processor *)mpt; if (!acpi_lapic) - MP_processor_info(m); + MP_processor_info(m); mpt += sizeof(*m); count += sizeof(*m); break; @@ -268,8 +321,8 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) struct mpc_config_ioapic *m= (struct mpc_config_ioapic *)mpt; MP_ioapic_info(m); - mpt += sizeof(*m); - count += sizeof(*m); + mpt+=sizeof(*m); + count+=sizeof(*m); break; } case MP_INTSRC: @@ -278,8 +331,8 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) (struct mpc_config_intsrc *)mpt; MP_intsrc_info(m); - mpt += sizeof(*m); - count += sizeof(*m); + mpt+=sizeof(*m); + count+=sizeof(*m); break; } case MP_LINTSRC: @@ -287,15 +340,15 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) struct mpc_config_lintsrc *m= (struct mpc_config_lintsrc *)mpt; MP_lintsrc_info(m); - mpt += sizeof(*m); - count += sizeof(*m); + mpt+=sizeof(*m); + count+=sizeof(*m); break; } } } clustered_apic_check(); if (!num_processors) - printk(KERN_ERR "MPTABLE: no processors registered!\n"); + printk(KERN_ERR "SMP mptable: no processors registered!\n"); return num_processors; } @@ -391,10 +444,13 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) * 2 CPUs, numbered 0 & 1. */ processor.mpc_type = MP_PROCESSOR; - processor.mpc_apicver = 0; + /* Either an integrated APIC or a discrete 82489DX. */ + processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; processor.mpc_cpuflag = CPU_ENABLED; - processor.mpc_cpufeature = 0; - processor.mpc_featureflag = 0; + processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | + (boot_cpu_data.x86_model << 4) | + boot_cpu_data.x86_mask; + processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; processor.mpc_reserved[0] = 0; processor.mpc_reserved[1] = 0; for (i = 0; i < 2; i++) { @@ -413,6 +469,14 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) case 5: memcpy(bus.mpc_bustype, "ISA ", 6); break; + case 2: + case 6: + case 3: + memcpy(bus.mpc_bustype, "EISA ", 6); + break; + case 4: + case 7: + memcpy(bus.mpc_bustype, "MCA ", 6); } MP_bus_info(&bus); if (mpc_default_type > 4) { @@ -423,7 +487,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) ioapic.mpc_type = MP_IOAPIC; ioapic.mpc_apicid = 2; - ioapic.mpc_apicver = 0; + ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; ioapic.mpc_flags = MPC_APIC_USABLE; ioapic.mpc_apicaddr = 0xFEC00000; MP_ioapic_info(&ioapic); @@ -466,6 +530,13 @@ void __init get_smp_config (void) printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); + if (mpf->mpf_feature2 & (1<<7)) { + printk(KERN_INFO " IMCR and PIC compatibility mode.\n"); + pic_mode = 1; + } else { + printk(KERN_INFO " Virtual Wire compatibility mode.\n"); + pic_mode = 0; + } /* * Now see if we need to read further. @@ -545,7 +616,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) return 0; } -void __init find_smp_config(void) +void __init find_intel_smp (void) { unsigned int address; @@ -562,7 +633,9 @@ void __init find_smp_config(void) smp_scan_config(0xF0000,0x10000)) return; /* - * If it is an SMP machine we should know now. + * If it is an SMP machine we should know now, unless the + * configuration is in an EISA/MCA bus machine with an + * extended bios data area. * * there is a real-mode segmented pointer pointing to the * 4K EBDA area at 0x40E, calculate and scan it here. @@ -583,41 +656,69 @@ void __init find_smp_config(void) printk(KERN_INFO "No mptable found.\n"); } +/* + * - Intel MP Configuration Table + */ +void __init find_smp_config (void) +{ +#ifdef CONFIG_X86_LOCAL_APIC + find_intel_smp(); +#endif +} + + /* -------------------------------------------------------------------------- ACPI-based MP Configuration -------------------------------------------------------------------------- */ #ifdef CONFIG_ACPI -void __init mp_register_lapic_address(u64 address) +void __init mp_register_lapic_address ( + u64 address) { mp_lapic_addr = (unsigned long) address; + set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); + if (boot_cpu_id == -1U) boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID)); + + Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); } -void __cpuinit mp_register_lapic (u8 id, u8 enabled) + +void __cpuinit mp_register_lapic ( + u8 id, + u8 enabled) { struct mpc_config_processor processor; int boot_cpu = 0; - if (id == boot_cpu_id) + if (id >= MAX_APICS) { + printk(KERN_WARNING "Processor #%d invalid (max %d)\n", + id, MAX_APICS); + return; + } + + if (id == boot_cpu_physical_apicid) boot_cpu = 1; processor.mpc_type = MP_PROCESSOR; processor.mpc_apicid = id; - processor.mpc_apicver = 0; + processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR)); processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0); processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0); - processor.mpc_cpufeature = 0; - processor.mpc_featureflag = 0; + processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | + (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; + processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; processor.mpc_reserved[0] = 0; processor.mpc_reserved[1] = 0; MP_processor_info(&processor); } +#ifdef CONFIG_X86_IO_APIC + #define MP_ISA_BUS 0 #define MP_MAX_IOAPIC_PIN 127 @@ -628,9 +729,11 @@ static struct mp_ioapic_routing { u32 pin_programmed[4]; } mp_ioapic_routing[MAX_IO_APICS]; -static int mp_find_ioapic(int gsi) + +static int mp_find_ioapic ( + int gsi) { - int i = 0; + int i = 0; /* Find the IOAPIC that manages this GSI. */ for (i = 0; i < nr_ioapics; i++) { @@ -640,12 +743,17 @@ static int mp_find_ioapic(int gsi) } printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); + return -1; } + -void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) +void __init mp_register_ioapic ( + u8 id, + u32 address, + u32 gsi_base) { - int idx = 0; + int idx = 0; if (nr_ioapics >= MAX_IO_APICS) { printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " @@ -666,7 +774,7 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); mp_ioapics[idx].mpc_apicid = id; - mp_ioapics[idx].mpc_apicver = 0; + mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); /* * Build basic IRQ lookup table to facilitate gsi->io_apic lookups @@ -677,15 +785,21 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) mp_ioapic_routing[idx].gsi_end = gsi_base + io_apic_get_redir_entries(idx); - printk(KERN_INFO "IOAPIC[%d]: apic_id %d, address 0x%x, " + printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, - mp_ioapics[idx].mpc_apicaddr, + mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, mp_ioapic_routing[idx].gsi_start, mp_ioapic_routing[idx].gsi_end); + + return; } -void __init -mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) + +void __init mp_override_legacy_irq ( + u8 bus_irq, + u8 polarity, + u8 trigger, + u32 gsi) { struct mpc_config_intsrc intsrc; int ioapic = -1; @@ -723,18 +837,22 @@ mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) mp_irqs[mp_irq_entries] = intsrc; if (++mp_irq_entries == MAX_IRQ_SOURCES) panic("Max # of irq sources exceeded!\n"); + + return; } -void __init mp_config_acpi_legacy_irqs(void) + +void __init mp_config_acpi_legacy_irqs (void) { struct mpc_config_intsrc intsrc; - int i = 0; - int ioapic = -1; + int i = 0; + int ioapic = -1; /* * Fabricate the legacy ISA bus (bus #31). */ - set_bit(MP_ISA_BUS, mp_bus_not_pci); + mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; + Dprintk("Bus #%d is ISA\n", MP_ISA_BUS); /* * Locate the IOAPIC that manages the ISA IRQs (0-15). @@ -787,22 +905,24 @@ void __init mp_config_acpi_legacy_irqs(void) if (++mp_irq_entries == MAX_IRQ_SOURCES) panic("Max # of irq sources exceeded!\n"); } + + return; } #define MAX_GSI_NUM 4096 int mp_register_gsi(u32 gsi, int triggering, int polarity) { - int ioapic = -1; - int ioapic_pin = 0; - int idx, bit = 0; - static int pci_irq = 16; + int ioapic = -1; + int ioapic_pin = 0; + int idx, bit = 0; + static int pci_irq = 16; /* * Mapping between Global System Interrupts, which * represent all possible interrupts, to the IRQs * assigned to actual devices. */ - static int gsi_to_irq[MAX_GSI_NUM]; + static int gsi_to_irq[MAX_GSI_NUM]; if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) return gsi; @@ -876,4 +996,6 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) polarity == ACPI_ACTIVE_HIGH ? 0 : 1); return gsi; } + +#endif /*CONFIG_X86_IO_APIC*/ #endif /*CONFIG_ACPI*/ diff --git a/trunk/arch/x86_64/kernel/nmi.c b/trunk/arch/x86_64/kernel/nmi.c index 4d6fb047952e..5baa0c726e97 100644 --- a/trunk/arch/x86_64/kernel/nmi.c +++ b/trunk/arch/x86_64/kernel/nmi.c @@ -28,138 +28,71 @@ #include #include -/* perfctr_nmi_owner tracks the ownership of the perfctr registers: - * evtsel_nmi_owner tracks the ownership of the event selection - * - different performance counters/ event selection may be reserved for - * different subsystems this reservation system just tries to coordinate - * things a little - */ -static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner); -static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[2]); - -/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's - * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) +/* + * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: + * - it may be reserved by some other driver, or not + * - when not reserved by some other driver, it may be used for + * the NMI watchdog, or not + * + * This is maintained separately from nmi_active because the NMI + * watchdog may also be driven from the I/O APIC timer. */ -#define NMI_MAX_COUNTER_BITS 66 +static DEFINE_SPINLOCK(lapic_nmi_owner_lock); +static unsigned int lapic_nmi_owner; +#define LAPIC_NMI_WATCHDOG (1<<0) +#define LAPIC_NMI_RESERVED (1<<1) /* nmi_active: - * >0: the lapic NMI watchdog is active, but can be disabled - * <0: the lapic NMI watchdog has not been set up, and cannot + * +1: the lapic NMI watchdog is active, but can be disabled + * 0: the lapic NMI watchdog has not been set up, and cannot * be enabled - * 0: the lapic NMI watchdog is disabled, but can be enabled + * -1: the lapic NMI watchdog is disabled, but can be enabled */ -atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ +int nmi_active; /* oprofile uses this */ int panic_on_timeout; unsigned int nmi_watchdog = NMI_DEFAULT; static unsigned int nmi_hz = HZ; +static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ +static unsigned int nmi_p4_cccr_val; -struct nmi_watchdog_ctlblk { - int enabled; - u64 check_bit; - unsigned int cccr_msr; - unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ - unsigned int evntsel_msr; /* the MSR to select the events to handle */ -}; -static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); - -/* local prototypes */ -static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the performance counter register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_PERFCTR0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_PERFCTR0); - else - return (msr - MSR_P4_BPU_PERFCTR0); - } - return 0; -} - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the event selection register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_EVNTSEL0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_EVENTSEL0); - else - return (msr - MSR_P4_BSU_ESCR0); - } - return 0; -} - -/* checks for a bit availability (hack for oprofile) */ -int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) -{ - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); -} - -/* checks the an msr for availability */ -int avail_to_resrv_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); -} - -int reserve_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner))) - return 1; - return 0; -} - -void release_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner)); -} - -int reserve_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner))) - return 1; - return 0; -} +/* Note that these events don't tick when the CPU idles. This means + the frequency varies with CPU load. */ -void release_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; +#define K7_EVNTSEL_ENABLE (1 << 22) +#define K7_EVNTSEL_INT (1 << 20) +#define K7_EVNTSEL_OS (1 << 17) +#define K7_EVNTSEL_USR (1 << 16) +#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 +#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); +#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL +#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)); -} +#define MSR_P4_MISC_ENABLE 0x1A0 +#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) +#define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12) +#define MSR_P4_PERFCTR0 0x300 +#define MSR_P4_CCCR0 0x360 +#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) +#define P4_ESCR_OS (1<<3) +#define P4_ESCR_USR (1<<2) +#define P4_CCCR_OVF_PMI0 (1<<26) +#define P4_CCCR_OVF_PMI1 (1<<27) +#define P4_CCCR_THRESHOLD(N) ((N)<<20) +#define P4_CCCR_COMPLEMENT (1<<19) +#define P4_CCCR_COMPARE (1<<18) +#define P4_CCCR_REQUIRED (3<<16) +#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) +#define P4_CCCR_ENABLE (1<<12) +/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter + CRU_ESCR0 (with any non-null event selector) through a complemented + max threshold. [IA32-Vol3, Section 14.9.9] */ +#define MSR_P4_IQ_COUNTER0 0x30C +#define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR) +#define P4_NMI_IQ_CCCR0 \ + (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ + P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) static __cpuinit inline int nmi_known_cpu(void) { @@ -176,7 +109,7 @@ static __cpuinit inline int nmi_known_cpu(void) } /* Run after command line and cpu_init init, but before all other checks */ -void nmi_watchdog_default(void) +void __cpuinit nmi_watchdog_default(void) { if (nmi_watchdog != NMI_DEFAULT) return; @@ -212,12 +145,6 @@ int __init check_nmi_watchdog (void) int *counts; int cpu; - if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) - return 0; - - if (!atomic_read(&nmi_active)) - return 0; - counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); if (!counts) return -1; @@ -235,43 +162,26 @@ int __init check_nmi_watchdog (void) mdelay((10*1000)/nmi_hz); // wait 10 ticks for_each_online_cpu(cpu) { - if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled) - continue; if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) { + endflag = 1; printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", cpu, counts[cpu], cpu_pda(cpu)->__nmi_count); - per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0; - atomic_dec(&nmi_active); + nmi_active = 0; + lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; + nmi_perfctr_msr = 0; + kfree(counts); + return -1; } } - if (!atomic_read(&nmi_active)) { - kfree(counts); - atomic_set(&nmi_active, -1); - return -1; - } endflag = 1; printk("OK.\n"); /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ - if (nmi_watchdog == NMI_LOCAL_APIC) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - + if (nmi_watchdog == NMI_LOCAL_APIC) nmi_hz = 1; - /* - * On Intel CPUs with ARCH_PERFMON only 32 bits in the counter - * are writable, with higher bits sign extending from bit 31. - * So, we can only program the counter with 31 bit values and - * 32nd bit should be 1, for 33.. to be 1. - * Find the appropriate nmi_hz - */ - if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0 && - ((u64)cpu_khz * 1000) > 0x7fffffffULL) { - nmi_hz = ((u64)cpu_khz * 1000) / 0x7fffffffUL + 1; - } - } kfree(counts); return 0; @@ -291,65 +201,91 @@ int __init setup_nmi_watchdog(char *str) get_option(&str, &nmi); - if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE)) + if (nmi >= NMI_INVALID) return 0; - - if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0)) - return 0; /* no lapic support */ nmi_watchdog = nmi; return 1; } __setup("nmi_watchdog=", setup_nmi_watchdog); +static void disable_intel_arch_watchdog(void); + static void disable_lapic_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - if (atomic_read(&nmi_active) <= 0) + if (nmi_active <= 0) return; - - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + wrmsr(MSR_K7_EVNTSEL0, 0, 0); + break; + case X86_VENDOR_INTEL: + if (boot_cpu_data.x86 == 15) { + wrmsr(MSR_P4_IQ_CCCR0, 0, 0); + wrmsr(MSR_P4_CRU_ESCR0, 0, 0); + } else if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + disable_intel_arch_watchdog(); + } + break; + } + nmi_active = -1; + /* tell do_nmi() and others that we're not active any more */ + nmi_watchdog = 0; } static void enable_lapic_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + if (nmi_active < 0) { + nmi_watchdog = NMI_LOCAL_APIC; + touch_nmi_watchdog(); + setup_apic_nmi_watchdog(); + } +} - /* are we already enabled */ - if (atomic_read(&nmi_active) != 0) - return; +int reserve_lapic_nmi(void) +{ + unsigned int old_owner; - /* are we lapic aware */ - if (nmi_known_cpu() <= 0) - return; + spin_lock(&lapic_nmi_owner_lock); + old_owner = lapic_nmi_owner; + lapic_nmi_owner |= LAPIC_NMI_RESERVED; + spin_unlock(&lapic_nmi_owner_lock); + if (old_owner & LAPIC_NMI_RESERVED) + return -EBUSY; + if (old_owner & LAPIC_NMI_WATCHDOG) + disable_lapic_nmi_watchdog(); + return 0; +} + +void release_lapic_nmi(void) +{ + unsigned int new_owner; - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - touch_nmi_watchdog(); + spin_lock(&lapic_nmi_owner_lock); + new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED; + lapic_nmi_owner = new_owner; + spin_unlock(&lapic_nmi_owner_lock); + if (new_owner & LAPIC_NMI_WATCHDOG) + enable_lapic_nmi_watchdog(); } void disable_timer_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) <= 0) + if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0)) return; disable_irq(0); - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); + unset_nmi_callback(); + nmi_active = -1; + nmi_watchdog = NMI_NONE; } void enable_timer_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) == 0) { + if (nmi_active < 0) { + nmi_watchdog = NMI_IO_APIC; touch_nmi_watchdog(); - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); + nmi_active = 1; enable_irq(0); } } @@ -360,20 +296,15 @@ static int nmi_pm_active; /* nmi_active before suspend */ static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) { - /* only CPU0 goes here, other CPUs should be offline */ - nmi_pm_active = atomic_read(&nmi_active); - stop_apic_nmi_watchdog(NULL); - BUG_ON(atomic_read(&nmi_active) != 0); + nmi_pm_active = nmi_active; + disable_lapic_nmi_watchdog(); return 0; } static int lapic_nmi_resume(struct sys_device *dev) { - /* only CPU0 goes here, other CPUs should be offline */ - if (nmi_pm_active > 0) { - setup_apic_nmi_watchdog(NULL); - touch_nmi_watchdog(); - } + if (nmi_pm_active > 0) + enable_lapic_nmi_watchdog(); return 0; } @@ -392,13 +323,7 @@ static int __init init_lapic_nmi_sysfs(void) { int error; - /* should really be a BUG_ON but b/c this is an - * init call, it just doesn't work. -dcz - */ - if (nmi_watchdog != NMI_LOCAL_APIC) - return 0; - - if ( atomic_read(&nmi_active) < 0 ) + if (nmi_active == 0 || nmi_watchdog != NMI_LOCAL_APIC) return 0; error = sysdev_class_register(&nmi_sysclass); @@ -416,209 +341,74 @@ late_initcall(init_lapic_nmi_sysfs); * Original code written by Keith Owens. */ -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ +static void clear_msr_range(unsigned int base, unsigned int n) +{ + unsigned int i; -#define K7_EVNTSEL_ENABLE (1 << 22) -#define K7_EVNTSEL_INT (1 << 20) -#define K7_EVNTSEL_OS (1 << 17) -#define K7_EVNTSEL_USR (1 << 16) -#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 -#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING + for(i = 0; i < n; ++i) + wrmsr(base+i, 0, 0); +} -static int setup_k7_watchdog(void) +static void setup_k7_watchdog(void) { - unsigned int perfctr_msr, evntsel_msr; + int i; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_K7_PERFCTR0; - evntsel_msr = MSR_K7_EVNTSEL0; - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_K7_PERFCTR0; - /* Simulator may not support it */ - if (checking_wrmsrl(evntsel_msr, 0UL)) - goto fail2; - wrmsrl(perfctr_msr, 0UL); + for(i = 0; i < 4; ++i) { + /* Simulator may not support it */ + if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) { + nmi_perfctr_msr = 0; + return; + } + wrmsrl(MSR_K7_PERFCTR0+i, 0UL); + } evntsel = K7_EVNTSEL_INT | K7_EVNTSEL_OS | K7_EVNTSEL_USR | K7_NMI_EVENT; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); + wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz)); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= K7_EVNTSEL_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL<<63; - return 1; -fail2: - release_evntsel_nmi(evntsel_msr); -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); } -static void stop_k7_watchdog(void) +static void disable_intel_arch_watchdog(void) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); - - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); -} - -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) -#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) -#define P4_ESCR_OS (1<<3) -#define P4_ESCR_USR (1<<2) -#define P4_CCCR_OVF_PMI0 (1<<26) -#define P4_CCCR_OVF_PMI1 (1<<27) -#define P4_CCCR_THRESHOLD(N) ((N)<<20) -#define P4_CCCR_COMPLEMENT (1<<19) -#define P4_CCCR_COMPARE (1<<18) -#define P4_CCCR_REQUIRED (3<<16) -#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) -#define P4_CCCR_ENABLE (1<<12) -#define P4_CCCR_OVF (1<<31) -/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter - CRU_ESCR0 (with any non-null event selector) through a complemented - max threshold. [IA32-Vol3, Section 14.9.9] */ - -static int setup_p4_watchdog(void) -{ - unsigned int perfctr_msr, evntsel_msr, cccr_msr; - unsigned int evntsel, cccr_val; - unsigned int misc_enable, dummy; - unsigned int ht_num; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); - if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) - return 0; - -#ifdef CONFIG_SMP - /* detect which hyperthread we are on */ - if (smp_num_siblings == 2) { - unsigned int ebx, apicid; - - ebx = cpuid_ebx(1); - apicid = (ebx >> 24) & 0xff; - ht_num = apicid & 1; - } else -#endif - ht_num = 0; + unsigned ebx; - /* performance counters are shared resources - * assign each hyperthread its own set - * (re-use the ESCR0 register, seems safe - * and keeps the cccr_val the same) + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebp indicates event present. */ - if (!ht_num) { - /* logical cpu 0 */ - perfctr_msr = MSR_P4_IQ_PERFCTR0; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR0; - cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); - } else { - /* logical cpu 1 */ - perfctr_msr = MSR_P4_IQ_PERFCTR1; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR1; - cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); - } - - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; - - evntsel = P4_ESCR_EVENT_SELECT(0x3F) - | P4_ESCR_OS - | P4_ESCR_USR; - - cccr_val |= P4_CCCR_THRESHOLD(15) - | P4_CCCR_COMPLEMENT - | P4_CCCR_COMPARE - | P4_CCCR_REQUIRED; - - wrmsr(evntsel_msr, evntsel, 0); - wrmsr(cccr_msr, cccr_val, 0); - wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); - apic_write(APIC_LVTPC, APIC_DM_NMI); - cccr_val |= P4_CCCR_ENABLE; - wrmsr(cccr_msr, cccr_val, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = cccr_msr; - wd->check_bit = 1ULL<<39; - return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; -} - -static void stop_p4_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->cccr_msr, 0, 0); - wrmsr(wd->evntsel_msr, 0, 0); - - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + ebx = cpuid_ebx(10); + if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0); } -#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL -#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - static int setup_intel_arch_watchdog(void) { - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - unsigned int perfctr_msr, evntsel_msr; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + unsigned ebx; /* * Check whether the Architectural PerfMon supports * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. + * NOTE: Corresponding bit = 0 in ebp indicates event present. */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - goto fail; - - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; - - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; + ebx = cpuid_ebx(10); + if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + return 0; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - wrmsrl(perfctr_msr, 0UL); + clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); + clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); evntsel = ARCH_PERFMON_EVENTSEL_INT | ARCH_PERFMON_EVENTSEL_OS @@ -626,122 +416,84 @@ static int setup_intel_arch_watchdog(void) | ARCH_PERFMON_NMI_EVENT_SEL | ARCH_PERFMON_NMI_EVENT_UMASK; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); - + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); + wrmsrl(MSR_ARCH_PERFMON_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz)); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL << (eax.split.bit_width - 1); + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; } -static void stop_intel_arch_watchdog(void) + +static int setup_p4_watchdog(void) { - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + unsigned int misc_enable, dummy; - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. - */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - return; + rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy); + if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) + return 0; - wrmsr(wd->evntsel_msr, 0, 0); + nmi_perfctr_msr = MSR_P4_IQ_COUNTER0; + nmi_p4_cccr_val = P4_NMI_IQ_CCCR0; +#ifdef CONFIG_SMP + if (smp_num_siblings == 2) + nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1; +#endif - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL)) + clear_msr_range(0x3F1, 2); + /* MSR 0x3F0 seems to have a default value of 0xFC00, but current + docs doesn't fully define it, so leave it alone for now. */ + if (boot_cpu_data.x86_model >= 0x3) { + /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */ + clear_msr_range(0x3A0, 26); + clear_msr_range(0x3BC, 3); + } else { + clear_msr_range(0x3A0, 31); + } + clear_msr_range(0x3C0, 6); + clear_msr_range(0x3C8, 6); + clear_msr_range(0x3E0, 2); + clear_msr_range(MSR_P4_CCCR0, 18); + clear_msr_range(MSR_P4_PERFCTR0, 18); + + wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); + wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); + Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz * 1000UL / nmi_hz)); + wrmsrl(MSR_P4_IQ_COUNTER0, -((u64)cpu_khz * 1000 / nmi_hz)); + apic_write(APIC_LVTPC, APIC_DM_NMI); + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); + return 1; } -void setup_apic_nmi_watchdog(void *unused) +void setup_apic_nmi_watchdog(void) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; - - if (wd->enabled == 1) - return; - - /* cheap hack to support suspend/resume */ - /* if cpu0 is not active neither should the other cpus */ - if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0)) - return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) - return; - if (!setup_k7_watchdog()) + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (boot_cpu_data.x86 != 15) + return; + if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) + return; + setup_k7_watchdog(); + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + if (!setup_intel_arch_watchdog()) return; - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - if (!setup_intel_arch_watchdog()) - return; - break; - } + } else if (boot_cpu_data.x86 == 15) { if (!setup_p4_watchdog()) return; - break; - default: + } else { return; } - } - wd->enabled = 1; - atomic_inc(&nmi_active); -} - -void stop_apic_nmi_watchdog(void *unused) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; + break; - if (wd->enabled == 0) + default: return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) - return; - stop_k7_watchdog(); - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - stop_intel_arch_watchdog(); - break; - } - stop_p4_watchdog(); - break; - default: - return; - } } - wd->enabled = 0; - atomic_dec(&nmi_active); + lapic_nmi_owner = LAPIC_NMI_WATCHDOG; + nmi_active = 1; } /* @@ -774,109 +526,93 @@ void touch_nmi_watchdog (void) touch_softlockup_watchdog(); } -int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) +void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) { int sum; int touched = 0; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - u64 dummy; - int rc=0; - - /* check for other users first */ - if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) - == NOTIFY_STOP) { - rc = 1; - touched = 1; - } sum = read_pda(apic_timer_irqs); if (__get_cpu_var(nmi_touch)) { __get_cpu_var(nmi_touch) = 0; touched = 1; } - #ifdef CONFIG_X86_MCE /* Could check oops_in_progress here too, but it's safer not too */ if (atomic_read(&mce_entry) > 0) touched = 1; #endif - /* if the apic timer isn't firing, this cpu isn't doing much */ if (!touched && __get_cpu_var(last_irq_sum) == sum) { /* * Ayiee, looks like this CPU is stuck ... * wait a few IRQs (5 seconds) before doing the oops ... */ local_inc(&__get_cpu_var(alert_counter)); - if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) - die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs, - panic_on_timeout); + if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) { + if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) + == NOTIFY_STOP) { + local_set(&__get_cpu_var(alert_counter), 0); + return; + } + die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs); + } } else { __get_cpu_var(last_irq_sum) = sum; local_set(&__get_cpu_var(alert_counter), 0); } - - /* see if the nmi watchdog went off */ - if (wd->enabled) { - if (nmi_watchdog == NMI_LOCAL_APIC) { - rdmsrl(wd->perfctr_msr, dummy); - if (dummy & wd->check_bit){ - /* this wasn't a watchdog timer interrupt */ - goto done; - } - - /* only Intel uses the cccr msr */ - if (wd->cccr_msr != 0) { - /* - * P4 quirks: - * - An overflown perfctr will assert its interrupt - * until the OVF flag in its CCCR is cleared. - * - LVTPC is masked on interrupt and must be - * unmasked by the LVTPC handler. - */ - rdmsrl(wd->cccr_msr, dummy); - dummy &= ~P4_CCCR_OVF; - wrmsrl(wd->cccr_msr, dummy); - apic_write(APIC_LVTPC, APIC_DM_NMI); - } else if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { - /* - * ArchPerfom/Core Duo needs to re-unmask - * the apic vector - */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - } - /* start the cycle over again */ - wrmsrl(wd->perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); - rc = 1; - } else if (nmi_watchdog == NMI_IO_APIC) { - /* don't know how to accurately check for this. - * just assume it was a watchdog timer interrupt - * This matches the old behaviour. + if (nmi_perfctr_msr) { + if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) { + /* + * P4 quirks: + * - An overflown perfctr will assert its interrupt + * until the OVF flag in its CCCR is cleared. + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. + */ + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); + apic_write(APIC_LVTPC, APIC_DM_NMI); + } else if (nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + /* + * For Intel based architectural perfmon + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. */ - rc = 1; - } else - printk(KERN_WARNING "Unknown enabled NMI hardware?!\n"); + apic_write(APIC_LVTPC, APIC_DM_NMI); + } + wrmsrl(nmi_perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); } -done: - return rc; } +static __kprobes int dummy_nmi_callback(struct pt_regs * regs, int cpu) +{ + return 0; +} + +static nmi_callback_t nmi_callback = dummy_nmi_callback; + asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) { + int cpu = safe_smp_processor_id(); + nmi_enter(); add_pda(__nmi_count,1); - default_do_nmi(regs); + if (!rcu_dereference(nmi_callback)(regs, cpu)) + default_do_nmi(regs); nmi_exit(); } -int do_nmi_callback(struct pt_regs * regs, int cpu) +void set_nmi_callback(nmi_callback_t callback) { -#ifdef CONFIG_SYSCTL - if (unknown_nmi_panic) - return unknown_nmi_panic_callback(regs, cpu); -#endif - return 0; + vmalloc_sync_all(); + rcu_assign_pointer(nmi_callback, callback); +} +EXPORT_SYMBOL_GPL(set_nmi_callback); + +void unset_nmi_callback(void) +{ + nmi_callback = dummy_nmi_callback; } +EXPORT_SYMBOL_GPL(unset_nmi_callback); #ifdef CONFIG_SYSCTL @@ -885,42 +621,36 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) unsigned char reason = get_nmi_reason(); char buf[64]; - sprintf(buf, "NMI received for unknown reason %02x\n", reason); - die_nmi(buf, regs, 1); /* Always panic here */ + if (!(reason & 0xc0)) { + sprintf(buf, "NMI received for unknown reason %02x\n", reason); + die_nmi(buf,regs); + } return 0; } /* - * proc handler for /proc/sys/kernel/nmi + * proc handler for /proc/sys/kernel/unknown_nmi_panic */ -int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, +int proc_unknown_nmi_panic(struct ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, loff_t *ppos) { int old_state; - nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0; - old_state = nmi_watchdog_enabled; + old_state = unknown_nmi_panic; proc_dointvec(table, write, file, buffer, length, ppos); - if (!!old_state == !!nmi_watchdog_enabled) + if (!!old_state == !!unknown_nmi_panic) return 0; - if (atomic_read(&nmi_active) < 0) { - printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); - return -EIO; - } - - /* if nmi_watchdog is not set yet, then set it */ - nmi_watchdog_default(); - - if (nmi_watchdog == NMI_LOCAL_APIC) { - if (nmi_watchdog_enabled) - enable_lapic_nmi_watchdog(); - else - disable_lapic_nmi_watchdog(); + if (unknown_nmi_panic) { + if (reserve_lapic_nmi() < 0) { + unknown_nmi_panic = 0; + return -EBUSY; + } else { + set_nmi_callback(unknown_nmi_panic_callback); + } } else { - printk( KERN_WARNING - "NMI watchdog doesn't know what hardware to touch\n"); - return -EIO; + release_lapic_nmi(); + unset_nmi_callback(); } return 0; } @@ -929,12 +659,8 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); -EXPORT_SYMBOL(reserve_perfctr_nmi); -EXPORT_SYMBOL(release_perfctr_nmi); -EXPORT_SYMBOL(reserve_evntsel_nmi); -EXPORT_SYMBOL(release_evntsel_nmi); +EXPORT_SYMBOL(reserve_lapic_nmi); +EXPORT_SYMBOL(release_lapic_nmi); EXPORT_SYMBOL(disable_timer_nmi_watchdog); EXPORT_SYMBOL(enable_timer_nmi_watchdog); EXPORT_SYMBOL(touch_nmi_watchdog); diff --git a/trunk/arch/x86_64/kernel/pci-calgary.c b/trunk/arch/x86_64/kernel/pci-calgary.c index cfb09b07ae99..146924ba5df5 100644 --- a/trunk/arch/x86_64/kernel/pci-calgary.c +++ b/trunk/arch/x86_64/kernel/pci-calgary.c @@ -86,8 +86,7 @@ #define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ #define MAX_NUM_CHASSIS 8 /* max number of chassis */ -/* MAX_PHB_BUS_NUM is the maximal possible dev->bus->number */ -#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) +#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) /* max dev->bus->number */ #define PHBS_PER_CALGARY 4 /* register offsets in Calgary's internal register space */ @@ -112,49 +111,31 @@ static const unsigned long phb_offsets[] = { 0xB000 /* PHB3 */ }; +static char bus_to_phb[MAX_PHB_BUS_NUM]; +void* tce_table_kva[MAX_PHB_BUS_NUM]; unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; static int translate_empty_slots __read_mostly = 0; static int calgary_detected __read_mostly = 0; -struct calgary_bus_info { - void *tce_space; - unsigned char translation_disabled; - signed char phbid; -}; - -static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; +/* + * the bitmap of PHBs the user requested that we disable + * translation on. + */ +static DECLARE_BITMAP(translation_disabled, MAX_PHB_BUS_NUM); static void tce_cache_blast(struct iommu_table *tbl); /* enable this to stress test the chip's TCE cache */ #ifdef CONFIG_IOMMU_DEBUG -int debugging __read_mostly = 1; - -static inline unsigned long verify_bit_range(unsigned long* bitmap, - int expected, unsigned long start, unsigned long end) +static inline void tce_cache_blast_stress(struct iommu_table *tbl) { - unsigned long idx = start; - - BUG_ON(start >= end); - - while (idx < end) { - if (!!test_bit(idx, bitmap) != expected) - return idx; - ++idx; - } - - /* all bits have the expected value */ - return ~0UL; + tce_cache_blast(tbl); } -#else /* debugging is disabled */ -int debugging __read_mostly = 0; - -static inline unsigned long verify_bit_range(unsigned long* bitmap, - int expected, unsigned long start, unsigned long end) +#else +static inline void tce_cache_blast_stress(struct iommu_table *tbl) { - return ~0UL; } -#endif /* CONFIG_IOMMU_DEBUG */ +#endif /* BLAST_TCE_CACHE_ON_UNMAP */ static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen) { @@ -168,7 +149,7 @@ static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen) static inline int translate_phb(struct pci_dev* dev) { - int disabled = bus_info[dev->bus->number].translation_disabled; + int disabled = test_bit(dev->bus->number, translation_disabled); return !disabled; } @@ -177,7 +158,6 @@ static void iommu_range_reserve(struct iommu_table *tbl, { unsigned long index; unsigned long end; - unsigned long badbit; index = start_addr >> PAGE_SHIFT; @@ -189,15 +169,14 @@ static void iommu_range_reserve(struct iommu_table *tbl, if (end > tbl->it_size) /* don't go off the table */ end = tbl->it_size; - badbit = verify_bit_range(tbl->it_map, 0, index, end); - if (badbit != ~0UL) { - if (printk_ratelimit()) + while (index < end) { + if (test_bit(index, tbl->it_map)) printk(KERN_ERR "Calgary: entry already allocated at " "0x%lx tbl %p dma 0x%lx npages %u\n", - badbit, tbl, start_addr, npages); + index, tbl, start_addr, npages); + ++index; } - - set_bit_string(tbl->it_map, index, npages); + set_bit_string(tbl->it_map, start_addr >> PAGE_SHIFT, npages); } static unsigned long iommu_range_alloc(struct iommu_table *tbl, @@ -264,7 +243,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, unsigned int npages) { unsigned long entry; - unsigned long badbit; + unsigned long i; entry = dma_addr >> PAGE_SHIFT; @@ -272,15 +251,16 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, tce_free(tbl, entry, npages); - badbit = verify_bit_range(tbl->it_map, 1, entry, entry + npages); - if (badbit != ~0UL) { - if (printk_ratelimit()) + for (i = 0; i < npages; ++i) { + if (!test_bit(entry + i, tbl->it_map)) printk(KERN_ERR "Calgary: bit is off at 0x%lx " "tbl %p dma 0x%Lx entry 0x%lx npages %u\n", - badbit, tbl, dma_addr, entry, npages); + entry + i, tbl, dma_addr, entry, npages); } __clear_bit_string(tbl->it_map, entry, npages); + + tce_cache_blast_stress(tbl); } static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, @@ -474,7 +454,7 @@ static struct dma_mapping_ops calgary_dma_ops = { static inline int busno_to_phbid(unsigned char num) { - return bus_info[num].phbid; + return bus_to_phb[num]; } static inline unsigned long split_queue_offset(unsigned char num) @@ -651,10 +631,6 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar) if (ret) return ret; - tbl = dev->sysdata; - tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space; - tce_free(tbl, 0, tbl->it_size); - calgary_reserve_regions(dev); /* set TARs for each PHB */ @@ -678,12 +654,11 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar) return 0; } -static void __init calgary_free_bus(struct pci_dev *dev) +static void __init calgary_free_tar(struct pci_dev *dev) { u64 val64; struct iommu_table *tbl = dev->sysdata; void __iomem *target; - unsigned int bitmapsz; target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number)); val64 = be64_to_cpu(readq(target)); @@ -691,15 +666,8 @@ static void __init calgary_free_bus(struct pci_dev *dev) writeq(cpu_to_be64(val64), target); readq(target); /* flush */ - bitmapsz = tbl->it_size / BITS_PER_BYTE; - free_pages((unsigned long)tbl->it_map, get_order(bitmapsz)); - tbl->it_map = NULL; - kfree(tbl); dev->sysdata = NULL; - - /* Can't free bootmem allocated memory after system is up :-( */ - bus_info[dev->bus->number].tce_space = NULL; } static void calgary_watchdog(unsigned long data) @@ -804,11 +772,12 @@ static inline unsigned int __init locate_register_space(struct pci_dev *dev) return address; } -static void __init calgary_init_one_nontraslated(struct pci_dev *dev) +static int __init calgary_init_one_nontraslated(struct pci_dev *dev) { - pci_dev_get(dev); dev->sysdata = NULL; dev->bus->self = dev; + + return 0; } static int __init calgary_init_one(struct pci_dev *dev) @@ -829,7 +798,6 @@ static int __init calgary_init_one(struct pci_dev *dev) if (ret) goto iounmap; - pci_dev_get(dev); dev->bus->self = dev; calgary_enable_translation(dev); @@ -856,9 +824,10 @@ static int __init calgary_init(void) calgary_init_one_nontraslated(dev); continue; } - if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots) + if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) { + pci_dev_put(dev); continue; - + } ret = calgary_init_one(dev); if (ret) goto error; @@ -871,18 +840,15 @@ static int __init calgary_init(void) dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CALGARY, dev); - if (!dev) - break; if (!translate_phb(dev)) { pci_dev_put(dev); continue; } - if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots) + if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) continue; - calgary_disable_translation(dev); - calgary_free_bus(dev); - pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */ + calgary_free_tar(dev); + pci_dev_put(dev); } return ret; @@ -924,15 +890,13 @@ void __init detect_calgary(void) if (swiotlb || no_iommu || iommu_detected) return; - if (!early_pci_allowed()) - return; - specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { int dev; - struct calgary_bus_info *info = &bus_info[bus]; - info->phbid = -1; + + tce_table_kva[bus] = NULL; + bus_to_phb[bus] = -1; if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) continue; @@ -943,9 +907,12 @@ void __init detect_calgary(void) */ phb = (phb + 1) % PHBS_PER_CALGARY; - if (info->translation_disabled) + if (test_bit(bus, translation_disabled)) { + printk(KERN_INFO "Calgary: translation is disabled for " + "PHB 0x%x\n", bus); + /* skip this phb, don't allocate a tbl for it */ continue; - + } /* * Scan the slots of the PCI bus to see if there is a device present. * The parent bus will be the zero-ith device, so start at 1. @@ -956,8 +923,8 @@ void __init detect_calgary(void) tbl = alloc_tce_table(); if (!tbl) goto cleanup; - info->tce_space = tbl; - info->phbid = phb; + tce_table_kva[bus] = tbl; + bus_to_phb[bus] = phb; calgary_found = 1; break; } @@ -967,20 +934,15 @@ void __init detect_calgary(void) if (calgary_found) { iommu_detected = 1; calgary_detected = 1; - printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected.\n"); - printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, " - "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size, - debugging ? "enabled" : "disabled"); + printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected. " + "TCE table spec is %d.\n", specified_table_size); } return; cleanup: - for (--bus; bus >= 0; --bus) { - struct calgary_bus_info *info = &bus_info[bus]; - - if (info->tce_space) - free_tce_table(info->tce_space); - } + for (--bus; bus >= 0; --bus) + if (tce_table_kva[bus]) + free_tce_table(tce_table_kva[bus]); } int __init calgary_iommu_init(void) @@ -1054,7 +1016,7 @@ static int __init calgary_parse_options(char *p) if (bridge < MAX_PHB_BUS_NUM) { printk(KERN_INFO "Calgary: disabling " "translation for PHB 0x%x\n", bridge); - bus_info[bridge].translation_disabled = 1; + set_bit(bridge, translation_disabled); } } diff --git a/trunk/arch/x86_64/kernel/pci-dma.c b/trunk/arch/x86_64/kernel/pci-dma.c index 4dcb671bd19f..9c44f4f2433d 100644 --- a/trunk/arch/x86_64/kernel/pci-dma.c +++ b/trunk/arch/x86_64/kernel/pci-dma.c @@ -236,9 +236,6 @@ __init int iommu_setup(char *p) { iommu_merge = 1; - if (!p) - return -EINVAL; - while (*p) { if (!strncmp(p,"off",3)) no_iommu = 1; @@ -281,9 +278,9 @@ __init int iommu_setup(char *p) if (*p == ',') ++p; } - return 0; + return 1; } -early_param("iommu", iommu_setup); +__setup("iommu=", iommu_setup); void __init pci_iommu_alloc(void) { diff --git a/trunk/arch/x86_64/kernel/pci-gart.c b/trunk/arch/x86_64/kernel/pci-gart.c index 16261a8a3303..6d3e61baf7a0 100644 --- a/trunk/arch/x86_64/kernel/pci-gart.c +++ b/trunk/arch/x86_64/kernel/pci-gart.c @@ -239,6 +239,8 @@ dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir) { unsigned long phys_mem, bus; + BUG_ON(dir == DMA_NONE); + if (!dev) dev = &fallback_dev; @@ -381,6 +383,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) unsigned long pages = 0; int need = 0, nextneed; + BUG_ON(dir == DMA_NONE); if (nents == 0) return 0; diff --git a/trunk/arch/x86_64/kernel/pci-nommu.c b/trunk/arch/x86_64/kernel/pci-nommu.c index df09ab05a1bd..aad7609d8e92 100644 --- a/trunk/arch/x86_64/kernel/pci-nommu.c +++ b/trunk/arch/x86_64/kernel/pci-nommu.c @@ -59,6 +59,7 @@ int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, { int i; + BUG_ON(direction == DMA_NONE); for (i = 0; i < nents; i++ ) { struct scatterlist *s = &sg[i]; BUG_ON(!s->page); diff --git a/trunk/arch/x86_64/kernel/process.c b/trunk/arch/x86_64/kernel/process.c index 458006ae19f3..bb6745d13b8f 100644 --- a/trunk/arch/x86_64/kernel/process.c +++ b/trunk/arch/x86_64/kernel/process.c @@ -80,25 +80,25 @@ void idle_notifier_unregister(struct notifier_block *n) } EXPORT_SYMBOL(idle_notifier_unregister); +enum idle_state { CPU_IDLE, CPU_NOT_IDLE }; +static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE; + void enter_idle(void) { - write_pda(isidle, 1); + __get_cpu_var(idle_state) = CPU_IDLE; atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL); } static void __exit_idle(void) { - if (read_pda(isidle) == 0) - return; - write_pda(isidle, 0); + __get_cpu_var(idle_state) = CPU_NOT_IDLE; atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); } /* Called from interrupts to signify idle end */ void exit_idle(void) { - /* idle loop has pid 0 */ - if (current->pid) + if (current->pid | read_pda(irqcount)) return; __exit_idle(); } @@ -220,9 +220,6 @@ void cpu_idle (void) play_dead(); enter_idle(); idle(); - /* In many cases the interrupt that ended idle - has already called exit_idle. But some idle - loops can be woken up without interrupt. */ __exit_idle(); } @@ -353,7 +350,6 @@ void exit_thread(void) kfree(t->io_bitmap_ptr); t->io_bitmap_ptr = NULL; - clear_thread_flag(TIF_IO_BITMAP); /* * Careful, clear this in the TSS too: */ @@ -373,7 +369,6 @@ void flush_thread(void) if (t->flags & _TIF_IA32) current_thread_info()->status |= TS_COMPAT; } - t->flags &= ~_TIF_DEBUG; tsk->thread.debugreg0 = 0; tsk->thread.debugreg1 = 0; @@ -466,7 +461,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, asm("mov %%es,%0" : "=m" (p->thread.es)); asm("mov %%ds,%0" : "=m" (p->thread.ds)); - if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) { + if (unlikely(me->thread.io_bitmap_ptr != NULL)) { p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); if (!p->thread.io_bitmap_ptr) { p->thread.io_bitmap_max = 0; @@ -474,7 +469,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, } memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr, IO_BITMAP_BYTES); - set_tsk_thread_flag(p, TIF_IO_BITMAP); } /* @@ -504,40 +498,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, */ #define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r) -static inline void __switch_to_xtra(struct task_struct *prev_p, - struct task_struct *next_p, - struct tss_struct *tss) -{ - struct thread_struct *prev, *next; - - prev = &prev_p->thread, - next = &next_p->thread; - - if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { - loaddebug(next, 0); - loaddebug(next, 1); - loaddebug(next, 2); - loaddebug(next, 3); - /* no 4 and 5 */ - loaddebug(next, 6); - loaddebug(next, 7); - } - - if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { - /* - * Copy the relevant range of the IO bitmap. - * Normally this is 128 bytes or less: - */ - memcpy(tss->io_bitmap, next->io_bitmap_ptr, - max(prev->io_bitmap_max, next->io_bitmap_max)); - } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) { - /* - * Clear any possible leftover bits: - */ - memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); - } -} - /* * switch_to(x,y) should switch tasks from x to y. * @@ -555,10 +515,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) int cpu = smp_processor_id(); struct tss_struct *tss = &per_cpu(init_tss, cpu); - /* we're going to use this soon, after a few expensive things */ - if (next_p->fpu_counter>5) - prefetch(&next->i387.fxsave); - /* * Reload esp0, LDT and the page table pointer: */ @@ -627,29 +583,41 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) And the AMD workaround requires it to be after DS reload. */ unlazy_fpu(prev_p); write_pda(kernelstack, - (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); -#ifdef CONFIG_CC_STACKPROTECTOR - write_pda(stack_canary, next_p->stack_canary); - /* - * Build time only check to make sure the stack_canary is at - * offset 40 in the pda; this is a gcc ABI requirement - */ - BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40); -#endif + task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); /* - * Now maybe reload the debug registers and handle I/O bitmaps + * Now maybe reload the debug registers */ - if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW)) - || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) - __switch_to_xtra(prev_p, next_p, tss); + if (unlikely(next->debugreg7)) { + loaddebug(next, 0); + loaddebug(next, 1); + loaddebug(next, 2); + loaddebug(next, 3); + /* no 4 and 5 */ + loaddebug(next, 6); + loaddebug(next, 7); + } + + + /* + * Handle the IO bitmap + */ + if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) { + if (next->io_bitmap_ptr) + /* + * Copy the relevant range of the IO bitmap. + * Normally this is 128 bytes or less: + */ + memcpy(tss->io_bitmap, next->io_bitmap_ptr, + max(prev->io_bitmap_max, next->io_bitmap_max)); + else { + /* + * Clear any possible leftover bits: + */ + memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); + } + } - /* If the task has used fpu the last 5 timeslices, just do a full - * restore of the math state immediately to avoid the trap; the - * chances of needing FPU soon are obviously high now - */ - if (next_p->fpu_counter>5) - math_state_restore(); return prev_p; } @@ -866,7 +834,7 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) unsigned long arch_align_stack(unsigned long sp) { - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + if (randomize_va_space) sp -= get_random_int() % 8192; return sp & ~0xf; } diff --git a/trunk/arch/x86_64/kernel/ptrace.c b/trunk/arch/x86_64/kernel/ptrace.c index addc14af0c56..2d50024c9f30 100644 --- a/trunk/arch/x86_64/kernel/ptrace.c +++ b/trunk/arch/x86_64/kernel/ptrace.c @@ -116,17 +116,17 @@ unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *r return addr; } -static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) +static int is_at_popf(struct task_struct *child, struct pt_regs *regs) { int i, copied; - unsigned char opcode[15]; + unsigned char opcode[16]; unsigned long addr = convert_rip_to_linear(child, regs); copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); for (i = 0; i < copied; i++) { switch (opcode[i]) { - /* popf and iret */ - case 0x9d: case 0xcf: + /* popf */ + case 0x9d: return 1; /* CHECKME: 64 65 */ @@ -138,17 +138,14 @@ static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) case 0x26: case 0x2e: case 0x36: case 0x3e: case 0x64: case 0x65: - case 0xf2: case 0xf3: + case 0xf0: case 0xf2: case 0xf3: continue; + /* REX prefixes */ case 0x40 ... 0x4f: - if (regs->cs != __USER_CS) - /* 32-bit mode: register increment */ - return 0; - /* 64-bit mode: REX prefix */ continue; - /* CHECKME: f2, f3 */ + /* CHECKME: f0, f2, f3 */ /* * pushf: NOTE! We should probably not let @@ -189,8 +186,10 @@ static void set_singlestep(struct task_struct *child) * ..but if TF is changed by the instruction we will trace, * don't mark it as being "us" that set it, so that we * won't clear it by hand later. + * + * AK: this is not enough, LAHF and IRET can change TF in user space too. */ - if (is_setting_trap_flag(child, regs)) + if (is_at_popf(child, regs)) return; child->ptrace |= PT_DTRACE; @@ -421,13 +420,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) if ((0x5554 >> ((data >> (16 + 4*i)) & 0xf)) & 1) break; if (i == 4) { - child->thread.debugreg7 = data; - if (data) - set_tsk_thread_flag(child, TIF_DEBUG); - else - clear_tsk_thread_flag(child, TIF_DEBUG); + child->thread.debugreg7 = data; ret = 0; - } + } break; } break; diff --git a/trunk/arch/x86_64/kernel/relocate_kernel.S b/trunk/arch/x86_64/kernel/relocate_kernel.S index 14e95872c6a3..d24fa9b72a2b 100644 --- a/trunk/arch/x86_64/kernel/relocate_kernel.S +++ b/trunk/arch/x86_64/kernel/relocate_kernel.S @@ -7,169 +7,31 @@ */ #include -#include -#include -/* - * Must be relocatable PIC code callable as a C function - */ - -#define PTR(x) (x << 3) -#define PAGE_ALIGNED (1 << PAGE_SHIFT) -#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */ - - .text - .align PAGE_ALIGNED - .code64 - .globl relocate_kernel -relocate_kernel: - /* %rdi indirection_page - * %rsi page_list - * %rdx start address + /* + * Must be relocatable PIC code callable as a C function, that once + * it starts can not use the previous processes stack. */ - - /* map the control page at its virtual address */ - - movq $0x0000ff8000000000, %r10 /* mask */ - mov $(39 - 3), %cl /* bits to shift */ - movq PTR(VA_CONTROL_PAGE)(%rsi), %r11 /* address to map */ - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PGD)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PUD_0)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PUD_0)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PMD_0)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PMD_0)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PTE_0)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PTE_0)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - /* identity map the control page at its physical address */ - - movq $0x0000ff8000000000, %r10 /* mask */ - mov $(39 - 3), %cl /* bits to shift */ - movq PTR(PA_CONTROL_PAGE)(%rsi), %r11 /* address to map */ - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PGD)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PUD_1)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PUD_1)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PMD_1)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PMD_1)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PTE_1)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PTE_1)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - + .globl relocate_new_kernel + .code64 relocate_new_kernel: - /* %rdi indirection_page - * %rsi page_list + /* %rdi page_list + * %rsi reboot_code_buffer * %rdx start address + * %rcx page_table + * %r8 arg5 + * %r9 arg6 */ /* zero out flags, and disable interrupts */ pushq $0 popfq - /* get physical address of control page now */ - /* this is impossible after page table switch */ - movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 - - /* get physical address of page table now too */ - movq PTR(PA_TABLE_PAGE)(%rsi), %rcx + /* set a new stack at the bottom of our page... */ + lea 4096(%rsi), %rsp - /* switch to new set of page tables */ - movq PTR(PA_PGD)(%rsi), %r9 - movq %r9, %cr3 - - /* setup a new stack at the end of the physical control page */ - lea 4096(%r8), %rsp - - /* jump to identity mapped page */ - addq $(identity_mapped - relocate_kernel), %r8 - pushq %r8 - ret - -identity_mapped: - /* store the start address on the stack */ - pushq %rdx + /* store the parameters back on the stack */ + pushq %rdx /* store the start address */ /* Set cr0 to a known state: * 31 1 == Paging enabled @@ -274,3 +136,8 @@ identity_mapped: xorq %r15, %r15 ret +relocate_new_kernel_end: + + .globl relocate_new_kernel_size +relocate_new_kernel_size: + .quad relocate_new_kernel_end - relocate_new_kernel diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index f98e48cae6da..4b39f0da17f3 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -74,6 +74,16 @@ EXPORT_SYMBOL(boot_cpu_data); unsigned long mmu_cr4_features; +int acpi_disabled; +EXPORT_SYMBOL(acpi_disabled); +#ifdef CONFIG_ACPI +extern int __initdata acpi_ht; +extern acpi_interrupt_flags acpi_sci_flags; +int __initdata acpi_force = 0; +#endif + +int acpi_numa __initdata; + /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; @@ -97,6 +107,7 @@ struct sys_desc_table_struct { struct edid_info edid_info; EXPORT_SYMBOL_GPL(edid_info); +struct e820map e820; extern int root_mountflags; @@ -265,22 +276,185 @@ static void __init probe_roms(void) } } -#ifdef CONFIG_PROC_VMCORE -/* elfcorehdr= specifies the location of elf core header - * stored by the crashed kernel. This option will be passed - * by kexec loader to the capture kernel. - */ -static int __init setup_elfcorehdr(char *arg) +/* Check for full argument with no trailing characters */ +static int fullarg(char *p, char *arg) { - char *end; - if (!arg) - return -EINVAL; - elfcorehdr_addr = memparse(arg, &end); - return end > arg ? 0 : -EINVAL; + int l = strlen(arg); + return !memcmp(p, arg, l) && (p[l] == 0 || isspace(p[l])); } -early_param("elfcorehdr", setup_elfcorehdr); + +static __init void parse_cmdline_early (char ** cmdline_p) +{ + char c = ' ', *to = command_line, *from = COMMAND_LINE; + int len = 0; + int userdef = 0; + + for (;;) { + if (c != ' ') + goto next_char; + +#ifdef CONFIG_SMP + /* + * If the BIOS enumerates physical processors before logical, + * maxcpus=N at enumeration-time can be used to disable HT. + */ + else if (!memcmp(from, "maxcpus=", 8)) { + extern unsigned int maxcpus; + + maxcpus = simple_strtoul(from + 8, NULL, 0); + } +#endif +#ifdef CONFIG_ACPI + /* "acpi=off" disables both ACPI table parsing and interpreter init */ + if (fullarg(from,"acpi=off")) + disable_acpi(); + + if (fullarg(from, "acpi=force")) { + /* add later when we do DMI horrors: */ + acpi_force = 1; + acpi_disabled = 0; + } + + /* acpi=ht just means: do ACPI MADT parsing + at bootup, but don't enable the full ACPI interpreter */ + if (fullarg(from, "acpi=ht")) { + if (!acpi_force) + disable_acpi(); + acpi_ht = 1; + } + else if (fullarg(from, "pci=noacpi")) + acpi_disable_pci(); + else if (fullarg(from, "acpi=noirq")) + acpi_noirq_set(); + + else if (fullarg(from, "acpi_sci=edge")) + acpi_sci_flags.trigger = 1; + else if (fullarg(from, "acpi_sci=level")) + acpi_sci_flags.trigger = 3; + else if (fullarg(from, "acpi_sci=high")) + acpi_sci_flags.polarity = 1; + else if (fullarg(from, "acpi_sci=low")) + acpi_sci_flags.polarity = 3; + + /* acpi=strict disables out-of-spec workarounds */ + else if (fullarg(from, "acpi=strict")) { + acpi_strict = 1; + } +#ifdef CONFIG_X86_IO_APIC + else if (fullarg(from, "acpi_skip_timer_override")) + acpi_skip_timer_override = 1; +#endif +#endif + + if (fullarg(from, "disable_timer_pin_1")) + disable_timer_pin_1 = 1; + if (fullarg(from, "enable_timer_pin_1")) + disable_timer_pin_1 = -1; + + if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) { + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); + disable_apic = 1; + } + + if (fullarg(from, "noapic")) + skip_ioapic_setup = 1; + + if (fullarg(from,"apic")) { + skip_ioapic_setup = 0; + ioapic_force = 1; + } + + if (!memcmp(from, "mem=", 4)) + parse_memopt(from+4, &from); + + if (!memcmp(from, "memmap=", 7)) { + /* exactmap option is for used defined memory */ + if (!memcmp(from+7, "exactmap", 8)) { +#ifdef CONFIG_CRASH_DUMP + /* If we are doing a crash dump, we + * still need to know the real mem + * size before original memory map is + * reset. + */ + saved_max_pfn = e820_end_of_ram(); +#endif + from += 8+7; + end_pfn_map = 0; + e820.nr_map = 0; + userdef = 1; + } + else { + parse_memmapopt(from+7, &from); + userdef = 1; + } + } + +#ifdef CONFIG_NUMA + if (!memcmp(from, "numa=", 5)) + numa_setup(from+5); +#endif + + if (!memcmp(from,"iommu=",6)) { + iommu_setup(from+6); + } + + if (fullarg(from,"oops=panic")) + panic_on_oops = 1; + + if (!memcmp(from, "noexec=", 7)) + nonx_setup(from + 7); + +#ifdef CONFIG_KEXEC + /* crashkernel=size@addr specifies the location to reserve for + * a crash kernel. By reserving this memory we guarantee + * that linux never set's it up as a DMA target. + * Useful for holding code to do something appropriate + * after a kernel panic. + */ + else if (!memcmp(from, "crashkernel=", 12)) { + unsigned long size, base; + size = memparse(from+12, &from); + if (*from == '@') { + base = memparse(from+1, &from); + /* FIXME: Do I want a sanity check + * to validate the memory range? + */ + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + } +#endif + +#ifdef CONFIG_PROC_VMCORE + /* elfcorehdr= specifies the location of elf core header + * stored by the crashed kernel. This option will be passed + * by kexec loader to the capture kernel. + */ + else if(!memcmp(from, "elfcorehdr=", 11)) + elfcorehdr_addr = memparse(from+11, &from); +#endif + +#ifdef CONFIG_HOTPLUG_CPU + else if (!memcmp(from, "additional_cpus=", 16)) + setup_additional_cpus(from+16); #endif + next_char: + c = *(from++); + if (!c) + break; + if (COMMAND_LINE_SIZE <= ++len) + break; + *(to++) = c; + } + if (userdef) { + printk(KERN_INFO "user-defined physical RAM map:\n"); + e820_print_map("user"); + } + *to = '\0'; + *cmdline_p = command_line; +} + #ifndef CONFIG_NUMA static void __init contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) @@ -347,8 +521,6 @@ static void discover_ebda(void) void __init setup_arch(char **cmdline_p) { - printk(KERN_INFO "Command line: %s\n", saved_command_line); - ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); screen_info = SCREEN_INFO; edid_info = EDID_INFO; @@ -375,21 +547,16 @@ void __init setup_arch(char **cmdline_p) data_resource.start = virt_to_phys(&_etext); data_resource.end = virt_to_phys(&_edata)-1; - early_identify_cpu(&boot_cpu_data); - - strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - - parse_early_param(); + parse_cmdline_early(cmdline_p); - finish_e820_parsing(); + early_identify_cpu(&boot_cpu_data); /* * partially used pages are not usable - thus * we are rounding upwards: */ end_pfn = e820_end_of_ram(); - num_physpages = end_pfn; + num_physpages = end_pfn; /* for pfn_valid */ check_efer(); @@ -409,11 +576,6 @@ void __init setup_arch(char **cmdline_p) acpi_boot_table_init(); #endif - /* How many end-of-memory variables you have, grandma! */ - max_low_pfn = end_pfn; - max_pfn = end_pfn; - high_memory = (void *)__va(end_pfn * PAGE_SIZE - 1) + 1; - #ifdef CONFIG_ACPI_NUMA /* * Parse SRAT to discover nodes. @@ -463,10 +625,12 @@ void __init setup_arch(char **cmdline_p) */ acpi_reserve_bootmem(); #endif +#ifdef CONFIG_X86_LOCAL_APIC /* * Find and reserve possible boot-time SMP configuration: */ find_smp_config(); +#endif #ifdef CONFIG_BLK_DEV_INITRD if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) { @@ -493,9 +657,7 @@ void __init setup_arch(char **cmdline_p) paging_init(); -#ifdef CONFIG_PCI - early_quirks(); -#endif + check_ioapic(); /* * set this early, so we dont allocate cpu0 @@ -512,12 +674,14 @@ void __init setup_arch(char **cmdline_p) init_cpu_to_node(); +#ifdef CONFIG_X86_LOCAL_APIC /* * get boot-time SMP configuration: */ if (smp_found_config) get_smp_config(); init_apic_mappings(); +#endif /* * Request address space for all standard RAM and ROM resources @@ -675,7 +839,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) #endif } -static void __cpuinit init_amd(struct cpuinfo_x86 *c) +static void __init init_amd(struct cpuinfo_x86 *c) { unsigned level; @@ -731,12 +895,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) /* Fix cpuid4 emulation for more */ num_cache_leaves = 3; - - /* When there is only one core no need to synchronize RDTSC */ - if (num_possible_cpus() == 1) - set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); - else - clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); } static void __cpuinit detect_ht(struct cpuinfo_x86 *c) @@ -818,7 +976,8 @@ static void srat_detect_node(void) node = first_node(node_online_map); numa_set_node(cpu, node); - printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); + if (acpi_numa > 0) + printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); #endif } @@ -852,8 +1011,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if ((c->x86 == 0xf && c->x86_model >= 0x03) || (c->x86 == 0x6 && c->x86_model >= 0x0e)) set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); - if (c->x86 == 6) - set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); c->x86_max_cores = intel_num_cpu_cores(c); @@ -1072,8 +1229,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* Intel-defined (#2) */ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", - "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, - NULL, NULL, "dca", NULL, NULL, NULL, NULL, NULL, + "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* VIA/Cyrix/Centaur-defined */ diff --git a/trunk/arch/x86_64/kernel/setup64.c b/trunk/arch/x86_64/kernel/setup64.c index 8c4b80fe71a1..417de564456e 100644 --- a/trunk/arch/x86_64/kernel/setup64.c +++ b/trunk/arch/x86_64/kernel/setup64.c @@ -24,7 +24,7 @@ #include #include -char x86_boot_params[BOOT_PARAM_SIZE] __initdata; +char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; @@ -46,10 +46,8 @@ Control non executable mappings for 64bit processes. on Enable(default) off Disable */ -static int __init nonx_setup(char *str) +int __init nonx_setup(char *str) { - if (!str) - return -EINVAL; if (!strncmp(str, "on", 2)) { __supported_pte_mask |= _PAGE_NX; do_not_nx = 0; @@ -57,9 +55,9 @@ static int __init nonx_setup(char *str) do_not_nx = 1; __supported_pte_mask &= ~_PAGE_NX; } - return 0; + return 1; } -early_param("noexec", nonx_setup); +__setup("noexec=", nonx_setup); /* parsed early actually */ int force_personality32 = 0; @@ -95,9 +93,12 @@ void __init setup_per_cpu_areas(void) #endif /* Copy section for each CPU (we discard the original) */ - size = PERCPU_ENOUGH_ROOM; + size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); +#ifdef CONFIG_MODULES + if (size < PERCPU_ENOUGH_ROOM) + size = PERCPU_ENOUGH_ROOM; +#endif - printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", size); for_each_cpu_mask (i, cpu_possible_map) { char *ptr; @@ -121,10 +122,7 @@ void pda_init(int cpu) /* Setup up data that may be needed in __get_free_pages early */ asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); - /* Memory clobbers used to order PDA accessed */ - mb(); wrmsrl(MSR_GS_BASE, pda); - mb(); pda->cpunumber = cpu; pda->irqcount = -1; @@ -180,8 +178,6 @@ void __cpuinit check_efer(void) } } -unsigned long kernel_eflags; - /* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT @@ -239,17 +235,28 @@ void __cpuinit cpu_init (void) * set up and load the per-CPU TSS */ for (v = 0; v < N_EXCEPTION_STACKS; v++) { - static const unsigned int order[N_EXCEPTION_STACKS] = { - [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, - [DEBUG_STACK - 1] = DEBUG_STACK_ORDER - }; if (cpu) { + static const unsigned int order[N_EXCEPTION_STACKS] = { + [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, + [DEBUG_STACK - 1] = DEBUG_STACK_ORDER + }; + estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); if (!estacks) panic("Cannot allocate exception stack %ld %d\n", v, cpu); } - estacks += PAGE_SIZE << order[v]; + switch (v + 1) { +#if DEBUG_STKSZ > EXCEPTION_STKSZ + case DEBUG_STACK: + cpu_pda(cpu)->debugstack = (unsigned long)estacks; + estacks += DEBUG_STKSZ; + break; +#endif + default: + estacks += EXCEPTION_STKSZ; + break; + } orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks; } @@ -283,6 +290,4 @@ void __cpuinit cpu_init (void) set_debugreg(0UL, 7); fpu_init(); - - raw_local_save_flags(kernel_eflags); } diff --git a/trunk/arch/x86_64/kernel/signal.c b/trunk/arch/x86_64/kernel/signal.c index 49ec324cd141..28161170fb0a 100644 --- a/trunk/arch/x86_64/kernel/signal.c +++ b/trunk/arch/x86_64/kernel/signal.c @@ -37,6 +37,37 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, int ia32_setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs); +asmlinkage long +sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) +{ + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&newset, unewset, sizeof(newset))) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); +#ifdef DEBUG_SIG + printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n", + saveset, newset, regs, regs->rip); +#endif + regs->rax = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(regs, &saveset)) + return -EINTR; + } +} + asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, struct pt_regs *regs) @@ -277,6 +308,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, #endif /* Set up registers for signal handler */ + { + struct exec_domain *ed = current_thread_info()->exec_domain; + if (unlikely(ed && ed->signal_invmap && sig < 32)) + sig = ed->signal_invmap[sig]; + } regs->rdi = sig; /* In case the signal handler was declared without prototypes */ regs->rax = 0; @@ -305,11 +341,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif - return 0; + return 1; give_sigsegv: force_sigsegv(sig, current); - return -EFAULT; + return 0; } /* @@ -372,7 +408,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, #endif ret = setup_rt_frame(sig, ka, info, oldset, regs); - if (ret == 0) { + if (ret) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) @@ -389,12 +425,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -static void do_signal(struct pt_regs *regs) +int do_signal(struct pt_regs *regs, sigset_t *oldset) { struct k_sigaction ka; siginfo_t info; int signr; - sigset_t *oldset; /* * We want the common case to go fast, which @@ -403,11 +438,9 @@ static void do_signal(struct pt_regs *regs) * if so. */ if (!user_mode(regs)) - return; + return 1; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else + if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); @@ -421,46 +454,30 @@ static void do_signal(struct pt_regs *regs) set_debugreg(current->thread.debugreg7, 7); /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - clear_thread_flag(TIF_RESTORE_SIGMASK); - } - return; + return handle_signal(signr, &info, &ka, oldset, regs); } /* Did we come from a system call? */ if ((long)regs->orig_rax >= 0) { /* Restart the system call - no handlers present */ long res = regs->rax; - switch (res) { - case -ERESTARTNOHAND: - case -ERESTARTSYS: - case -ERESTARTNOINTR: + if (res == -ERESTARTNOHAND || + res == -ERESTARTSYS || + res == -ERESTARTNOINTR) { regs->rax = regs->orig_rax; regs->rip -= 2; - break; - case -ERESTART_RESTARTBLOCK: + } + if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) { regs->rax = test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall; regs->rip -= 2; - break; } } - - /* if there's no signal to deliver, we just put the saved sigmask - back. */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } + return 0; } -void -do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) +void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_flags) { #ifdef DEBUG_SIG printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx pending:%lx\n", @@ -474,8 +491,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) } /* deal with pending signal delivery */ - if (thread_info_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK)) - do_signal(regs); + if (thread_info_flags & _TIF_SIGPENDING) + do_signal(regs,oldset); } void signal_fault(struct pt_regs *regs, void __user *frame, char *where) diff --git a/trunk/arch/x86_64/kernel/smp.c b/trunk/arch/x86_64/kernel/smp.c index 4f67697f5036..06af6ca60129 100644 --- a/trunk/arch/x86_64/kernel/smp.c +++ b/trunk/arch/x86_64/kernel/smp.c @@ -522,3 +522,26 @@ asmlinkage void smp_call_function_interrupt(void) } } +int safe_smp_processor_id(void) +{ + unsigned apicid, i; + + if (disable_apic) + return 0; + + apicid = hard_smp_processor_id(); + if (apicid < NR_CPUS && x86_cpu_to_apicid[apicid] == apicid) + return apicid; + + for (i = 0; i < NR_CPUS; ++i) { + if (x86_cpu_to_apicid[i] == apicid) + return i; + } + + /* No entries in x86_cpu_to_apicid? Either no MPS|ACPI, + * or called too early. Either way, we must be CPU 0. */ + if (x86_cpu_to_apicid[0] == BAD_APICID) + return 0; + + return 0; /* Should not happen */ +} diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index 7b7a6870288a..3ae9ffddddc0 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -1091,6 +1091,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* * Switch from PIC to APIC mode. */ + connect_bsp_APIC(); setup_local_APIC(); if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) { @@ -1175,9 +1176,12 @@ int __cpuinit __cpu_up(unsigned int cpu) void __init smp_cpus_done(unsigned int max_cpus) { smp_cleanup_boot(); + +#ifdef CONFIG_X86_IO_APIC setup_ioapic_dest(); +#endif + check_nmi_watchdog(); - time_init_gtod(); } #ifdef CONFIG_HOTPLUG_CPU @@ -1230,8 +1234,6 @@ int __cpu_disable(void) if (cpu == 0) return -EBUSY; - if (nmi_watchdog == NMI_LOCAL_APIC) - stop_apic_nmi_watchdog(NULL); clear_local_APIC(); /* @@ -1271,11 +1273,11 @@ void __cpu_die(unsigned int cpu) printk(KERN_ERR "CPU %u didn't die...\n", cpu); } -static __init int setup_additional_cpus(char *s) +__init int setup_additional_cpus(char *s) { - return s && get_option(&s, &additional_cpus) ? 0 : -EINVAL; + return get_option(&s, &additional_cpus); } -early_param("additional_cpus", setup_additional_cpus); +__setup("additional_cpus=", setup_additional_cpus); #else /* ... !CONFIG_HOTPLUG_CPU */ diff --git a/trunk/arch/x86_64/kernel/stacktrace.c b/trunk/arch/x86_64/kernel/stacktrace.c index 6026b31d037e..32cf55eb9af8 100644 --- a/trunk/arch/x86_64/kernel/stacktrace.c +++ b/trunk/arch/x86_64/kernel/stacktrace.c @@ -7,49 +7,215 @@ */ #include #include -#include -#include -static void save_stack_warning(void *data, char *msg) -{ -} +#include -static void -save_stack_warning_symbol(void *data, char *msg, unsigned long symbol) +static inline int +in_range(unsigned long start, unsigned long addr, unsigned long end) { + return addr >= start && addr <= end; } -static int save_stack_stack(void *data, char *name) +static unsigned long +get_stack_end(struct task_struct *task, unsigned long stack) { - struct stack_trace *trace = (struct stack_trace *)data; - return trace->all_contexts ? 0 : -1; + unsigned long stack_start, stack_end, flags; + int i, cpu; + + /* + * The most common case is that we are in the task stack: + */ + stack_start = (unsigned long)task->thread_info; + stack_end = stack_start + THREAD_SIZE; + + if (in_range(stack_start, stack, stack_end)) + return stack_end; + + /* + * We are in an interrupt if irqstackptr is set: + */ + raw_local_irq_save(flags); + cpu = safe_smp_processor_id(); + stack_end = (unsigned long)cpu_pda(cpu)->irqstackptr; + + if (stack_end) { + stack_start = stack_end & ~(IRQSTACKSIZE-1); + if (in_range(stack_start, stack, stack_end)) + goto out_restore; + /* + * We get here if we are in an IRQ context but we + * are also in an exception stack. + */ + } + + /* + * Iterate over all exception stacks, and figure out whether + * 'stack' is in one of them: + */ + for (i = 0; i < N_EXCEPTION_STACKS; i++) { + /* + * set 'end' to the end of the exception stack. + */ + stack_end = per_cpu(init_tss, cpu).ist[i]; + stack_start = stack_end - EXCEPTION_STKSZ; + + /* + * Is 'stack' above this exception frame's end? + * If yes then skip to the next frame. + */ + if (stack >= stack_end) + continue; + /* + * Is 'stack' above this exception frame's start address? + * If yes then we found the right frame. + */ + if (stack >= stack_start) + goto out_restore; + + /* + * If this is a debug stack, and if it has a larger size than + * the usual exception stacks, then 'stack' might still + * be within the lower portion of the debug stack: + */ +#if DEBUG_STKSZ > EXCEPTION_STKSZ + if (i == DEBUG_STACK - 1 && stack >= stack_end - DEBUG_STKSZ) { + /* + * Black magic. A large debug stack is composed of + * multiple exception stack entries, which we + * iterate through now. Dont look: + */ + do { + stack_end -= EXCEPTION_STKSZ; + stack_start -= EXCEPTION_STKSZ; + } while (stack < stack_start); + + goto out_restore; + } +#endif + } + /* + * Ok, 'stack' is not pointing to any of the system stacks. + */ + stack_end = 0; + +out_restore: + raw_local_irq_restore(flags); + + return stack_end; } -static void save_stack_address(void *data, unsigned long addr) + +/* + * Save stack-backtrace addresses into a stack_trace buffer: + */ +static inline unsigned long +save_context_stack(struct stack_trace *trace, unsigned int skip, + unsigned long stack, unsigned long stack_end) { - struct stack_trace *trace = (struct stack_trace *)data; - if (trace->skip > 0) { - trace->skip--; - return; + unsigned long addr; + +#ifdef CONFIG_FRAME_POINTER + unsigned long prev_stack = 0; + + while (in_range(prev_stack, stack, stack_end)) { + pr_debug("stack: %p\n", (void *)stack); + addr = (unsigned long)(((unsigned long *)stack)[1]); + pr_debug("addr: %p\n", (void *)addr); + if (!skip) + trace->entries[trace->nr_entries++] = addr-1; + else + skip--; + if (trace->nr_entries >= trace->max_entries) + break; + if (!addr) + return 0; + /* + * Stack frames must go forwards (otherwise a loop could + * happen if the stackframe is corrupted), so we move + * prev_stack forwards: + */ + prev_stack = stack; + stack = (unsigned long)(((unsigned long *)stack)[0]); } - if (trace->nr_entries < trace->max_entries - 1) - trace->entries[trace->nr_entries++] = addr; + pr_debug("invalid: %p\n", (void *)stack); +#else + while (stack < stack_end) { + addr = ((unsigned long *)stack)[0]; + stack += sizeof(long); + if (__kernel_text_address(addr)) { + if (!skip) + trace->entries[trace->nr_entries++] = addr-1; + else + skip--; + if (trace->nr_entries >= trace->max_entries) + break; + } + } +#endif + return stack; } -static struct stacktrace_ops save_stack_ops = { - .warning = save_stack_warning, - .warning_symbol = save_stack_warning_symbol, - .stack = save_stack_stack, - .address = save_stack_address, -}; +#define MAX_STACKS 10 /* * Save stack-backtrace addresses into a stack_trace buffer. + * If all_contexts is set, all contexts (hardirq, softirq and process) + * are saved. If not set then only the current context is saved. */ -void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +void save_stack_trace(struct stack_trace *trace, + struct task_struct *task, int all_contexts, + unsigned int skip) { - dump_trace(task, NULL, NULL, &save_stack_ops, trace); - trace->entries[trace->nr_entries++] = ULONG_MAX; + unsigned long stack = (unsigned long)&stack; + int i, nr_stacks = 0, stacks_done[MAX_STACKS]; + + WARN_ON(trace->nr_entries || !trace->max_entries); + + if (!task) + task = current; + + pr_debug("task: %p, ti: %p\n", task, task->thread_info); + + if (!task || task == current) { + /* Grab rbp right from our regs: */ + asm ("mov %%rbp, %0" : "=r" (stack)); + pr_debug("rbp: %p\n", (void *)stack); + } else { + /* rbp is the last reg pushed by switch_to(): */ + stack = task->thread.rsp; + pr_debug("other task rsp: %p\n", (void *)stack); + stack = (unsigned long)(((unsigned long *)stack)[0]); + pr_debug("other task rbp: %p\n", (void *)stack); + } + + while (1) { + unsigned long stack_end = get_stack_end(task, stack); + + pr_debug("stack: %p\n", (void *)stack); + pr_debug("stack end: %p\n", (void *)stack_end); + + /* + * Invalid stack addres? + */ + if (!stack_end) + return; + /* + * Were we in this stack already? (recursion) + */ + for (i = 0; i < nr_stacks; i++) + if (stacks_done[i] == stack_end) + return; + stacks_done[nr_stacks] = stack_end; + + stack = save_context_stack(trace, skip, stack, stack_end); + if (!all_contexts || !stack || + trace->nr_entries >= trace->max_entries) + return; + trace->entries[trace->nr_entries++] = ULONG_MAX; + if (trace->nr_entries >= trace->max_entries) + return; + if (++nr_stacks >= MAX_STACKS) + return; + } } -EXPORT_SYMBOL(save_stack_trace); diff --git a/trunk/arch/x86_64/kernel/tce.c b/trunk/arch/x86_64/kernel/tce.c index cbabfdf78e06..5530dda3f27a 100644 --- a/trunk/arch/x86_64/kernel/tce.c +++ b/trunk/arch/x86_64/kernel/tce.c @@ -1,6 +1,4 @@ /* - * This file manages the translation entries for the IBM Calgary IOMMU. - * * Derived from arch/powerpc/platforms/pseries/iommu.c * * Copyright (C) IBM Corporation, 2006 @@ -106,6 +104,14 @@ static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl) /* set the tce table size - measured in entries */ tbl->it_size = table_size_to_number_of_entries(specified_table_size); + tbl->it_base = (unsigned long)tce_table_kva[dev->bus->number]; + if (!tbl->it_base) { + printk(KERN_ERR "Calgary: iommu_table_setparms: " + "no table allocated?!\n"); + ret = -ENOMEM; + goto done; + } + /* * number of bytes needed for the bitmap size in number of * entries; we need one bit per entry @@ -154,6 +160,8 @@ int build_tce_table(struct pci_dev *dev, void __iomem *bbar) if (ret) goto free_tbl; + tce_free(tbl, 0, tbl->it_size); + tbl->bbar = bbar; /* diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index 1c255ee76e7c..7700e6cd2bd9 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include #ifdef CONFIG_ACPI @@ -41,7 +39,9 @@ #include #include #include +#ifdef CONFIG_X86_LOCAL_APIC #include +#endif #ifdef CONFIG_CPU_FREQ static void cpufreq_delayed_get(void); @@ -49,7 +49,7 @@ static void cpufreq_delayed_get(void); extern void i8254_timer_resume(void); extern int using_apic_timer; -static char *timename = NULL; +static char *time_init_gtod(void); DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -187,15 +187,20 @@ unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); - /* Assume the lock function has either no stack frame or a copy - of eflags from PUSHF - Eflags always has bits 22 and up cleared unlike kernel addresses. */ + /* Assume the lock function has either no stack frame or only a single + word. This checks if the address on the stack looks like a kernel + text address. + There is a small window for false hits, but in that case the tick + is just accounted to the spinlock function. + Better would be to write these functions in assembler again + and check exactly. */ if (!user_mode(regs) && in_lock_functions(pc)) { - unsigned long *sp = (unsigned long *)regs->rsp; - if (sp[0] >> 22) - return sp[0]; - if (sp[1] >> 22) - return sp[1]; + char *v = *(char **)regs->rsp; + if ((v >= _stext && v <= _etext) || + (v >= _sinittext && v <= _einittext) || + (v >= (char *)MODULES_VADDR && v <= (char *)MODULES_END)) + return (unsigned long)v; + return ((unsigned long *)regs->rsp)[1]; } return pc; } @@ -276,7 +281,6 @@ static void set_rtc_mmss(unsigned long nowtime) * Note: This function is required to return accurate * time even in the absence of multiple timer ticks. */ -static inline unsigned long long cycles_2_ns(unsigned long long cyc); unsigned long long monotonic_clock(void) { unsigned long seq; @@ -301,7 +305,8 @@ unsigned long long monotonic_clock(void) base = monotonic_base; } while (read_seqretry(&xtime_lock, seq)); this_offset = get_cycles_sync(); - offset = cycles_2_ns(this_offset - last_offset); + /* FIXME: 1000 or 1000000? */ + offset = (this_offset - last_offset)*1000 / cpu_khz; } return base + offset; } @@ -405,7 +410,8 @@ void main_timer_handler(struct pt_regs *regs) offset %= USEC_PER_TICK; } - monotonic_base += cycles_2_ns(tsc - vxtime.last_tsc); + /* FIXME: 1000 or 1000000? */ + monotonic_base += (tsc - vxtime.last_tsc) * 1000000 / cpu_khz; vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot; @@ -435,8 +441,12 @@ void main_timer_handler(struct pt_regs *regs) * have to call the local interrupt handler. */ +#ifndef CONFIG_X86_LOCAL_APIC + profile_tick(CPU_PROFILING, regs); +#else if (!using_apic_timer) smp_local_timer_interrupt(regs); +#endif /* * If we have an externally synchronized Linux clock, then update CMOS clock @@ -460,8 +470,10 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (apic_runs_main_timer > 1) return IRQ_HANDLED; main_timer_handler(regs); +#ifdef CONFIG_X86_LOCAL_APIC if (using_apic_timer) smp_send_timer_broadcast_ipi(); +#endif return IRQ_HANDLED; } @@ -881,17 +893,11 @@ static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL }; -static int __cpuinit -time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu) -{ - unsigned cpu = (unsigned long) hcpu; - if (action == CPU_ONLINE) - vsyscall_set_cpu(cpu); - return NOTIFY_DONE; -} - void __init time_init(void) { + char *timename; + char *gtod; + if (nohpet) vxtime.hpet_address = 0; @@ -925,17 +931,18 @@ void __init time_init(void) } vxtime.mode = VXTIME_TSC; + gtod = time_init_gtod(); + + printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n", + vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod); + printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", + cpu_khz / 1000, cpu_khz % 1000); vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; vxtime.last_tsc = get_cycles_sync(); - set_cyc2ns_scale(cpu_khz); setup_irq(0, &irq0); - hotcpu_notifier(time_cpu_notifier, 0); - time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id()); -#ifndef CONFIG_SMP - time_init_gtod(); -#endif + set_cyc2ns_scale(cpu_khz); } /* @@ -966,18 +973,12 @@ __cpuinit int unsynchronized_tsc(void) /* * Decide what mode gettimeofday should use. */ -void time_init_gtod(void) +__init static char *time_init_gtod(void) { char *timetype; if (unsynchronized_tsc()) notsc = 1; - - if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) - vgetcpu_mode = VGETCPU_RDTSCP; - else - vgetcpu_mode = VGETCPU_LSL; - if (vxtime.hpet_address && notsc) { timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; if (hpet_use_timer) @@ -1000,16 +1001,7 @@ void time_init_gtod(void) timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; vxtime.mode = VXTIME_TSC; } - - printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n", - vxtime_hz / 1000000, vxtime_hz % 1000000, timename, timetype); - printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", - cpu_khz / 1000, cpu_khz % 1000); - vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; - vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; - vxtime.last_tsc = get_cycles_sync(); - - set_cyc2ns_scale(cpu_khz); + return timetype; } __setup("report_lost_ticks", time_setup); @@ -1039,16 +1031,8 @@ static int timer_resume(struct sys_device *dev) unsigned long flags; unsigned long sec; unsigned long ctime = get_cmos_time(); - long sleep_length = (ctime - sleep_start) * HZ; + unsigned long sleep_length = (ctime - sleep_start) * HZ; - if (sleep_length < 0) { - printk(KERN_WARNING "Time skew detected in timer resume!\n"); - /* The time after the resume must not be earlier than the time - * before the suspend or some nasty things will happen - */ - sleep_length = 0; - ctime = sleep_start; - } if (vxtime.hpet_address) hpet_reenable(); else diff --git a/trunk/arch/x86_64/kernel/trampoline.S b/trunk/arch/x86_64/kernel/trampoline.S index c79b99a9e2f6..23a03eb91fc7 100644 --- a/trunk/arch/x86_64/kernel/trampoline.S +++ b/trunk/arch/x86_64/kernel/trampoline.S @@ -64,7 +64,7 @@ idt_48: .word 0, 0 # idt base = 0L gdt_48: - .short GDT_ENTRIES*8 - 1 # gdt limit + .short __KERNEL32_CS + 7 # gdt limit .long cpu_gdt_table-__START_KERNEL_map .globl trampoline_end diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index 01f2a8d254c2..b1249774d1e8 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -45,7 +45,6 @@ #include #include #include -#include asmlinkage void divide_error(void); asmlinkage void debug(void); @@ -143,7 +142,7 @@ void printk_address(unsigned long address) #endif static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, - unsigned *usedp, char **idp) + unsigned *usedp, const char **idp) { static char ids[][8] = { [DEBUG_STACK - 1] = "#DB", @@ -162,7 +161,26 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, * 'stack' is in one of them: */ for (k = 0; k < N_EXCEPTION_STACKS; k++) { - unsigned long end = per_cpu(orig_ist, cpu).ist[k]; + unsigned long end; + + /* + * set 'end' to the end of the exception stack. + */ + switch (k + 1) { + /* + * TODO: this block is not needed i think, because + * setup64.c:cpu_init() sets up t->ist[DEBUG_STACK] + * properly too. + */ +#if DEBUG_STKSZ > EXCEPTION_STKSZ + case DEBUG_STACK: + end = cpu_pda(cpu)->debugstack + DEBUG_STKSZ; + break; +#endif + default: + end = per_cpu(orig_ist, cpu).ist[k]; + break; + } /* * Is 'stack' above this exception frame's end? * If yes then skip to the next frame. @@ -216,19 +234,13 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, return NULL; } -struct ops_and_data { - struct stacktrace_ops *ops; - void *data; -}; - -static int dump_trace_unwind(struct unwind_frame_info *info, void *context) +static int show_trace_unwind(struct unwind_frame_info *info, void *context) { - struct ops_and_data *oad = (struct ops_and_data *)context; int n = 0; while (unwind(info) == 0 && UNW_PC(info)) { n++; - oad->ops->address(oad->data, UNW_PC(info)); + printk_address(UNW_PC(info)); if (arch_unw_user_mode(info)) break; } @@ -242,53 +254,45 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context) * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack */ -void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack, - struct stacktrace_ops *ops, void *data) +void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack) { - const unsigned cpu = smp_processor_id(); + const unsigned cpu = safe_smp_processor_id(); unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; unsigned used = 0; + printk("\nCall Trace:\n"); + if (!tsk) tsk = current; if (call_trace >= 0) { int unw_ret = 0; struct unwind_frame_info info; - struct ops_and_data oad = { .ops = ops, .data = data }; if (regs) { if (unwind_init_frame_info(&info, tsk, regs) == 0) - unw_ret = dump_trace_unwind(&info, &oad); + unw_ret = show_trace_unwind(&info, NULL); } else if (tsk == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad); + unw_ret = unwind_init_running(&info, show_trace_unwind, NULL); else { if (unwind_init_blocked(&info, tsk) == 0) - unw_ret = dump_trace_unwind(&info, &oad); + unw_ret = show_trace_unwind(&info, NULL); } if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n", + print_symbol("DWARF2 unwinder stuck at %s\n", UNW_PC(&info)); if ((long)UNW_SP(&info) < 0) { - ops->warning(data, "Leftover inexact backtrace:\n"); + printk("Leftover inexact backtrace:\n"); stack = (unsigned long *)UNW_SP(&info); - if (!stack) - return; } else - ops->warning(data, "Full inexact backtrace again:\n"); + printk("Full inexact backtrace again:\n"); } else if (call_trace >= 1) return; else - ops->warning(data, "Full inexact backtrace again:\n"); + printk("Full inexact backtrace again:\n"); } else - ops->warning(data, "Inexact backtrace:\n"); - } - if (!stack) { - unsigned long dummy; - stack = &dummy; - if (tsk && tsk != current) - stack = (unsigned long *)tsk->thread.rsp; + printk("Inexact backtrace:\n"); } /* @@ -299,9 +303,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s #define HANDLE_STACK(cond) \ do while (cond) { \ unsigned long addr = *stack++; \ - if (oops_in_progress ? \ - __kernel_text_address(addr) : \ - kernel_text_address(addr)) { \ + if (kernel_text_address(addr)) { \ /* \ * If the address is either in the text segment of the \ * kernel, or in the region which contains vmalloc'ed \ @@ -310,7 +312,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s * down the cause of the crash will be able to figure \ * out the call path that was taken. \ */ \ - ops->address(data, addr); \ + printk_address(addr); \ } \ } while (0) @@ -319,17 +321,16 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s * current stack address. If the stacks consist of nested * exceptions */ - for (;;) { - char *id; + for ( ; ; ) { + const char *id; unsigned long *estack_end; estack_end = in_exception_stack(cpu, (unsigned long)stack, &used, &id); if (estack_end) { - if (ops->stack(data, id) < 0) - break; + printk(" <%s>", id); HANDLE_STACK (stack < estack_end); - ops->stack(data, ""); + printk(" "); /* * We link to the next stack via the * second-to-last pointer (index -2 to end) in the @@ -344,8 +345,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s (IRQSTACKSIZE - 64) / sizeof(*irqstack); if (stack >= irqstack && stack < irqstack_end) { - if (ops->stack(data, "IRQ") < 0) - break; + printk(" "); HANDLE_STACK (stack < irqstack_end); /* * We link to the next stack (which would be @@ -354,7 +354,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s */ stack = (unsigned long *) (irqstack_end[-1]); irqstack_end = NULL; - ops->stack(data, "EOI"); + printk(" "); continue; } } @@ -362,57 +362,19 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s } /* - * This handles the process stack: + * This prints the process stack: */ HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); #undef HANDLE_STACK -} -EXPORT_SYMBOL(dump_trace); - -static void -print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) -{ - print_symbol(msg, symbol); - printk("\n"); -} - -static void print_trace_warning(void *data, char *msg) -{ - printk("%s\n", msg); -} - -static int print_trace_stack(void *data, char *name) -{ - printk(" <%s> ", name); - return 0; -} - -static void print_trace_address(void *data, unsigned long addr) -{ - printk_address(addr); -} - -static struct stacktrace_ops print_trace_ops = { - .warning = print_trace_warning, - .warning_symbol = print_trace_warning_symbol, - .stack = print_trace_stack, - .address = print_trace_address, -}; -void -show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack) -{ - printk("\nCall Trace:\n"); - dump_trace(tsk, regs, stack, &print_trace_ops, NULL); printk("\n"); } -static void -_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp) +static void _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long * rsp) { unsigned long *stack; int i; - const int cpu = smp_processor_id(); + const int cpu = safe_smp_processor_id(); unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr); unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); @@ -466,7 +428,7 @@ void show_registers(struct pt_regs *regs) int i; int in_kernel = !user_mode(regs); unsigned long rsp; - const int cpu = smp_processor_id(); + const int cpu = safe_smp_processor_id(); struct task_struct *cur = cpu_pda(cpu)->pcurrent; rsp = regs->rsp; @@ -541,11 +503,9 @@ static unsigned int die_nest_count; unsigned __kprobes long oops_begin(void) { - int cpu = smp_processor_id(); + int cpu = safe_smp_processor_id(); unsigned long flags; - oops_enter(); - /* racy, but better than risking deadlock. */ local_irq_save(flags); if (!spin_trylock(&die_lock)) { @@ -574,7 +534,6 @@ void __kprobes oops_end(unsigned long flags) spin_unlock_irqrestore(&die_lock, flags); if (panic_on_oops) panic("Fatal exception"); - oops_exit(); } void __kprobes __die(const char * str, struct pt_regs * regs, long err) @@ -611,7 +570,7 @@ void die(const char * str, struct pt_regs * regs, long err) do_exit(SIGSEGV); } -void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic) +void __kprobes die_nmi(char *str, struct pt_regs *regs) { unsigned long flags = oops_begin(); @@ -619,12 +578,13 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic) * We are in trouble anyway, lets at least try * to get a message out. */ - printk(str, smp_processor_id()); + printk(str, safe_smp_processor_id()); show_registers(regs); if (kexec_should_crash(current)) crash_kexec(regs); - if (do_panic || panic_on_oops) - panic("Non maskable interrupt"); + if (panic_on_timeout || panic_on_oops) + panic("nmi watchdog"); + printk("console shuts up ...\n"); oops_end(flags); nmi_exit(); local_irq_enable(); @@ -770,15 +730,8 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, static __kprobes void mem_parity_error(unsigned char reason, struct pt_regs * regs) { - printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", - reason); - printk(KERN_EMERG "You probably have a hardware problem with your " - "RAM chips\n"); - - if (panic_on_unrecovered_nmi) - panic("NMI: Not continuing"); - - printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); + printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n"); + printk("You probably have a hardware problem with your RAM chips\n"); /* Clear and disable the memory parity error line. */ reason = (reason & 0xf) | 4; @@ -801,15 +754,9 @@ io_check_error(unsigned char reason, struct pt_regs * regs) static __kprobes void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) -{ - printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", - reason); - printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); - - if (panic_on_unrecovered_nmi) - panic("NMI: Not continuing"); - - printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); +{ printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); + printk("Dazed and confused, but trying to continue\n"); + printk("Do you have a strange power saving mode enabled?\n"); } /* Runs on IST stack. This code must keep interrupts off all the time. @@ -829,15 +776,17 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs) if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) == NOTIFY_STOP) return; +#ifdef CONFIG_X86_LOCAL_APIC /* * Ok, so this is none of the documented NMI sources, * so it must be the NMI watchdog. */ - if (nmi_watchdog_tick(regs,reason)) + if (nmi_watchdog > 0) { + nmi_watchdog_tick(regs,reason); return; - if (!do_nmi_callback(regs,cpu)) - unknown_nmi_error(reason, regs); - + } +#endif + unknown_nmi_error(reason, regs); return; } if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) @@ -1122,7 +1071,6 @@ asmlinkage void math_state_restore(void) init_fpu(me); restore_fpu_checking(&me->thread.i387.fxsave); task_thread_info(me)->status |= TS_USEDFPU; - me->fpu_counter++; } void __init trap_init(void) @@ -1161,30 +1109,24 @@ void __init trap_init(void) } -static int __init oops_setup(char *s) +/* Actual parsing is done early in setup.c. */ +static int __init oops_dummy(char *s) { - if (!s) - return -EINVAL; - if (!strcmp(s, "panic")) - panic_on_oops = 1; - return 0; + panic_on_oops = 1; + return 1; } -early_param("oops", oops_setup); +__setup("oops=", oops_dummy); static int __init kstack_setup(char *s) { - if (!s) - return -EINVAL; kstack_depth_to_print = simple_strtoul(s,NULL,0); - return 0; + return 1; } -early_param("kstack", kstack_setup); +__setup("kstack=", kstack_setup); #ifdef CONFIG_STACK_UNWIND static int __init call_trace_setup(char *s) { - if (!s) - return -EINVAL; if (strcmp(s, "old") == 0) call_trace = -1; else if (strcmp(s, "both") == 0) @@ -1193,7 +1135,7 @@ static int __init call_trace_setup(char *s) call_trace = 1; else if (strcmp(s, "new") == 0) call_trace = 2; - return 0; + return 1; } -early_param("call_trace", call_trace_setup); +__setup("call_trace=", call_trace_setup); #endif diff --git a/trunk/arch/x86_64/kernel/vmlinux.lds.S b/trunk/arch/x86_64/kernel/vmlinux.lds.S index d0564f1bcb0b..7c4de31471d4 100644 --- a/trunk/arch/x86_64/kernel/vmlinux.lds.S +++ b/trunk/arch/x86_64/kernel/vmlinux.lds.S @@ -13,12 +13,6 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(phys_startup_64) jiffies_64 = jiffies; -PHDRS { - text PT_LOAD FLAGS(5); /* R_E */ - data PT_LOAD FLAGS(7); /* RWE */ - user PT_LOAD FLAGS(7); /* RWE */ - note PT_NOTE FLAGS(4); /* R__ */ -} SECTIONS { . = __START_KERNEL; @@ -37,7 +31,7 @@ SECTIONS KPROBES_TEXT *(.fixup) *(.gnu.warning) - } :text = 0x9090 + } = 0x9090 /* out-of-line lock text */ .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) } @@ -63,7 +57,7 @@ SECTIONS .data : AT(ADDR(.data) - LOAD_OFFSET) { *(.data) CONSTRUCTORS - } :data + } _edata = .; /* End of data section */ @@ -95,7 +89,7 @@ SECTIONS #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) . = VSYSCALL_ADDR; - .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user + .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } __vsyscall_0 = VSYSCALL_VIRT_ADDR; . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); @@ -105,9 +99,6 @@ SECTIONS .vxtime : AT(VLOAD(.vxtime)) { *(.vxtime) } vxtime = VVIRT(.vxtime); - .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) } - vgetcpu_mode = VVIRT(.vgetcpu_mode); - .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) } wall_jiffies = VVIRT(.wall_jiffies); @@ -141,7 +132,7 @@ SECTIONS . = ALIGN(8192); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { *(.data.init_task) - } :data + } . = ALIGN(4096); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { @@ -216,12 +207,14 @@ SECTIONS __initramfs_start = .; .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } __initramfs_end = .; - . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); + /* temporary here to work around NR_CPUS. If you see this comment in 2.6.17+ + complain */ + . = ALIGN(4096); + __init_end = .; + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); __per_cpu_start = .; .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } __per_cpu_end = .; - . = ALIGN(4096); - __init_end = .; . = ALIGN(4096); __nosave_begin = .; diff --git a/trunk/arch/x86_64/kernel/vsmp.c b/trunk/arch/x86_64/kernel/vsmp.c index 044e852bd25e..92f70c74965f 100644 --- a/trunk/arch/x86_64/kernel/vsmp.c +++ b/trunk/arch/x86_64/kernel/vsmp.c @@ -20,9 +20,6 @@ static int __init vsmp_init(void) void *address; unsigned int cap, ctl; - if (!early_pci_allowed()) - return 0; - /* Check if we are running on a ScaleMP vSMP box */ if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) != PCI_VENDOR_ID_SCALEMP) || (read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) != PCI_DEVICE_ID_SCALEMP_VSMP_CTL)) diff --git a/trunk/arch/x86_64/kernel/vsyscall.c b/trunk/arch/x86_64/kernel/vsyscall.c index ac48c3857ddb..f603037df162 100644 --- a/trunk/arch/x86_64/kernel/vsyscall.c +++ b/trunk/arch/x86_64/kernel/vsyscall.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -34,15 +33,11 @@ #include #include #include -#include -#include -#include #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) int __sysctl_vsyscall __section_sysctl_vsyscall = 1; seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED; -int __vgetcpu_mode __section_vgetcpu_mode; #include @@ -77,8 +72,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) __vxtime.tsc_quot) >> 32; /* See comment in x86_64 do_gettimeofday. */ } else { - usec += ((readl((void __iomem *) - fix_to_virt(VSYSCALL_HPET) + 0xf0) - + usec += ((readl((void *)fix_to_virt(VSYSCALL_HPET) + 0xf0) - __vxtime.last) * __vxtime.quot) >> 32; } } while (read_seqretry(&__xtime_lock, sequence)); @@ -133,46 +127,9 @@ time_t __vsyscall(1) vtime(time_t *t) return __xtime.tv_sec; } -/* Fast way to get current CPU and node. - This helps to do per node and per CPU caches in user space. - The result is not guaranteed without CPU affinity, but usually - works out because the scheduler tries to keep a thread on the same - CPU. - - tcache must point to a two element sized long array. - All arguments can be NULL. */ -long __vsyscall(2) -vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) +long __vsyscall(2) venosys_0(void) { - unsigned int dummy, p; - unsigned long j = 0; - - /* Fast cache - only recompute value once per jiffies and avoid - relatively costly rdtscp/cpuid otherwise. - This works because the scheduler usually keeps the process - on the same CPU and this syscall doesn't guarantee its - results anyways. - We do this here because otherwise user space would do it on - its own in a likely inferior way (no access to jiffies). - If you don't like it pass NULL. */ - if (tcache && tcache->t0 == (j = __jiffies)) { - p = tcache->t1; - } else if (__vgetcpu_mode == VGETCPU_RDTSCP) { - /* Load per CPU data from RDTSCP */ - rdtscp(dummy, dummy, p); - } else { - /* Load per CPU data from GDT */ - asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); - } - if (tcache) { - tcache->t0 = j; - tcache->t1 = p; - } - if (cpu) - *cpu = p & 0xfff; - if (node) - *node = p >> 12; - return 0; + return -ENOSYS; } long __vsyscall(3) venosys_1(void) @@ -192,8 +149,7 @@ static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos) { extern u16 vsysc1, vsysc2; - u16 __iomem *map1; - u16 __iomem *map2; + u16 *map1, *map2; int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); if (!write) return ret; @@ -208,11 +164,11 @@ static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, goto out; } if (!sysctl_vsyscall) { - writew(SYSCALL, map1); - writew(SYSCALL, map2); + *map1 = SYSCALL; + *map2 = SYSCALL; } else { - writew(NOP2, map1); - writew(NOP2, map2); + *map1 = NOP2; + *map2 = NOP2; } iounmap(map2); out: @@ -244,43 +200,6 @@ static ctl_table kernel_root_table2[] = { #endif -static void __cpuinit write_rdtscp_cb(void *info) -{ - write_rdtscp_aux((unsigned long)info); -} - -void __cpuinit vsyscall_set_cpu(int cpu) -{ - unsigned long *d; - unsigned long node = 0; -#ifdef CONFIG_NUMA - node = cpu_to_node[cpu]; -#endif - if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) { - void *info = (void *)((node << 12) | cpu); - /* Can happen on preemptive kernel */ - if (get_cpu() == cpu) - write_rdtscp_cb(info); -#ifdef CONFIG_SMP - else { - /* the notifier is unfortunately not executed on the - target CPU */ - smp_call_function_single(cpu,write_rdtscp_cb,info,0,1); - } -#endif - put_cpu(); - } - - /* Store cpu number in limit so that it can be loaded quickly - in user space in vgetcpu. - 12 bits for the CPU and 8 bits for the node. */ - d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU); - *d = 0x0f40000000000ULL; - *d |= cpu; - *d |= (node & 0xf) << 12; - *d |= (node >> 4) << 48; -} - static void __init map_vsyscall(void) { extern char __vsyscall_0; @@ -295,7 +214,6 @@ static int __init vsyscall_init(void) VSYSCALL_ADDR(__NR_vgettimeofday))); BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); - BUG_ON((unsigned long) &vgetcpu != VSYSCALL_ADDR(__NR_vgetcpu)); map_vsyscall(); #ifdef CONFIG_SYSCTL register_sysctl_table(kernel_root_table2, 0); diff --git a/trunk/arch/x86_64/kernel/x8664_ksyms.c b/trunk/arch/x86_64/kernel/x8664_ksyms.c index c3454af5e3a2..370952c4ff22 100644 --- a/trunk/arch/x86_64/kernel/x8664_ksyms.c +++ b/trunk/arch/x86_64/kernel/x8664_ksyms.c @@ -29,7 +29,6 @@ EXPORT_SYMBOL(__put_user_8); EXPORT_SYMBOL(copy_user_generic); EXPORT_SYMBOL(copy_from_user); EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(__copy_from_user_inatomic); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(clear_page); diff --git a/trunk/arch/x86_64/lib/Makefile b/trunk/arch/x86_64/lib/Makefile index b78d4170fce2..ccef6ae747a3 100644 --- a/trunk/arch/x86_64/lib/Makefile +++ b/trunk/arch/x86_64/lib/Makefile @@ -9,4 +9,4 @@ obj-y := io.o iomap_copy.o lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ usercopy.o getuser.o putuser.o \ thunk.o clear_page.o copy_page.o bitstr.o bitops.o -lib-y += memcpy.o memmove.o memset.o copy_user.o rwlock.o +lib-y += memcpy.o memmove.o memset.o copy_user.o diff --git a/trunk/arch/x86_64/lib/clear_page.S b/trunk/arch/x86_64/lib/clear_page.S index 9a10a78bb4a4..1f81b79b796c 100644 --- a/trunk/arch/x86_64/lib/clear_page.S +++ b/trunk/arch/x86_64/lib/clear_page.S @@ -1,22 +1,10 @@ -#include -#include - /* * Zero a page. * rdi page */ - ALIGN -clear_page_c: - CFI_STARTPROC - movl $4096/8,%ecx - xorl %eax,%eax - rep stosq - ret - CFI_ENDPROC -ENDPROC(clear_page) - -ENTRY(clear_page) - CFI_STARTPROC + .globl clear_page + .p2align 4 +clear_page: xorl %eax,%eax movl $4096/64,%ecx .p2align 4 @@ -35,25 +23,28 @@ ENTRY(clear_page) jnz .Lloop nop ret - CFI_ENDPROC -.Lclear_page_end: -ENDPROC(clear_page) +clear_page_end: /* Some CPUs run faster using the string instructions. It is also a lot simpler. Use this when possible */ #include - .section .altinstr_replacement,"ax" -1: .byte 0xeb /* jmp */ - .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */ -2: - .previous .section .altinstructions,"a" .align 8 - .quad clear_page - .quad 1b - .byte X86_FEATURE_REP_GOOD - .byte .Lclear_page_end - clear_page - .byte 2b - 1b + .quad clear_page + .quad clear_page_c + .byte X86_FEATURE_REP_GOOD + .byte clear_page_end-clear_page + .byte clear_page_c_end-clear_page_c + .previous + + .section .altinstr_replacement,"ax" +clear_page_c: + movl $4096/8,%ecx + xorl %eax,%eax + rep + stosq + ret +clear_page_c_end: .previous diff --git a/trunk/arch/x86_64/lib/copy_page.S b/trunk/arch/x86_64/lib/copy_page.S index 0ebb03b60e79..8fa19d96a7ee 100644 --- a/trunk/arch/x86_64/lib/copy_page.S +++ b/trunk/arch/x86_64/lib/copy_page.S @@ -1,33 +1,17 @@ /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ -#include -#include -#include - - ALIGN -copy_page_c: - CFI_STARTPROC - movl $4096/8,%ecx - rep movsq - ret - CFI_ENDPROC -ENDPROC(copy_page_c) - /* Don't use streaming store because it's better when the target ends up in cache. */ /* Could vary the prefetch distance based on SMP/UP */ -ENTRY(copy_page) - CFI_STARTPROC + .globl copy_page + .p2align 4 +copy_page: subq $3*8,%rsp - CFI_ADJUST_CFA_OFFSET 3*8 movq %rbx,(%rsp) - CFI_REL_OFFSET rbx, 0 movq %r12,1*8(%rsp) - CFI_REL_OFFSET r12, 1*8 movq %r13,2*8(%rsp) - CFI_REL_OFFSET r13, 2*8 movl $(4096/64)-5,%ecx .p2align 4 @@ -88,33 +72,30 @@ ENTRY(copy_page) jnz .Loop2 movq (%rsp),%rbx - CFI_RESTORE rbx movq 1*8(%rsp),%r12 - CFI_RESTORE r12 movq 2*8(%rsp),%r13 - CFI_RESTORE r13 addq $3*8,%rsp - CFI_ADJUST_CFA_OFFSET -3*8 ret -.Lcopy_page_end: - CFI_ENDPROC -ENDPROC(copy_page) /* Some CPUs run faster using the string copy instructions. It is also a lot simpler. Use this when possible */ #include - .section .altinstr_replacement,"ax" -1: .byte 0xeb /* jmp */ - .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */ -2: - .previous .section .altinstructions,"a" .align 8 - .quad copy_page - .quad 1b - .byte X86_FEATURE_REP_GOOD - .byte .Lcopy_page_end - copy_page - .byte 2b - 1b + .quad copy_page + .quad copy_page_c + .byte X86_FEATURE_REP_GOOD + .byte copy_page_c_end-copy_page_c + .byte copy_page_c_end-copy_page_c + .previous + + .section .altinstr_replacement,"ax" +copy_page_c: + movl $4096/8,%ecx + rep + movsq + ret +copy_page_c_end: .previous diff --git a/trunk/arch/x86_64/lib/copy_user.S b/trunk/arch/x86_64/lib/copy_user.S index 70bebd310408..f64569b83b54 100644 --- a/trunk/arch/x86_64/lib/copy_user.S +++ b/trunk/arch/x86_64/lib/copy_user.S @@ -4,78 +4,56 @@ * Functions to copy from and to user space. */ -#include -#include - #define FIX_ALIGNMENT 1 -#include -#include -#include -#include + #include + #include + #include + #include - .macro ALTERNATIVE_JUMP feature,orig,alt -0: +/* Standard copy_to_user with segment limit checking */ + .globl copy_to_user + .p2align 4 +copy_to_user: + GET_THREAD_INFO(%rax) + movq %rdi,%rcx + addq %rdx,%rcx + jc bad_to_user + cmpq threadinfo_addr_limit(%rax),%rcx + jae bad_to_user +2: .byte 0xe9 /* 32bit jump */ - .long \orig-1f /* by default jump to orig */ + .long .Lcug-1f 1: + .section .altinstr_replacement,"ax" -2: .byte 0xe9 /* near jump with 32bit immediate */ - .long \alt-1b /* offset */ /* or alternatively to alt */ +3: .byte 0xe9 /* replacement jmp with 8 bit immediate */ + .long copy_user_generic_c-1b /* offset */ .previous .section .altinstructions,"a" .align 8 - .quad 0b .quad 2b - .byte \feature /* when feature is set */ + .quad 3b + .byte X86_FEATURE_REP_GOOD .byte 5 .byte 5 .previous - .endm - -/* Standard copy_to_user with segment limit checking */ -ENTRY(copy_to_user) - CFI_STARTPROC - GET_THREAD_INFO(%rax) - movq %rdi,%rcx - addq %rdx,%rcx - jc bad_to_user - cmpq threadinfo_addr_limit(%rax),%rcx - jae bad_to_user - xorl %eax,%eax /* clear zero flag */ - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string - CFI_ENDPROC - -ENTRY(copy_user_generic) - CFI_STARTPROC - movl $1,%ecx /* set zero flag */ - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string - CFI_ENDPROC - -ENTRY(__copy_from_user_inatomic) - CFI_STARTPROC - xorl %ecx,%ecx /* clear zero flag */ - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string - CFI_ENDPROC /* Standard copy_from_user with segment limit checking */ -ENTRY(copy_from_user) - CFI_STARTPROC + .globl copy_from_user + .p2align 4 +copy_from_user: GET_THREAD_INFO(%rax) movq %rsi,%rcx addq %rdx,%rcx jc bad_from_user cmpq threadinfo_addr_limit(%rax),%rcx jae bad_from_user - movl $1,%ecx /* set zero flag */ - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string - CFI_ENDPROC -ENDPROC(copy_from_user) + /* FALL THROUGH to copy_user_generic */ .section .fixup,"ax" /* must zero dest */ bad_from_user: - CFI_STARTPROC movl %edx,%ecx xorl %eax,%eax rep @@ -83,32 +61,40 @@ bad_from_user: bad_to_user: movl %edx,%eax ret - CFI_ENDPROC -END(bad_from_user) .previous /* - * copy_user_generic_unrolled - memory copy with exception handling. - * This version is for CPUs like P4 that don't have efficient micro code for rep movsq + * copy_user_generic - memory copy with exception handling. * * Input: * rdi destination * rsi source * rdx count - * ecx zero flag -- if true zero destination on error * * Output: * eax uncopied bytes or 0 if successful. */ -ENTRY(copy_user_generic_unrolled) - CFI_STARTPROC + .globl copy_user_generic + .p2align 4 +copy_user_generic: + .byte 0x66,0x66,0x90 /* 5 byte nop for replacement jump */ + .byte 0x66,0x90 +1: + .section .altinstr_replacement,"ax" +2: .byte 0xe9 /* near jump with 32bit immediate */ + .long copy_user_generic_c-1b /* offset */ + .previous + .section .altinstructions,"a" + .align 8 + .quad copy_user_generic + .quad 2b + .byte X86_FEATURE_REP_GOOD + .byte 5 + .byte 5 + .previous +.Lcug: pushq %rbx - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rbx, 0 - pushq %rcx - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rcx, 0 xorl %eax,%eax /*zero for the exception handler */ #ifdef FIX_ALIGNMENT @@ -182,16 +168,9 @@ ENTRY(copy_user_generic_unrolled) decl %ecx jnz .Lloop_1 - CFI_REMEMBER_STATE .Lende: - popq %rcx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE rcx popq %rbx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE rbx ret - CFI_RESTORE_STATE #ifdef FIX_ALIGNMENT /* align destination */ @@ -273,8 +252,6 @@ ENTRY(copy_user_generic_unrolled) addl %ecx,%edx /* edx: bytes to zero, rdi: dest, eax:zero */ .Lzero_rest: - cmpl $0,(%rsp) - jz .Le_zero movq %rdx,%rcx .Le_byte: xorl %eax,%eax @@ -284,9 +261,6 @@ ENTRY(copy_user_generic_unrolled) .Le_zero: movq %rdx,%rax jmp .Lende - CFI_ENDPROC -ENDPROC(copy_user_generic) - /* Some CPUs run faster using the string copy instructions. This is also a lot simpler. Use them when possible. @@ -296,7 +270,6 @@ ENDPROC(copy_user_generic) /* rdi destination * rsi source * rdx count - * ecx zero flag * * Output: * eax uncopied bytes or 0 if successfull. @@ -307,48 +280,22 @@ ENDPROC(copy_user_generic) * And more would be dangerous because both Intel and AMD have * errata with rep movsq > 4GB. If someone feels the need to fix * this please consider this. - */ -ENTRY(copy_user_generic_string) - CFI_STARTPROC - movl %ecx,%r8d /* save zero flag */ + */ +copy_user_generic_c: movl %edx,%ecx shrl $3,%ecx andl $7,%edx - jz 10f 1: rep movsq movl %edx,%ecx 2: rep movsb -9: movl %ecx,%eax +4: movl %ecx,%eax ret - - /* multiple of 8 byte */ -10: rep - movsq - xor %eax,%eax +3: lea (%rdx,%rcx,8),%rax ret - /* exception handling */ -3: lea (%rdx,%rcx,8),%rax /* exception on quad loop */ - jmp 6f -5: movl %ecx,%eax /* exception on byte loop */ - /* eax: left over bytes */ -6: testl %r8d,%r8d /* zero flag set? */ - jz 7f - movl %eax,%ecx /* initialize x86 loop counter */ - push %rax - xorl %eax,%eax -8: rep - stosb /* zero the rest */ -11: pop %rax -7: ret - CFI_ENDPROC -END(copy_user_generic_c) - .section __ex_table,"a" .quad 1b,3b - .quad 2b,5b - .quad 8b,11b - .quad 10b,3b + .quad 2b,4b .previous diff --git a/trunk/arch/x86_64/lib/csum-copy.S b/trunk/arch/x86_64/lib/csum-copy.S index f0dba36578ea..72fd55ee896e 100644 --- a/trunk/arch/x86_64/lib/csum-copy.S +++ b/trunk/arch/x86_64/lib/csum-copy.S @@ -5,9 +5,8 @@ * License. See the file COPYING in the main directory of this archive * for more details. No warranty for anything given at all. */ -#include -#include -#include + #include + #include /* * Checksum copy with exception handling. @@ -54,24 +53,19 @@ .endm -ENTRY(csum_partial_copy_generic) - CFI_STARTPROC + .globl csum_partial_copy_generic + .p2align 4 +csum_partial_copy_generic: cmpl $3*64,%edx jle .Lignore .Lignore: subq $7*8,%rsp - CFI_ADJUST_CFA_OFFSET 7*8 movq %rbx,2*8(%rsp) - CFI_REL_OFFSET rbx, 2*8 movq %r12,3*8(%rsp) - CFI_REL_OFFSET r12, 3*8 movq %r14,4*8(%rsp) - CFI_REL_OFFSET r14, 4*8 movq %r13,5*8(%rsp) - CFI_REL_OFFSET r13, 5*8 movq %rbp,6*8(%rsp) - CFI_REL_OFFSET rbp, 6*8 movq %r8,(%rsp) movq %r9,1*8(%rsp) @@ -214,22 +208,14 @@ ENTRY(csum_partial_copy_generic) addl %ebx,%eax adcl %r9d,%eax /* carry */ - CFI_REMEMBER_STATE .Lende: movq 2*8(%rsp),%rbx - CFI_RESTORE rbx movq 3*8(%rsp),%r12 - CFI_RESTORE r12 movq 4*8(%rsp),%r14 - CFI_RESTORE r14 movq 5*8(%rsp),%r13 - CFI_RESTORE r13 movq 6*8(%rsp),%rbp - CFI_RESTORE rbp addq $7*8,%rsp - CFI_ADJUST_CFA_OFFSET -7*8 ret - CFI_RESTORE_STATE /* Exception handlers. Very simple, zeroing is done in the wrappers */ .Lbad_source: @@ -245,5 +231,3 @@ ENTRY(csum_partial_copy_generic) jz .Lende movl $-EFAULT,(%rax) jmp .Lende - CFI_ENDPROC -ENDPROC(csum_partial_copy_generic) diff --git a/trunk/arch/x86_64/lib/getuser.S b/trunk/arch/x86_64/lib/getuser.S index 5448876261f8..3844d5e885a4 100644 --- a/trunk/arch/x86_64/lib/getuser.S +++ b/trunk/arch/x86_64/lib/getuser.S @@ -27,26 +27,25 @@ */ #include -#include #include #include #include #include .text -ENTRY(__get_user_1) - CFI_STARTPROC + .p2align 4 +.globl __get_user_1 +__get_user_1: GET_THREAD_INFO(%r8) cmpq threadinfo_addr_limit(%r8),%rcx jae bad_get_user 1: movzb (%rcx),%edx xorl %eax,%eax ret - CFI_ENDPROC -ENDPROC(__get_user_1) -ENTRY(__get_user_2) - CFI_STARTPROC + .p2align 4 +.globl __get_user_2 +__get_user_2: GET_THREAD_INFO(%r8) addq $1,%rcx jc 20f @@ -58,11 +57,10 @@ ENTRY(__get_user_2) ret 20: decq %rcx jmp bad_get_user - CFI_ENDPROC -ENDPROC(__get_user_2) -ENTRY(__get_user_4) - CFI_STARTPROC + .p2align 4 +.globl __get_user_4 +__get_user_4: GET_THREAD_INFO(%r8) addq $3,%rcx jc 30f @@ -74,11 +72,10 @@ ENTRY(__get_user_4) ret 30: subq $3,%rcx jmp bad_get_user - CFI_ENDPROC -ENDPROC(__get_user_4) -ENTRY(__get_user_8) - CFI_STARTPROC + .p2align 4 +.globl __get_user_8 +__get_user_8: GET_THREAD_INFO(%r8) addq $7,%rcx jc 40f @@ -90,16 +87,11 @@ ENTRY(__get_user_8) ret 40: subq $7,%rcx jmp bad_get_user - CFI_ENDPROC -ENDPROC(__get_user_8) bad_get_user: - CFI_STARTPROC xorl %edx,%edx movq $(-EFAULT),%rax ret - CFI_ENDPROC -END(bad_get_user) .section __ex_table,"a" .quad 1b,bad_get_user diff --git a/trunk/arch/x86_64/lib/iomap_copy.S b/trunk/arch/x86_64/lib/iomap_copy.S index 05a95e713da8..8bbade5fea05 100644 --- a/trunk/arch/x86_64/lib/iomap_copy.S +++ b/trunk/arch/x86_64/lib/iomap_copy.S @@ -15,16 +15,12 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include -#include - /* * override generic version in lib/iomap_copy.c */ -ENTRY(__iowrite32_copy) - CFI_STARTPROC + .globl __iowrite32_copy + .p2align 4 +__iowrite32_copy: movl %edx,%ecx rep movsd ret - CFI_ENDPROC -ENDPROC(__iowrite32_copy) diff --git a/trunk/arch/x86_64/lib/memcpy.S b/trunk/arch/x86_64/lib/memcpy.S index 967b22fa7d07..5554948b5554 100644 --- a/trunk/arch/x86_64/lib/memcpy.S +++ b/trunk/arch/x86_64/lib/memcpy.S @@ -1,10 +1,6 @@ /* Copyright 2002 Andi Kleen */ -#include -#include -#include -#include - + #include /* * memcpy - Copy a memory block. * @@ -17,26 +13,12 @@ * rax original destination */ - ALIGN -memcpy_c: - CFI_STARTPROC - movq %rdi,%rax - movl %edx,%ecx - shrl $3,%ecx - andl $7,%edx - rep movsq - movl %edx,%ecx - rep movsb - ret - CFI_ENDPROC -ENDPROC(memcpy_c) - -ENTRY(__memcpy) -ENTRY(memcpy) - CFI_STARTPROC + .globl __memcpy + .globl memcpy + .p2align 4 +__memcpy: +memcpy: pushq %rbx - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rbx, 0 movq %rdi,%rax movl %edx,%ecx @@ -104,27 +86,36 @@ ENTRY(memcpy) .Lende: popq %rbx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE rbx ret .Lfinal: - CFI_ENDPROC -ENDPROC(memcpy) -ENDPROC(__memcpy) /* Some CPUs run faster using the string copy instructions. It is also a lot simpler. Use this when possible */ - .section .altinstr_replacement,"ax" -1: .byte 0xeb /* jmp */ - .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */ -2: - .previous .section .altinstructions,"a" .align 8 - .quad memcpy - .quad 1b - .byte X86_FEATURE_REP_GOOD - .byte .Lfinal - memcpy - .byte 2b - 1b + .quad memcpy + .quad memcpy_c + .byte X86_FEATURE_REP_GOOD + .byte .Lfinal-memcpy + .byte memcpy_c_end-memcpy_c + .previous + + .section .altinstr_replacement,"ax" + /* rdi destination + * rsi source + * rdx count + */ +memcpy_c: + movq %rdi,%rax + movl %edx,%ecx + shrl $3,%ecx + andl $7,%edx + rep + movsq + movl %edx,%ecx + rep + movsb + ret +memcpy_c_end: .previous diff --git a/trunk/arch/x86_64/lib/memset.S b/trunk/arch/x86_64/lib/memset.S index 09ed1f6b0eaa..ad397f2c7de8 100644 --- a/trunk/arch/x86_64/lib/memset.S +++ b/trunk/arch/x86_64/lib/memset.S @@ -1,9 +1,4 @@ /* Copyright 2002 Andi Kleen, SuSE Labs */ - -#include -#include -#include - /* * ISO C memset - set a memory block to a byte value. * @@ -13,29 +8,11 @@ * * rax original destination */ - ALIGN -memset_c: - CFI_STARTPROC - movq %rdi,%r9 - movl %edx,%r8d - andl $7,%r8d - movl %edx,%ecx - shrl $3,%ecx - /* expand byte value */ - movzbl %sil,%esi - movabs $0x0101010101010101,%rax - mulq %rsi /* with rax, clobbers rdx */ - rep stosq - movl %r8d,%ecx - rep stosb - movq %r9,%rax - ret - CFI_ENDPROC -ENDPROC(memset_c) - -ENTRY(memset) -ENTRY(__memset) - CFI_STARTPROC + .globl __memset + .globl memset + .p2align 4 +memset: +__memset: movq %rdi,%r10 movq %rdx,%r11 @@ -48,7 +25,6 @@ ENTRY(__memset) movl %edi,%r9d andl $7,%r9d jnz .Lbad_alignment - CFI_REMEMBER_STATE .Lafter_bad_alignment: movl %r11d,%ecx @@ -99,7 +75,6 @@ ENTRY(__memset) movq %r10,%rax ret - CFI_RESTORE_STATE .Lbad_alignment: cmpq $7,%r11 jbe .Lhandle_7 @@ -109,26 +84,42 @@ ENTRY(__memset) addq %r8,%rdi subq %r8,%r11 jmp .Lafter_bad_alignment -.Lfinal: - CFI_ENDPROC -ENDPROC(memset) -ENDPROC(__memset) /* Some CPUs run faster using the string instructions. It is also a lot simpler. Use this when possible */ #include - .section .altinstr_replacement,"ax" -1: .byte 0xeb /* jmp */ - .byte (memset_c - memset) - (2f - 1b) /* offset */ -2: - .previous .section .altinstructions,"a" .align 8 - .quad memset - .quad 1b - .byte X86_FEATURE_REP_GOOD - .byte .Lfinal - memset - .byte 2b - 1b + .quad memset + .quad memset_c + .byte X86_FEATURE_REP_GOOD + .byte memset_c_end-memset_c + .byte memset_c_end-memset_c + .previous + + .section .altinstr_replacement,"ax" + /* rdi destination + * rsi value + * rdx count + */ +memset_c: + movq %rdi,%r9 + movl %edx,%r8d + andl $7,%r8d + movl %edx,%ecx + shrl $3,%ecx + /* expand byte value */ + movzbl %sil,%esi + movabs $0x0101010101010101,%rax + mulq %rsi /* with rax, clobbers rdx */ + rep + stosq + movl %r8d,%ecx + rep + stosb + movq %r9,%rax + ret +memset_c_end: .previous diff --git a/trunk/arch/x86_64/lib/putuser.S b/trunk/arch/x86_64/lib/putuser.S index 4989f5a8fa9b..7f5593974e2d 100644 --- a/trunk/arch/x86_64/lib/putuser.S +++ b/trunk/arch/x86_64/lib/putuser.S @@ -25,26 +25,25 @@ */ #include -#include #include #include #include #include .text -ENTRY(__put_user_1) - CFI_STARTPROC + .p2align 4 +.globl __put_user_1 +__put_user_1: GET_THREAD_INFO(%r8) cmpq threadinfo_addr_limit(%r8),%rcx jae bad_put_user 1: movb %dl,(%rcx) xorl %eax,%eax ret - CFI_ENDPROC -ENDPROC(__put_user_1) -ENTRY(__put_user_2) - CFI_STARTPROC + .p2align 4 +.globl __put_user_2 +__put_user_2: GET_THREAD_INFO(%r8) addq $1,%rcx jc 20f @@ -56,11 +55,10 @@ ENTRY(__put_user_2) ret 20: decq %rcx jmp bad_put_user - CFI_ENDPROC -ENDPROC(__put_user_2) -ENTRY(__put_user_4) - CFI_STARTPROC + .p2align 4 +.globl __put_user_4 +__put_user_4: GET_THREAD_INFO(%r8) addq $3,%rcx jc 30f @@ -72,11 +70,10 @@ ENTRY(__put_user_4) ret 30: subq $3,%rcx jmp bad_put_user - CFI_ENDPROC -ENDPROC(__put_user_4) -ENTRY(__put_user_8) - CFI_STARTPROC + .p2align 4 +.globl __put_user_8 +__put_user_8: GET_THREAD_INFO(%r8) addq $7,%rcx jc 40f @@ -88,15 +85,10 @@ ENTRY(__put_user_8) ret 40: subq $7,%rcx jmp bad_put_user - CFI_ENDPROC -ENDPROC(__put_user_8) bad_put_user: - CFI_STARTPROC movq $(-EFAULT),%rax ret - CFI_ENDPROC -END(bad_put_user) .section __ex_table,"a" .quad 1b,bad_put_user diff --git a/trunk/arch/x86_64/lib/rwlock.S b/trunk/arch/x86_64/lib/rwlock.S deleted file mode 100644 index 0cde1f807314..000000000000 --- a/trunk/arch/x86_64/lib/rwlock.S +++ /dev/null @@ -1,38 +0,0 @@ -/* Slow paths of read/write spinlocks. */ - -#include -#include -#include -#include - -/* rdi: pointer to rwlock_t */ -ENTRY(__write_lock_failed) - CFI_STARTPROC - LOCK_PREFIX - addl $RW_LOCK_BIAS,(%rdi) -1: rep - nop - cmpl $RW_LOCK_BIAS,(%rdi) - jne 1b - LOCK_PREFIX - subl $RW_LOCK_BIAS,(%rdi) - jnz __write_lock_failed - ret - CFI_ENDPROC -END(__write_lock_failed) - -/* rdi: pointer to rwlock_t */ -ENTRY(__read_lock_failed) - CFI_STARTPROC - LOCK_PREFIX - incl (%rdi) -1: rep - nop - cmpl $1,(%rdi) - js 1b - LOCK_PREFIX - decl (%rdi) - js __read_lock_failed - ret - CFI_ENDPROC -END(__read_lock_failed) diff --git a/trunk/arch/x86_64/lib/thunk.S b/trunk/arch/x86_64/lib/thunk.S index 0025535cac8d..332ea5dff916 100644 --- a/trunk/arch/x86_64/lib/thunk.S +++ b/trunk/arch/x86_64/lib/thunk.S @@ -1,9 +1,10 @@ -/* - * Save registers before calling assembly functions. This avoids - * disturbance of register allocation in some inline assembly constructs. - * Copyright 2001,2002 by Andi Kleen, SuSE Labs. - * Subject to the GNU public license, v.2. No warranty of any kind. - */ + /* + * Save registers before calling assembly functions. This avoids + * disturbance of register allocation in some inline assembly constructs. + * Copyright 2001,2002 by Andi Kleen, SuSE Labs. + * Subject to the GNU public license, v.2. No warranty of any kind. + * $Id: thunk.S,v 1.2 2002/03/13 20:06:58 ak Exp $ + */ #include #include @@ -66,3 +67,33 @@ restore_norax: RESTORE_ARGS 1 ret CFI_ENDPROC + +#ifdef CONFIG_SMP +/* Support for read/write spinlocks. */ + .text +/* rax: pointer to rwlock_t */ +ENTRY(__write_lock_failed) + lock + addl $RW_LOCK_BIAS,(%rax) +1: rep + nop + cmpl $RW_LOCK_BIAS,(%rax) + jne 1b + lock + subl $RW_LOCK_BIAS,(%rax) + jnz __write_lock_failed + ret + +/* rax: pointer to rwlock_t */ +ENTRY(__read_lock_failed) + lock + incl (%rax) +1: rep + nop + cmpl $1,(%rax) + js 1b + lock + decl (%rax) + js __read_lock_failed + ret +#endif diff --git a/trunk/arch/x86_64/mm/fault.c b/trunk/arch/x86_64/mm/fault.c index 1a17b0733ab5..4198798e1469 100644 --- a/trunk/arch/x86_64/mm/fault.c +++ b/trunk/arch/x86_64/mm/fault.c @@ -40,7 +40,8 @@ #define PF_RSVD (1<<3) #define PF_INSTR (1<<4) -static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); /* Hook to register for page fault notifications */ int register_page_fault_notifier(struct notifier_block *nb) @@ -48,13 +49,11 @@ int register_page_fault_notifier(struct notifier_block *nb) vmalloc_sync_all(); return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); } -EXPORT_SYMBOL_GPL(register_page_fault_notifier); int unregister_page_fault_notifier(struct notifier_block *nb) { return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); } -EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); static inline int notify_page_fault(enum die_val val, const char *str, struct pt_regs *regs, long err, int trap, int sig) @@ -68,6 +67,13 @@ static inline int notify_page_fault(enum die_val val, const char *str, }; return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); } +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif void bust_spinlocks(int yes) { @@ -96,7 +102,7 @@ void bust_spinlocks(int yes) static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, unsigned long error_code) { - unsigned char __user *instr; + unsigned char *instr; int scan_more = 1; int prefetch = 0; unsigned char *max_instr; @@ -105,7 +111,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, if (error_code & PF_INSTR) return 0; - instr = (unsigned char __user *)convert_rip_to_linear(current, regs); + instr = (unsigned char *)convert_rip_to_linear(current, regs); max_instr = instr + 15; if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE) @@ -116,7 +122,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, unsigned char instr_hi; unsigned char instr_lo; - if (__get_user(opcode, (char __user *)instr)) + if (__get_user(opcode, instr)) break; instr_hi = opcode & 0xf0; @@ -154,7 +160,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, case 0x00: /* Prefetch instruction is 0x0F0D or 0x0F18 */ scan_more = 0; - if (__get_user(opcode, (char __user *)instr)) + if (__get_user(opcode, instr)) break; prefetch = (instr_lo == 0xF) && (opcode == 0x0D || opcode == 0x18); @@ -170,7 +176,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, static int bad_address(void *p) { unsigned long dummy; - return __get_user(dummy, (unsigned long __user *)p); + return __get_user(dummy, (unsigned long *)p); } void dump_pagetable(unsigned long address) diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index 1e4669fa5734..52fd42c40c86 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -229,6 +229,7 @@ __init void *early_ioremap(unsigned long addr, unsigned long size) /* actually usually some more */ if (size >= LARGE_PAGE_SIZE) { + printk("SMBIOS area too long %lu\n", size); return NULL; } set_pmd(temp_mappings[0].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE)); @@ -249,13 +250,12 @@ __init void early_iounmap(void *addr, unsigned long size) } static void __meminit -phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) +phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end) { - int i = pmd_index(address); + int i; - for (; i < PTRS_PER_PMD; i++, address += PMD_SIZE) { + for (i = 0; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) { unsigned long entry; - pmd_t *pmd = pmd_page + pmd_index(address); if (address >= end) { if (!after_bootmem) @@ -263,10 +263,6 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) set_pmd(pmd, __pmd(0)); break; } - - if (pmd_val(*pmd)) - continue; - entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address; entry &= __supported_pte_mask; set_pmd(pmd, __pmd(entry)); @@ -276,41 +272,45 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) static void __meminit phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end) { - pmd_t *pmd = pmd_offset(pud,0); - spin_lock(&init_mm.page_table_lock); - phys_pmd_init(pmd, address, end); - spin_unlock(&init_mm.page_table_lock); - __flush_tlb_all(); + pmd_t *pmd = pmd_offset(pud, (unsigned long)__va(address)); + + if (pmd_none(*pmd)) { + spin_lock(&init_mm.page_table_lock); + phys_pmd_init(pmd, address, end); + spin_unlock(&init_mm.page_table_lock); + __flush_tlb_all(); + } } -static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end) +static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) { - int i = pud_index(addr); + long i = pud_index(address); + + pud = pud + i; + if (after_bootmem && pud_val(*pud)) { + phys_pmd_update(pud, address, end); + return; + } - for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE ) { + for (; i < PTRS_PER_PUD; pud++, i++) { int map; - unsigned long pmd_phys; - pud_t *pud = pud_page + pud_index(addr); + unsigned long paddr, pmd_phys; pmd_t *pmd; - if (addr >= end) + paddr = (address & PGDIR_MASK) + i*PUD_SIZE; + if (paddr >= end) break; - if (!after_bootmem && !e820_any_mapped(addr,addr+PUD_SIZE,0)) { + if (!after_bootmem && !e820_any_mapped(paddr, paddr+PUD_SIZE, 0)) { set_pud(pud, __pud(0)); continue; } - if (pud_val(*pud)) { - phys_pmd_update(pud, addr, end); - continue; - } - pmd = alloc_low_page(&map, &pmd_phys); spin_lock(&init_mm.page_table_lock); set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); - phys_pmd_init(pmd, addr, end); + phys_pmd_init(pmd, paddr, end); spin_unlock(&init_mm.page_table_lock); unmap_low_page(map); } @@ -597,6 +597,12 @@ void __init mem_init(void) pci_iommu_alloc(); + /* How many end-of-memory variables you have, grandma! */ + max_low_pfn = end_pfn; + max_pfn = end_pfn; + num_physpages = end_pfn; + high_memory = (void *) __va(end_pfn * PAGE_SIZE); + /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); diff --git a/trunk/arch/x86_64/mm/k8topology.c b/trunk/arch/x86_64/mm/k8topology.c index 5cf594f9230d..7c45c2d2b8b2 100644 --- a/trunk/arch/x86_64/mm/k8topology.c +++ b/trunk/arch/x86_64/mm/k8topology.c @@ -54,9 +54,6 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) nodes_clear(nodes_parsed); - if (!early_pci_allowed()) - return -1; - nb = find_northbridge(); if (nb < 0) return nb; diff --git a/trunk/arch/x86_64/mm/numa.c b/trunk/arch/x86_64/mm/numa.c index 322bf45fc36a..b2fac14baac0 100644 --- a/trunk/arch/x86_64/mm/numa.c +++ b/trunk/arch/x86_64/mm/numa.c @@ -225,7 +225,7 @@ void __init numa_init_array(void) int numa_fake __initdata = 0; /* Numa emulation */ -static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) +static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn) { int i; struct bootnode nodes[MAX_NUMNODES]; @@ -348,10 +348,9 @@ void __init paging_init(void) } } -static __init int numa_setup(char *opt) +/* [numa=off] */ +__init int numa_setup(char *opt) { - if (!opt) - return -EINVAL; if (!strncmp(opt,"off",3)) numa_off = 1; #ifdef CONFIG_NUMA_EMU @@ -367,11 +366,9 @@ static __init int numa_setup(char *opt) if (!strncmp(opt,"hotadd=", 7)) hotadd_percent = simple_strtoul(opt+7, NULL, 10); #endif - return 0; + return 1; } -early_param("numa", numa_setup); - /* * Setup early cpu_to_node. * diff --git a/trunk/arch/x86_64/mm/pageattr.c b/trunk/arch/x86_64/mm/pageattr.c index 3e231d762aaa..2685b1f3671c 100644 --- a/trunk/arch/x86_64/mm/pageattr.c +++ b/trunk/arch/x86_64/mm/pageattr.c @@ -108,8 +108,8 @@ static void revert_page(unsigned long address, pgprot_t ref_prot) BUG_ON(pud_none(*pud)); pmd = pmd_offset(pud, address); BUG_ON(pmd_val(*pmd) & _PAGE_PSE); + pgprot_val(ref_prot) |= _PAGE_PSE; large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot); - large_pte = pte_mkhuge(large_pte); set_pte((pte_t *)pmd, large_pte); } @@ -119,28 +119,32 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, { pte_t *kpte; struct page *kpte_page; + unsigned kpte_flags; pgprot_t ref_prot2; kpte = lookup_address(address); if (!kpte) return 0; kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); + kpte_flags = pte_val(*kpte); if (pgprot_val(prot) != pgprot_val(ref_prot)) { - if (!pte_huge(*kpte)) { + if ((kpte_flags & _PAGE_PSE) == 0) { set_pte(kpte, pfn_pte(pfn, prot)); } else { /* * split_large_page will take the reference for this * change_page_attr on the split page. */ + struct page *split; - ref_prot2 = pte_pgprot(pte_clrhuge(*kpte)); + ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE)); + split = split_large_page(address, prot, ref_prot2); if (!split) return -ENOMEM; - set_pte(kpte, mk_pte(split, ref_prot2)); + set_pte(kpte,mk_pte(split, ref_prot2)); kpte_page = split; - } + } page_private(kpte_page)++; - } else if (!pte_huge(*kpte)) { + } else if ((kpte_flags & _PAGE_PSE) == 0) { set_pte(kpte, pfn_pte(pfn, ref_prot)); BUG_ON(page_private(kpte_page) == 0); page_private(kpte_page)--; @@ -186,12 +190,10 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) * lowmem */ if (__pa(address) < KERNEL_TEXT_SIZE) { unsigned long addr2; - pgprot_t prot2; + pgprot_t prot2 = prot; addr2 = __START_KERNEL_map + __pa(address); - /* Make sure the kernel mappings stay executable */ - prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); - err = __change_page_attr(addr2, pfn, prot2, - PAGE_KERNEL_EXEC); + pgprot_val(prot2) &= ~_PAGE_NX; + err = __change_page_attr(addr2, pfn, prot2, PAGE_KERNEL_EXEC); } } up_write(&init_mm.mmap_sem); diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index ca10701e7a90..502fce65e96a 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -21,8 +21,6 @@ #include #include -int acpi_numa __initdata; - #if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \ && !defined(CONFIG_MEMORY_HOTPLUG) diff --git a/trunk/arch/x86_64/pci/Makefile b/trunk/arch/x86_64/pci/Makefile index 1eb18f421edf..a3f6ad570179 100644 --- a/trunk/arch/x86_64/pci/Makefile +++ b/trunk/arch/x86_64/pci/Makefile @@ -9,7 +9,7 @@ obj-y := i386.o obj-$(CONFIG_PCI_DIRECT)+= direct.o obj-y += fixup.o init.o obj-$(CONFIG_ACPI) += acpi.o -obj-y += legacy.o irq.o common.o early.o +obj-y += legacy.o irq.o common.o # mmconfig has a 64bit special obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o @@ -23,4 +23,3 @@ common-y += ../../i386/pci/common.o fixup-y += ../../i386/pci/fixup.o i386-y += ../../i386/pci/i386.o init-y += ../../i386/pci/init.o -early-y += ../../i386/pci/early.o diff --git a/trunk/arch/x86_64/pci/mmconfig.c b/trunk/arch/x86_64/pci/mmconfig.c index 7732f4254d21..3c55c76c6fd5 100644 --- a/trunk/arch/x86_64/pci/mmconfig.c +++ b/trunk/arch/x86_64/pci/mmconfig.c @@ -156,45 +156,15 @@ static __init void unreachable_devices(void) addr = pci_dev_base(0, k, PCI_DEVFN(i, 0)); if (addr == NULL|| readl(addr) != val1) { set_bit(i + 32*k, fallback_slots); - printk(KERN_NOTICE "PCI: No mmconfig possible" - " on device %02x:%02x\n", k, i); + printk(KERN_NOTICE + "PCI: No mmconfig possible on device %x:%x\n", + k, i); } } } } -static __init void pci_mmcfg_insert_resources(void) -{ -#define PCI_MMCFG_RESOURCE_NAME_LEN 19 - int i; - struct resource *res; - char *names; - unsigned num_buses; - - res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), - pci_mmcfg_config_num, GFP_KERNEL); - - if (!res) { - printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); - return; - } - - names = (void *)&res[pci_mmcfg_config_num]; - for (i = 0; i < pci_mmcfg_config_num; i++, res++) { - num_buses = pci_mmcfg_config[i].end_bus_number - - pci_mmcfg_config[i].start_bus_number + 1; - res->name = names; - snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", - pci_mmcfg_config[i].pci_segment_group_number); - res->start = pci_mmcfg_config[i].base_address; - res->end = res->start + (num_buses << 20) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - insert_resource(&iomem_resource, res); - names += PCI_MMCFG_RESOURCE_NAME_LEN; - } -} - -void __init pci_mmcfg_init(int type) +void __init pci_mmcfg_init(void) { int i; @@ -207,9 +177,7 @@ void __init pci_mmcfg_init(int type) (pci_mmcfg_config[0].base_address == 0)) return; - /* Only do this check when type 1 works. If it doesn't work - assume we run on a Mac and always use MCFG */ - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address, + if (!e820_all_mapped(pci_mmcfg_config[0].base_address, pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", @@ -218,6 +186,7 @@ void __init pci_mmcfg_init(int type) return; } + /* RED-PEN i386 doesn't do _nocache right now */ pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); if (pci_mmcfg_virt == NULL) { printk("PCI: Can not allocate memory for mmconfig structures\n"); @@ -236,7 +205,6 @@ void __init pci_mmcfg_init(int type) } unreachable_devices(); - pci_mmcfg_insert_resources(); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index 58b0eb581114..8afba339f05a 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -868,8 +868,8 @@ int hpet_alloc(struct hpet_data *hdp) do_div(temp, period); hpetp->hp_tick_freq = temp; /* ticks per second */ - printk(KERN_INFO "hpet%d: at MMIO 0x%lx, IRQ%s", - hpetp->hp_which, hdp->hd_phys_address, + printk(KERN_INFO "hpet%d: at MMIO 0x%lx (virtual 0x%p), IRQ%s", + hpetp->hp_which, hdp->hd_phys_address, hdp->hd_address, hpetp->hp_ntimer > 1 ? "s" : ""); for (i = 0; i < hpetp->hp_ntimer; i++) printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); diff --git a/trunk/drivers/i2c/i2c-dev.c b/trunk/drivers/i2c/i2c-dev.c index 58ccddd5c237..6e90dec02567 100644 --- a/trunk/drivers/i2c/i2c-dev.c +++ b/trunk/drivers/i2c/i2c-dev.c @@ -34,17 +34,14 @@ #include #include #include -#include #include static struct i2c_client i2cdev_client_template; struct i2c_dev { - int minor; struct i2c_adapter *adap; struct class_device *class_dev; }; -#define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev) #define I2C_MINORS 256 static struct i2c_dev *i2c_dev_array[I2C_MINORS]; @@ -60,18 +57,6 @@ static struct i2c_dev *i2c_dev_get_by_minor(unsigned index) return i2c_dev; } -static struct i2c_dev *i2c_dev_get_by_adapter(struct i2c_adapter *adap) -{ - struct i2c_dev *i2c_dev = NULL; - - spin_lock(&i2c_dev_array_lock); - if ((i2c_dev_array[adap->nr]) && - (i2c_dev_array[adap->nr]->adap == adap)) - i2c_dev = i2c_dev_array[adap->nr]; - spin_unlock(&i2c_dev_array_lock); - return i2c_dev; -} - static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap) { struct i2c_dev *i2c_dev; @@ -86,7 +71,7 @@ static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap) dev_err(&adap->dev, "i2c-dev already has a device assigned to this adapter\n"); goto error; } - i2c_dev->minor = adap->nr; + i2c_dev->adap = adap; i2c_dev_array[adap->nr] = i2c_dev; spin_unlock(&i2c_dev_array_lock); return i2c_dev; @@ -98,7 +83,7 @@ static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap) static void return_i2c_dev(struct i2c_dev *i2c_dev) { spin_lock(&i2c_dev_array_lock); - i2c_dev_array[i2c_dev->minor] = NULL; + i2c_dev_array[i2c_dev->adap->nr] = NULL; spin_unlock(&i2c_dev_array_lock); } @@ -415,21 +400,19 @@ static struct class *i2c_dev_class; static int i2cdev_attach_adapter(struct i2c_adapter *adap) { struct i2c_dev *i2c_dev; - struct device *dev; i2c_dev = get_free_i2c_dev(adap); if (IS_ERR(i2c_dev)) return PTR_ERR(i2c_dev); pr_debug("i2c-dev: adapter [%s] registered as minor %d\n", - adap->name, i2c_dev->minor); + adap->name, adap->nr); /* register this i2c device with the driver core */ - i2c_dev->adap = adap; - dev = &adap->dev; i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, - MKDEV(I2C_MAJOR, i2c_dev->minor), - dev, "i2c-%d", i2c_dev->minor); + MKDEV(I2C_MAJOR, adap->nr), + &adap->dev, "i2c-%d", + adap->nr); if (!i2c_dev->class_dev) goto error; class_device_create_file(i2c_dev->class_dev, &class_device_attr_name); @@ -444,12 +427,12 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) { struct i2c_dev *i2c_dev; - i2c_dev = i2c_dev_get_by_adapter(adap); + i2c_dev = i2c_dev_get_by_minor(adap->nr); if (!i2c_dev) return -ENODEV; return_i2c_dev(i2c_dev); - class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, i2c_dev->minor)); + class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); kfree(i2c_dev); pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c b/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c index 5c9b509e40e4..bf2455a6d562 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_iba6110.c @@ -742,6 +742,7 @@ static int ipath_setup_ht_reset(struct ipath_devdata *dd) return 0; } +#define HT_CAPABILITY_ID 0x08 /* HT capabilities not defined in kernel */ #define HT_INTR_DISC_CONFIG 0x80 /* HT interrupt and discovery cap */ #define HT_INTR_REG_INDEX 2 /* intconfig requires indirect accesses */ @@ -972,7 +973,7 @@ static int ipath_setup_ht_config(struct ipath_devdata *dd, * do this early, before we ever enable errors or hardware errors, * mostly to avoid causing the chip to enter freeze mode. */ - pos = pci_find_capability(pdev, PCI_CAP_ID_HT); + pos = pci_find_capability(pdev, HT_CAPABILITY_ID); if (!pos) { ipath_dev_err(dd, "Couldn't find HyperTransport " "capability; no interrupts\n"); @@ -995,7 +996,7 @@ static int ipath_setup_ht_config(struct ipath_devdata *dd, else if (cap_type == HT_INTR_DISC_CONFIG) ihandler = set_int_handler(dd, pdev, pos); } while ((pos = pci_find_next_capability(pdev, pos, - PCI_CAP_ID_HT))); + HT_CAPABILITY_ID))); if (!ihandler) { ipath_dev_err(dd, "Couldn't find interrupt handler in " diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index aadaa3c8096b..5f7db9d2436e 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -77,12 +77,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, * This adds a single pci device to the global * device list and adds sysfs and procfs entries */ -int __devinit pci_bus_add_device(struct pci_dev *dev) +void __devinit pci_bus_add_device(struct pci_dev *dev) { - int retval; - retval = device_add(&dev->dev); - if (retval) - return retval; + device_add(&dev->dev); down_write(&pci_bus_sem); list_add_tail(&dev->global_list, &pci_devices); @@ -90,7 +87,6 @@ int __devinit pci_bus_add_device(struct pci_dev *dev) pci_proc_attach_device(dev); pci_create_sysfs_dev_files(dev); - return 0; } /** @@ -108,7 +104,6 @@ int __devinit pci_bus_add_device(struct pci_dev *dev) void __devinit pci_bus_add_devices(struct pci_bus *bus) { struct pci_dev *dev; - int retval; list_for_each_entry(dev, &bus->devices, bus_list) { /* @@ -117,9 +112,7 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus) */ if (!list_empty(&dev->global_list)) continue; - retval = pci_bus_add_device(dev); - if (retval) - dev_err(&dev->dev, "Error adding device, continuing\n"); + pci_bus_add_device(dev); } list_for_each_entry(dev, &bus->devices, bus_list) { @@ -136,13 +129,10 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus) list_add_tail(&dev->subordinate->node, &dev->bus->children); up_write(&pci_bus_sem); - } + } pci_bus_add_devices(dev->subordinate); - retval = sysfs_create_link(&dev->subordinate->class_dev.kobj, - &dev->dev.kobj, "bridge"); - if (retval) - dev_err(&dev->dev, "Error creating sysfs " - "bridge symlink, continuing...\n"); + + sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge"); } } } diff --git a/trunk/drivers/pci/hotplug/acpiphp.h b/trunk/drivers/pci/hotplug/acpiphp.h index 7fff07e877c7..be104eced34c 100644 --- a/trunk/drivers/pci/hotplug/acpiphp.h +++ b/trunk/drivers/pci/hotplug/acpiphp.h @@ -150,11 +150,6 @@ struct acpiphp_attention_info struct module *owner; }; -struct acpiphp_ioapic { - struct pci_dev *dev; - u32 gsi_base; - struct list_head list; -}; /* PCI bus bridge HID */ #define ACPI_PCI_HOST_HID "PNP0A03" diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 83e8e4412de5..ae67a8f55ba1 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -53,8 +53,6 @@ #include "acpiphp.h" static LIST_HEAD(bridge_list); -static LIST_HEAD(ioapic_list); -static DEFINE_SPINLOCK(ioapic_list_lock); #define MY_NAME "acpiphp_glue" @@ -799,7 +797,6 @@ ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) struct pci_dev *pdev; u32 gsi_base; u64 phys_addr; - struct acpiphp_ioapic *ioapic; /* Evaluate _STA if present */ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); @@ -814,107 +811,41 @@ ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) if (get_gsi_base(handle, &gsi_base)) return AE_OK; - ioapic = kmalloc(sizeof(*ioapic), GFP_KERNEL); - if (!ioapic) - return AE_NO_MEMORY; - pdev = get_apic_pci_info(handle); if (!pdev) - goto exit_kfree; + return AE_OK; - if (pci_enable_device(pdev)) - goto exit_pci_dev_put; + if (pci_enable_device(pdev)) { + pci_dev_put(pdev); + return AE_OK; + } pci_set_master(pdev); - if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) - goto exit_pci_disable_device; - - phys_addr = pci_resource_start(pdev, 0); - if (acpi_register_ioapic(handle, phys_addr, gsi_base)) - goto exit_pci_release_region; - - ioapic->gsi_base = gsi_base; - ioapic->dev = pdev; - spin_lock(&ioapic_list_lock); - list_add_tail(&ioapic->list, &ioapic_list); - spin_unlock(&ioapic_list_lock); - - return AE_OK; - - exit_pci_release_region: - pci_release_region(pdev, 0); - exit_pci_disable_device: - pci_disable_device(pdev); - exit_pci_dev_put: - pci_dev_put(pdev); - exit_kfree: - kfree(ioapic); - - return AE_OK; -} - -static acpi_status -ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - acpi_status status; - unsigned long sta; - acpi_handle tmp; - u32 gsi_base; - struct acpiphp_ioapic *pos, *n, *ioapic = NULL; - - /* Evaluate _STA if present */ - status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); - if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) - return AE_CTRL_DEPTH; - - /* Scan only PCI bus scope */ - status = acpi_get_handle(handle, "_HID", &tmp); - if (ACPI_SUCCESS(status)) - return AE_CTRL_DEPTH; - - if (get_gsi_base(handle, &gsi_base)) + if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) { + pci_disable_device(pdev); + pci_dev_put(pdev); return AE_OK; - - acpi_unregister_ioapic(handle, gsi_base); - - spin_lock(&ioapic_list_lock); - list_for_each_entry_safe(pos, n, &ioapic_list, list) { - if (pos->gsi_base != gsi_base) - continue; - ioapic = pos; - list_del(&ioapic->list); - break; } - spin_unlock(&ioapic_list_lock); - if (!ioapic) + phys_addr = pci_resource_start(pdev, 0); + if (acpi_register_ioapic(handle, phys_addr, gsi_base)) { + pci_release_region(pdev, 0); + pci_disable_device(pdev); + pci_dev_put(pdev); return AE_OK; - - pci_release_region(ioapic->dev, 0); - pci_disable_device(ioapic->dev); - pci_dev_put(ioapic->dev); - kfree(ioapic); + } return AE_OK; } static int acpiphp_configure_ioapics(acpi_handle handle) { - ioapic_add(handle, 0, NULL, NULL); acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX, ioapic_add, NULL, NULL); return 0; } -static int acpiphp_unconfigure_ioapics(acpi_handle handle) -{ - ioapic_remove(handle, 0, NULL, NULL); - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, - ACPI_UINT32_MAX, ioapic_remove, NULL, NULL); - return 0; -} - static int power_on_slot(struct acpiphp_slot *slot) { acpi_status status; @@ -1066,7 +997,7 @@ static int acpiphp_bus_add(struct acpiphp_func *func) * @handle: handle to acpi namespace * */ -static int acpiphp_bus_trim(acpi_handle handle) +int acpiphp_bus_trim(acpi_handle handle) { struct acpi_device *device; int retval; @@ -1143,11 +1074,10 @@ static int enable_device(struct acpiphp_slot *slot) pci_bus_assign_resources(bus); acpiphp_sanitize_bus(bus); - acpiphp_set_hpp_values(slot->bridge->handle, bus); - list_for_each_entry(func, &slot->funcs, sibling) - acpiphp_configure_ioapics(func->handle); pci_enable_bridges(bus); pci_bus_add_devices(bus); + acpiphp_set_hpp_values(slot->bridge->handle, bus); + acpiphp_configure_ioapics(slot->bridge->handle); /* associate pci_dev to our representation */ list_for_each (l, &slot->funcs) { @@ -1173,16 +1103,6 @@ static int enable_device(struct acpiphp_slot *slot) return retval; } -static void disable_bridges(struct pci_bus *bus) -{ - struct pci_dev *dev; - list_for_each_entry(dev, &bus->devices, bus_list) { - if (dev->subordinate) { - disable_bridges(dev->subordinate); - pci_disable_device(dev); - } - } -} /** * disable_device - disable a slot @@ -1207,19 +1127,6 @@ static int disable_device(struct acpiphp_slot *slot) func->bridge = NULL; } - if (func->pci_dev) { - pci_stop_bus_device(func->pci_dev); - if (func->pci_dev->subordinate) { - disable_bridges(func->pci_dev->subordinate); - pci_disable_device(func->pci_dev); - } - } - } - - list_for_each (l, &slot->funcs) { - func = list_entry(l, struct acpiphp_func, sibling); - - acpiphp_unconfigure_ioapics(func->handle); acpiphp_bus_trim(func->handle); /* try to remove anyway. * acpiphp_bus_add might have been failed */ diff --git a/trunk/drivers/pci/hotplug/fakephp.c b/trunk/drivers/pci/hotplug/fakephp.c index 05a4f0f90186..dd2b762777c4 100644 --- a/trunk/drivers/pci/hotplug/fakephp.c +++ b/trunk/drivers/pci/hotplug/fakephp.c @@ -176,9 +176,7 @@ static void pci_rescan_slot(struct pci_dev *temp) struct pci_bus *bus = temp->bus; struct pci_dev *dev; int func; - int retval; u8 hdr_type; - if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) { temp->hdr_type = hdr_type & 0x7f; if (!pci_find_slot(bus->number, temp->devfn)) { @@ -187,12 +185,8 @@ static void pci_rescan_slot(struct pci_dev *temp) dbg("New device on %s function %x:%x\n", bus->name, temp->devfn >> 3, temp->devfn & 7); - retval = pci_bus_add_device(dev); - if (retval) - dev_err(&dev->dev, "error adding " - "device, continuing.\n"); - else - add_slot(dev); + pci_bus_add_device(dev); + add_slot(dev); } } /* multifunction device? */ @@ -211,12 +205,8 @@ static void pci_rescan_slot(struct pci_dev *temp) dbg("New device on %s function %x:%x\n", bus->name, temp->devfn >> 3, temp->devfn & 7); - retval = pci_bus_add_device(dev); - if (retval) - dev_err(&dev->dev, "error adding " - "device, continuing.\n"); - else - add_slot(dev); + pci_bus_add_device(dev); + add_slot(dev); } } } diff --git a/trunk/drivers/pci/hotplug/pci_hotplug.h b/trunk/drivers/pci/hotplug/pci_hotplug.h index 772523dc3860..e929b7c11429 100644 --- a/trunk/drivers/pci/hotplug/pci_hotplug.h +++ b/trunk/drivers/pci/hotplug/pci_hotplug.h @@ -172,8 +172,8 @@ struct hotplug_slot { extern int pci_hp_register (struct hotplug_slot *slot); extern int pci_hp_deregister (struct hotplug_slot *slot); -extern int __must_check pci_hp_change_slot_info (struct hotplug_slot *slot, - struct hotplug_slot_info *info); +extern int pci_hp_change_slot_info (struct hotplug_slot *slot, + struct hotplug_slot_info *info); extern struct subsystem pci_hotplug_slots_subsys; /* PCI Setting Record (Type 0) */ diff --git a/trunk/drivers/pci/hotplug/pci_hotplug_core.c b/trunk/drivers/pci/hotplug/pci_hotplug_core.c index e2823ea9c4ed..b7b378df89e3 100644 --- a/trunk/drivers/pci/hotplug/pci_hotplug_core.c +++ b/trunk/drivers/pci/hotplug/pci_hotplug_core.c @@ -482,95 +482,31 @@ static int has_test_file (struct hotplug_slot *slot) static int fs_add_slot (struct hotplug_slot *slot) { - int retval = 0; - - if (has_power_file(slot) == 0) { - retval = sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr); - if (retval) - goto exit_power; - } - - if (has_attention_file(slot) == 0) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_attention.attr); - if (retval) - goto exit_attention; - } - - if (has_latch_file(slot) == 0) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_latch.attr); - if (retval) - goto exit_latch; - } - - if (has_adapter_file(slot) == 0) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_presence.attr); - if (retval) - goto exit_adapter; - } - - if (has_address_file(slot) == 0) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_address.attr); - if (retval) - goto exit_address; - } - - if (has_max_bus_speed_file(slot) == 0) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_max_bus_speed.attr); - if (retval) - goto exit_max_speed; - } - - if (has_cur_bus_speed_file(slot) == 0) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_cur_bus_speed.attr); - if (retval) - goto exit_cur_speed; - } - - if (has_test_file(slot) == 0) { - retval = sysfs_create_file(&slot->kobj, - &hotplug_slot_attr_test.attr); - if (retval) - goto exit_test; - } + if (has_power_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr); - goto exit; + if (has_attention_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr); -exit_test: - if (has_cur_bus_speed_file(slot) == 0) - sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); + if (has_latch_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr); -exit_cur_speed: - if (has_max_bus_speed_file(slot) == 0) - sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); + if (has_adapter_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr); -exit_max_speed: if (has_address_file(slot) == 0) - sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_address.attr); + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_address.attr); -exit_address: - if (has_adapter_file(slot) == 0) - sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr); + if (has_max_bus_speed_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); -exit_adapter: - if (has_latch_file(slot) == 0) - sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); + if (has_cur_bus_speed_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); -exit_latch: - if (has_attention_file(slot) == 0) - sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr); + if (has_test_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr); -exit_attention: - if (has_power_file(slot) == 0) - sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); -exit_power: -exit: - return retval; + return 0; } static void fs_remove_slot (struct hotplug_slot *slot) @@ -690,11 +626,8 @@ int pci_hp_deregister (struct hotplug_slot *slot) * * Returns 0 if successful, anything else for an error. */ -int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot, - struct hotplug_slot_info *info) +int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info) { - int retval; - if ((slot == NULL) || (info == NULL)) return -ENODEV; @@ -703,60 +636,32 @@ int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot, * for the files referring to the fields that have now changed. */ if ((has_power_file(slot) == 0) && - (slot->info->power_status != info->power_status)) { - retval = sysfs_update_file(&slot->kobj, - &hotplug_slot_attr_power.attr); - if (retval) - return retval; - } + (slot->info->power_status != info->power_status)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_power.attr); if ((has_attention_file(slot) == 0) && - (slot->info->attention_status != info->attention_status)) { - retval = sysfs_update_file(&slot->kobj, - &hotplug_slot_attr_attention.attr); - if (retval) - return retval; - } + (slot->info->attention_status != info->attention_status)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_attention.attr); if ((has_latch_file(slot) == 0) && - (slot->info->latch_status != info->latch_status)) { - retval = sysfs_update_file(&slot->kobj, - &hotplug_slot_attr_latch.attr); - if (retval) - return retval; - } + (slot->info->latch_status != info->latch_status)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_latch.attr); if ((has_adapter_file(slot) == 0) && - (slot->info->adapter_status != info->adapter_status)) { - retval = sysfs_update_file(&slot->kobj, - &hotplug_slot_attr_presence.attr); - if (retval) - return retval; - } + (slot->info->adapter_status != info->adapter_status)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_presence.attr); if ((has_address_file(slot) == 0) && - (slot->info->address != info->address)) { - retval = sysfs_update_file(&slot->kobj, - &hotplug_slot_attr_address.attr); - if (retval) - return retval; - } + (slot->info->address != info->address)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_address.attr); if ((has_max_bus_speed_file(slot) == 0) && - (slot->info->max_bus_speed != info->max_bus_speed)) { - retval = sysfs_update_file(&slot->kobj, - &hotplug_slot_attr_max_bus_speed.attr); - if (retval) - return retval; - } + (slot->info->max_bus_speed != info->max_bus_speed)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); if ((has_cur_bus_speed_file(slot) == 0) && - (slot->info->cur_bus_speed != info->cur_bus_speed)) { - retval = sysfs_update_file(&slot->kobj, - &hotplug_slot_attr_cur_bus_speed.attr); - if (retval) - return retval; - } + (slot->info->cur_bus_speed != info->cur_bus_speed)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); memcpy (slot->info, info, sizeof (struct hotplug_slot_info)); diff --git a/trunk/drivers/pci/hotplug/pciehp_ctrl.c b/trunk/drivers/pci/hotplug/pciehp_ctrl.c index 41290a106bd8..33d198768356 100644 --- a/trunk/drivers/pci/hotplug/pciehp_ctrl.c +++ b/trunk/drivers/pci/hotplug/pciehp_ctrl.c @@ -762,14 +762,14 @@ int pciehp_enable_slot(struct slot *p_slot) if (rc || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); - return -ENODEV; + return 1; } if (MRL_SENS(p_slot->ctrl->ctrlcap)) { rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); - return -ENODEV; + return 1; } } @@ -778,7 +778,7 @@ int pciehp_enable_slot(struct slot *p_slot) if (rc || getstatus) { info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); - return -EINVAL; + return 1; } } mutex_unlock(&p_slot->ctrl->crit_sect); @@ -813,7 +813,7 @@ int pciehp_disable_slot(struct slot *p_slot) if (ret || !getstatus) { info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); - return -ENODEV; + return 1; } } @@ -822,7 +822,7 @@ int pciehp_disable_slot(struct slot *p_slot) if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); - return -ENODEV; + return 1; } } @@ -831,7 +831,7 @@ int pciehp_disable_slot(struct slot *p_slot) if (ret || !getstatus) { info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); mutex_unlock(&p_slot->ctrl->crit_sect); - return -EINVAL; + return 1; } } diff --git a/trunk/drivers/pci/hotplug/pcihp_skeleton.c b/trunk/drivers/pci/hotplug/pcihp_skeleton.c index 2b9e10e38613..8ad446605f75 100644 --- a/trunk/drivers/pci/hotplug/pcihp_skeleton.c +++ b/trunk/drivers/pci/hotplug/pcihp_skeleton.c @@ -1,5 +1,5 @@ /* - * PCI Hot Plug Controller Skeleton Driver - 0.3 + * PCI Hot Plug Controller Skeleton Driver - 0.2 * * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2001,2003 IBM Corp. @@ -21,7 +21,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * This driver is to be used as a skeleton driver to show how to interface + * This driver is to be used as a skeleton driver to be show how to interface * with the pci hotplug core easily. * * Send feedback to @@ -58,6 +58,8 @@ static LIST_HEAD(slot_list); #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) + + /* local variables */ static int debug; static int num_slots; @@ -107,6 +109,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) return retval; } + static int disable_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot->private; @@ -339,7 +342,7 @@ static int __init pcihp_skel_init(void) info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); /* * Do specific initialization stuff for your driver here - * like initializing your controller hardware (if any) and + * Like initializing your controller hardware (if any) and * determining the number of slots you have in the system * right now. */ diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index c7103ac5cd06..7208b95c6ee7 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -173,7 +173,7 @@ struct controller { #define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" /* sysfs functions for the hotplug controller info */ -extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); +extern void shpchp_create_ctrl_files (struct controller *ctrl); extern int shpchp_sysfs_enable_slot(struct slot *slot); extern int shpchp_sysfs_disable_slot(struct slot *slot); diff --git a/trunk/drivers/pci/hotplug/shpchp_core.c b/trunk/drivers/pci/hotplug/shpchp_core.c index 235c18a22393..a14e7de19846 100644 --- a/trunk/drivers/pci/hotplug/shpchp_core.c +++ b/trunk/drivers/pci/hotplug/shpchp_core.c @@ -449,14 +449,10 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ctrl->speed = PCI_SPEED_33MHz; } - rc = shpchp_create_ctrl_files(ctrl); - if (rc) - goto err_cleanup_slots; + shpchp_create_ctrl_files(ctrl); return 0; -err_cleanup_slots: - cleanup_slots(ctrl); err_out_release_ctlr: ctrl->hpc_ops->release_ctlr(ctrl); err_out_free_ctrl: diff --git a/trunk/drivers/pci/hotplug/shpchp_sysfs.c b/trunk/drivers/pci/hotplug/shpchp_sysfs.c index 29fa9d26adae..620e1139e607 100644 --- a/trunk/drivers/pci/hotplug/shpchp_sysfs.c +++ b/trunk/drivers/pci/hotplug/shpchp_sysfs.c @@ -91,9 +91,9 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha } static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); -int __must_check shpchp_create_ctrl_files (struct controller *ctrl) +void shpchp_create_ctrl_files (struct controller *ctrl) { - return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); + device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); } void shpchp_remove_ctrl_files(struct controller *ctrl) diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 008235947aa4..a83c1f5735d6 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -900,33 +900,6 @@ static int msix_capability_init(struct pci_dev *dev, return 0; } -/** - * pci_msi_supported - check whether MSI may be enabled on device - * @dev: pointer to the pci_dev data structure of MSI device function - * - * MSI must be globally enabled and supported by the device and its root - * bus. But, the root bus is not easy to find since some architectures - * have virtual busses on top of the PCI hierarchy (for instance the - * hypertransport bus), while the actual bus where MSI must be supported - * is below. So we test the MSI flag on all parent busses and assume - * that no quirk will ever set the NO_MSI flag on a non-root bus. - **/ -static -int pci_msi_supported(struct pci_dev * dev) -{ - struct pci_bus *bus; - - if (!pci_msi_enable || !dev || dev->no_msi) - return -EINVAL; - - /* check MSI flags of all parent busses */ - for (bus = dev->bus; bus; bus = bus->parent) - if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) - return -EINVAL; - - return 0; -} - /** * pci_enable_msi - configure device's MSI capability structure * @dev: pointer to the pci_dev data structure of MSI device function @@ -939,11 +912,19 @@ int pci_msi_supported(struct pci_dev * dev) **/ int pci_enable_msi(struct pci_dev* dev) { - int pos, temp, status; + struct pci_bus *bus; + int pos, temp, status = -EINVAL; u16 control; - if (pci_msi_supported(dev) < 0) - return -EINVAL; + if (!pci_msi_enable || !dev) + return status; + + if (dev->no_msi) + return status; + + for (bus = dev->bus; bus; bus = bus->parent) + if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) + return -EINVAL; temp = dev->irq; @@ -1153,14 +1134,22 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec) **/ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) { + struct pci_bus *bus; int status, pos, nr_entries, free_vectors; int i, j, temp; u16 control; unsigned long flags; - if (!entries || pci_msi_supported(dev) < 0) + if (!pci_msi_enable || !dev || !entries) return -EINVAL; + if (dev->no_msi) + return -EINVAL; + + for (bus = dev->bus; bus; bus = bus->parent) + if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) + return -EINVAL; + status = msi_init(); if (status < 0) return status; diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index b1c0c707d96c..d8ace1f90dd2 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -56,7 +56,6 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) subdevice=PCI_ANY_ID, class=0, class_mask=0; unsigned long driver_data=0; int fields=0; - int retval = 0; fields = sscanf(buf, "%x %x %x %x %x %x %lux", &vendor, &device, &subvendor, &subdevice, @@ -83,12 +82,10 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) spin_unlock(&pdrv->dynids.lock); if (get_driver(&pdrv->driver)) { - retval = driver_attach(&pdrv->driver); + driver_attach(&pdrv->driver); put_driver(&pdrv->driver); } - if (retval) - return retval; return count; } static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); @@ -421,11 +418,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner) drv->driver.bus = &pci_bus_type; drv->driver.owner = owner; drv->driver.kobj.ktype = &pci_driver_kobj_type; - - if (pci_multithread_probe) - drv->driver.multithread_probe = pci_multithread_probe; - else - drv->driver.multithread_probe = drv->multithread_probe; + drv->driver.multithread_probe = pci_multithread_probe; spin_lock_init(&drv->dynids.lock); INIT_LIST_HEAD(&drv->dynids.list); diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index a1d2e979b17f..fdefa7dcd156 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -117,7 +117,6 @@ is_enabled_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pci_dev *pdev = to_pci_dev(dev); - int retval = 0; /* this can crash the machine when done on the "wrong" device */ if (!capable(CAP_SYS_ADMIN)) @@ -127,53 +126,11 @@ is_enabled_store(struct device *dev, struct device_attribute *attr, pci_disable_device(pdev); if (*buf == '1') - retval = pci_enable_device(pdev); + pci_enable_device(pdev); - if (retval) - return retval; return count; } -static ssize_t -msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct pci_dev *pdev = to_pci_dev(dev); - - if (!pdev->subordinate) - return 0; - - return sprintf (buf, "%u\n", - !(pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI)); -} - -static ssize_t -msi_bus_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct pci_dev *pdev = to_pci_dev(dev); - - /* bad things may happen if the no_msi flag is changed - * while some drivers are loaded */ - if (!capable(CAP_SYS_ADMIN)) - return count; - - if (!pdev->subordinate) - return count; - - if (*buf == '0') { - pdev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; - dev_warn(&pdev->dev, "forced subordinate bus to not support MSI," - " bad things could happen.\n"); - } - - if (*buf == '1') { - pdev->subordinate->bus_flags &= ~PCI_BUS_FLAGS_NO_MSI; - dev_warn(&pdev->dev, "forced subordinate bus to support MSI," - " bad things could happen.\n"); - } - - return count; -} struct device_attribute pci_dev_attrs[] = { __ATTR_RO(resource), @@ -188,7 +145,6 @@ struct device_attribute pci_dev_attrs[] = { __ATTR(enable, 0600, is_enabled_show, is_enabled_store), __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), broken_parity_status_show,broken_parity_status_store), - __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store), __ATTR_NULL, }; @@ -428,39 +384,16 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, return pci_mmap_page_range(pdev, vma, mmap_type, 0); } -/** - * pci_remove_resource_files - cleanup resource files - * @dev: dev to cleanup - * - * If we created resource files for @dev, remove them from sysfs and - * free their resources. - */ -static void -pci_remove_resource_files(struct pci_dev *pdev) -{ - int i; - - for (i = 0; i < PCI_ROM_RESOURCE; i++) { - struct bin_attribute *res_attr; - - res_attr = pdev->res_attr[i]; - if (res_attr) { - sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); - kfree(res_attr); - } - } -} - /** * pci_create_resource_files - create resource files in sysfs for @dev * @dev: dev in question * * Walk the resources in @dev creating files for each resource available. */ -static int pci_create_resource_files(struct pci_dev *pdev) +static void +pci_create_resource_files(struct pci_dev *pdev) { int i; - int retval; /* Expose the PCI resources from this device as files */ for (i = 0; i < PCI_ROM_RESOURCE; i++) { @@ -483,19 +416,35 @@ static int pci_create_resource_files(struct pci_dev *pdev) res_attr->size = pci_resource_len(pdev, i); res_attr->mmap = pci_mmap_resource; res_attr->private = &pdev->resource[i]; - retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr); - if (retval) { - pci_remove_resource_files(pdev); - return retval; - } - } else { - return -ENOMEM; + sysfs_create_bin_file(&pdev->dev.kobj, res_attr); + } + } +} + +/** + * pci_remove_resource_files - cleanup resource files + * @dev: dev to cleanup + * + * If we created resource files for @dev, remove them from sysfs and + * free their resources. + */ +static void +pci_remove_resource_files(struct pci_dev *pdev) +{ + int i; + + for (i = 0; i < PCI_ROM_RESOURCE; i++) { + struct bin_attribute *res_attr; + + res_attr = pdev->res_attr[i]; + if (res_attr) { + sysfs_remove_bin_file(&pdev->dev.kobj, res_attr); + kfree(res_attr); } } - return 0; } #else /* !HAVE_PCI_MMAP */ -static inline int pci_create_resource_files(struct pci_dev *dev) { return 0; } +static inline void pci_create_resource_files(struct pci_dev *dev) { return; } static inline void pci_remove_resource_files(struct pci_dev *dev) { return; } #endif /* HAVE_PCI_MMAP */ @@ -580,27 +529,22 @@ static struct bin_attribute pcie_config_attr = { .write = pci_write_config, }; -int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) +int pci_create_sysfs_dev_files (struct pci_dev *pdev) { - struct bin_attribute *rom_attr = NULL; - int retval; - if (!sysfs_initialized) return -EACCES; if (pdev->cfg_size < 4096) - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); + sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); else - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr); - if (retval) - goto err; + sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr); - retval = pci_create_resource_files(pdev); - if (retval) - goto err_bin_file; + pci_create_resource_files(pdev); /* If the device has a ROM, try to expose it in sysfs. */ if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) { + struct bin_attribute *rom_attr; + rom_attr = kzalloc(sizeof(*rom_attr), GFP_ATOMIC); if (rom_attr) { pdev->rom_attr = rom_attr; @@ -610,28 +554,13 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) rom_attr->attr.owner = THIS_MODULE; rom_attr->read = pci_read_rom; rom_attr->write = pci_write_rom; - retval = sysfs_create_bin_file(&pdev->dev.kobj, rom_attr); - if (retval) - goto err_rom; - } else { - retval = -ENOMEM; - goto err_bin_file; + sysfs_create_bin_file(&pdev->dev.kobj, rom_attr); } } /* add platform-specific attributes */ pcibios_add_platform_entries(pdev); - + return 0; - -err_rom: - kfree(rom_attr); -err_bin_file: - if (pdev->cfg_size < 4096) - sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); - else - sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr); -err: - return retval; } /** @@ -660,14 +589,10 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev) static int __init pci_sysfs_init(void) { struct pci_dev *pdev = NULL; - int retval; - + sysfs_initialized = 1; - for_each_pci_dev(pdev) { - retval = pci_create_sysfs_dev_files(pdev); - if (retval) - return retval; - } + for_each_pci_dev(pdev) + pci_create_sysfs_dev_files(pdev); return 0; } diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index a544997399b3..8ab027886034 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -445,51 +445,6 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) EXPORT_SYMBOL(pci_choose_state); -static int pci_save_pcie_state(struct pci_dev *dev) -{ - int pos, i = 0; - struct pci_cap_saved_state *save_state; - u16 *cap; - - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (pos <= 0) - return 0; - - save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); - if (!save_state) { - dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); - return -ENOMEM; - } - cap = (u16 *)&save_state->data[0]; - - pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]); - pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); - pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); - pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); - pci_add_saved_cap(dev, save_state); - return 0; -} - -static void pci_restore_pcie_state(struct pci_dev *dev) -{ - int i = 0, pos; - struct pci_cap_saved_state *save_state; - u16 *cap; - - save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (!save_state || pos <= 0) - return; - cap = (u16 *)&save_state->data[0]; - - pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]); - pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); - pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); - pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); - pci_remove_saved_cap(save_state); - kfree(save_state); -} - /** * pci_save_state - save the PCI configuration space of a device before suspending * @dev: - PCI device that we're dealing with @@ -505,8 +460,6 @@ pci_save_state(struct pci_dev *dev) return i; if ((i = pci_save_msix_state(dev)) != 0) return i; - if ((i = pci_save_pcie_state(dev)) != 0) - return i; return 0; } @@ -520,9 +473,6 @@ pci_restore_state(struct pci_dev *dev) int i; int val; - /* PCI Express register must be restored first */ - pci_restore_pcie_state(dev); - /* * The Base Address register should be programmed before the command * register(s) @@ -1005,12 +955,13 @@ static int __devinit pci_setup(char *str) } str = k; } - return 0; + return 1; } -early_param("pci", pci_setup); device_initcall(pci_init); +__setup("pci=", pci_setup); + #if defined(CONFIG_ISA) || defined(CONFIG_EISA) /* FIXME: Some boxes have multiple ISA bridges! */ struct pci_dev *isa_bridge; diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 6bf327db5c5e..08d58fc78ee1 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -42,7 +42,7 @@ extern void pci_remove_legacy_files(struct pci_bus *bus); /* Lock for read/write access to pci device and bus lists */ extern struct rw_semaphore pci_bus_sem; -#ifdef CONFIG_PCI_MSI +#ifdef CONFIG_X86_IO_APIC extern int pci_msi_quirk; #else #define pci_msi_quirk 0 diff --git a/trunk/drivers/pci/pcie/Kconfig b/trunk/drivers/pci/pcie/Kconfig index 0ad92a8ad8b1..1012db8b8b2c 100644 --- a/trunk/drivers/pci/pcie/Kconfig +++ b/trunk/drivers/pci/pcie/Kconfig @@ -34,4 +34,3 @@ config HOTPLUG_PCI_PCIE_POLL_EVENT_MODE When in doubt, say N. -source "drivers/pci/pcie/aer/Kconfig" diff --git a/trunk/drivers/pci/pcie/Makefile b/trunk/drivers/pci/pcie/Makefile index e00fb99acf44..984fa87283e3 100644 --- a/trunk/drivers/pci/pcie/Makefile +++ b/trunk/drivers/pci/pcie/Makefile @@ -5,6 +5,3 @@ pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o - -# Build PCI Express AER if needed -obj-$(CONFIG_PCIEAER) += aer/ diff --git a/trunk/drivers/pci/pcie/aer/Kconfig b/trunk/drivers/pci/pcie/aer/Kconfig deleted file mode 100644 index 3f37a60a6438..000000000000 --- a/trunk/drivers/pci/pcie/aer/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# -# PCI Express Root Port Device AER Configuration -# - -config PCIEAER - boolean "Root Port Advanced Error Reporting support" - depends on PCIEPORTBUS && ACPI - default y - help - This enables PCI Express Root Port Advanced Error Reporting - (AER) driver support. Error reporting messages sent to Root - Port will be handled by PCI Express AER driver. diff --git a/trunk/drivers/pci/pcie/aer/Makefile b/trunk/drivers/pci/pcie/aer/Makefile deleted file mode 100644 index 15a4f40d520b..000000000000 --- a/trunk/drivers/pci/pcie/aer/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for PCI-Express Root Port Advanced Error Reporting Driver -# - -obj-$(CONFIG_PCIEAER) += aerdriver.o - -aerdriver-objs := aerdrv_errprint.o aerdrv_core.o aerdrv.o aerdrv_acpi.o - diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.c b/trunk/drivers/pci/pcie/aer/aerdrv.c deleted file mode 100644 index 0d4ac027d53e..000000000000 --- a/trunk/drivers/pci/pcie/aer/aerdrv.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * drivers/pci/pcie/aer/aerdrv.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * This file implements the AER root port service driver. The driver will - * register an irq handler. When root port triggers an AER interrupt, the irq - * handler will collect root port status and schedule a work. - * - * Copyright (C) 2006 Intel Corp. - * Tom Long Nguyen (tom.l.nguyen@intel.com) - * Zhang Yanmin (yanmin.zhang@intel.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "aerdrv.h" - -/* - * Version Information - */ -#define DRIVER_VERSION "v1.0" -#define DRIVER_AUTHOR "tom.l.nguyen@intel.com" -#define DRIVER_DESC "Root Port Advanced Error Reporting Driver" -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -static int __devinit aer_probe (struct pcie_device *dev, - const struct pcie_port_service_id *id ); -static void aer_remove(struct pcie_device *dev); -static int aer_suspend(struct pcie_device *dev, pm_message_t state) -{return 0;} -static int aer_resume(struct pcie_device *dev) {return 0;} -static pci_ers_result_t aer_error_detected(struct pci_dev *dev, - enum pci_channel_state error); -static void aer_error_resume(struct pci_dev *dev); -static pci_ers_result_t aer_root_reset(struct pci_dev *dev); - -/* - * PCI Express bus's AER Root service driver data structure - */ -static struct pcie_port_service_id aer_id[] = { - { - .vendor = PCI_ANY_ID, - .device = PCI_ANY_ID, - .port_type = PCIE_RC_PORT, - .service_type = PCIE_PORT_SERVICE_AER, - }, - { /* end: all zeroes */ } -}; - -static struct pci_error_handlers aer_error_handlers = { - .error_detected = aer_error_detected, - .resume = aer_error_resume, -}; - -static struct pcie_port_service_driver aerdrv = { - .name = "aer", - .id_table = &aer_id[0], - - .probe = aer_probe, - .remove = aer_remove, - - .suspend = aer_suspend, - .resume = aer_resume, - - .err_handler = &aer_error_handlers, - - .reset_link = aer_root_reset, -}; - -/** - * aer_irq - Root Port's ISR - * @irq: IRQ assigned to Root Port - * @context: pointer to Root Port data structure - * @r: pointer struct pt_regs - * - * Invoked when Root Port detects AER messages. - **/ -static irqreturn_t aer_irq(int irq, void *context, struct pt_regs * r) -{ - unsigned int status, id; - struct pcie_device *pdev = (struct pcie_device *)context; - struct aer_rpc *rpc = get_service_data(pdev); - int next_prod_idx; - unsigned long flags; - int pos; - - pos = pci_find_aer_capability(pdev->port); - /* - * Must lock access to Root Error Status Reg, Root Error ID Reg, - * and Root error producer/consumer index - */ - spin_lock_irqsave(&rpc->e_lock, flags); - - /* Read error status */ - pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, &status); - if (!(status & ROOT_ERR_STATUS_MASKS)) { - spin_unlock_irqrestore(&rpc->e_lock, flags); - return IRQ_NONE; - } - - /* Read error source and clear error status */ - pci_read_config_dword(pdev->port, pos + PCI_ERR_ROOT_COR_SRC, &id); - pci_write_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, status); - - /* Store error source for later DPC handler */ - next_prod_idx = rpc->prod_idx + 1; - if (next_prod_idx == AER_ERROR_SOURCES_MAX) - next_prod_idx = 0; - if (next_prod_idx == rpc->cons_idx) { - /* - * Error Storm Condition - possibly the same error occurred. - * Drop the error. - */ - spin_unlock_irqrestore(&rpc->e_lock, flags); - return IRQ_HANDLED; - } - rpc->e_sources[rpc->prod_idx].status = status; - rpc->e_sources[rpc->prod_idx].id = id; - rpc->prod_idx = next_prod_idx; - spin_unlock_irqrestore(&rpc->e_lock, flags); - - /* Invoke DPC handler */ - schedule_work(&rpc->dpc_handler); - - return IRQ_HANDLED; -} - -/** - * aer_alloc_rpc - allocate Root Port data structure - * @dev: pointer to the pcie_dev data structure - * - * Invoked when Root Port's AER service is loaded. - **/ -static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev) -{ - struct aer_rpc *rpc; - - if (!(rpc = (struct aer_rpc *)kmalloc(sizeof(struct aer_rpc), - GFP_KERNEL))) - return NULL; - - memset(rpc, 0, sizeof(struct aer_rpc)); - /* - * Initialize Root lock access, e_lock, to Root Error Status Reg, - * Root Error ID Reg, and Root error producer/consumer index. - */ - rpc->e_lock = SPIN_LOCK_UNLOCKED; - - rpc->rpd = dev; - INIT_WORK(&rpc->dpc_handler, aer_isr, (void *)dev); - rpc->prod_idx = rpc->cons_idx = 0; - mutex_init(&rpc->rpc_mutex); - init_waitqueue_head(&rpc->wait_release); - - /* Use PCIE bus function to store rpc into PCIE device */ - set_service_data(dev, rpc); - - return rpc; -} - -/** - * aer_remove - clean up resources - * @dev: pointer to the pcie_dev data structure - * - * Invoked when PCI Express bus unloads or AER probe fails. - **/ -static void aer_remove(struct pcie_device *dev) -{ - struct aer_rpc *rpc = get_service_data(dev); - - if (rpc) { - /* If register interrupt service, it must be free. */ - if (rpc->isr) - free_irq(dev->irq, dev); - - wait_event(rpc->wait_release, rpc->prod_idx == rpc->cons_idx); - - aer_delete_rootport(rpc); - set_service_data(dev, NULL); - } -} - -/** - * aer_probe - initialize resources - * @dev: pointer to the pcie_dev data structure - * @id: pointer to the service id data structure - * - * Invoked when PCI Express bus loads AER service driver. - **/ -static int __devinit aer_probe (struct pcie_device *dev, - const struct pcie_port_service_id *id ) -{ - int status; - struct aer_rpc *rpc; - struct device *device = &dev->device; - - /* Init */ - if ((status = aer_init(dev))) - return status; - - /* Alloc rpc data structure */ - if (!(rpc = aer_alloc_rpc(dev))) { - printk(KERN_DEBUG "%s: Alloc rpc fails on PCIE device[%s]\n", - __FUNCTION__, device->bus_id); - aer_remove(dev); - return -ENOMEM; - } - - /* Request IRQ ISR */ - if ((status = request_irq(dev->irq, aer_irq, SA_SHIRQ, "aerdrv", - dev))) { - printk(KERN_DEBUG "%s: Request ISR fails on PCIE device[%s]\n", - __FUNCTION__, device->bus_id); - aer_remove(dev); - return status; - } - - rpc->isr = 1; - - aer_enable_rootport(rpc); - - return status; -} - -/** - * aer_root_reset - reset link on Root Port - * @dev: pointer to Root Port's pci_dev data structure - * - * Invoked by Port Bus driver when performing link reset at Root Port. - **/ -static pci_ers_result_t aer_root_reset(struct pci_dev *dev) -{ - u16 p2p_ctrl; - u32 status; - int pos; - - pos = pci_find_aer_capability(dev); - - /* Disable Root's interrupt in response to error messages */ - pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, 0); - - /* Assert Secondary Bus Reset */ - pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl); - p2p_ctrl |= PCI_CB_BRIDGE_CTL_CB_RESET; - pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); - - /* De-assert Secondary Bus Reset */ - p2p_ctrl &= ~PCI_CB_BRIDGE_CTL_CB_RESET; - pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl); - - /* - * System software must wait for at least 100ms from the end - * of a reset of one or more device before it is permitted - * to issue Configuration Requests to those devices. - */ - msleep(200); - printk(KERN_DEBUG "Complete link reset at Root[%s]\n", dev->dev.bus_id); - - /* Enable Root Port's interrupt in response to error messages */ - pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &status); - pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, status); - pci_write_config_dword(dev, - pos + PCI_ERR_ROOT_COMMAND, - ROOT_PORT_INTR_ON_MESG_MASK); - - return PCI_ERS_RESULT_RECOVERED; -} - -/** - * aer_error_detected - update severity status - * @dev: pointer to Root Port's pci_dev data structure - * @error: error severity being notified by port bus - * - * Invoked by Port Bus driver during error recovery. - **/ -static pci_ers_result_t aer_error_detected(struct pci_dev *dev, - enum pci_channel_state error) -{ - /* Root Port has no impact. Always recovers. */ - return PCI_ERS_RESULT_CAN_RECOVER; -} - -/** - * aer_error_resume - clean up corresponding error status bits - * @dev: pointer to Root Port's pci_dev data structure - * - * Invoked by Port Bus driver during nonfatal recovery. - **/ -static void aer_error_resume(struct pci_dev *dev) -{ - int pos; - u32 status, mask; - u16 reg16; - - /* Clean up Root device status */ - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); - pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); - - /* Clean AER Root Error Status */ - pos = pci_find_aer_capability(dev); - pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); - pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); - if (dev->error_state == pci_channel_io_normal) - status &= ~mask; /* Clear corresponding nonfatal bits */ - else - status &= mask; /* Clear corresponding fatal bits */ - pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); -} - -/** - * aer_service_init - register AER root service driver - * - * Invoked when AER root service driver is loaded. - **/ -static int __init aer_service_init(void) -{ - return pcie_port_service_register(&aerdrv); -} - -/** - * aer_service_exit - unregister AER root service driver - * - * Invoked when AER root service driver is unloaded. - **/ -static void __exit aer_service_exit(void) -{ - pcie_port_service_unregister(&aerdrv); -} - -module_init(aer_service_init); -module_exit(aer_service_exit); diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.h b/trunk/drivers/pci/pcie/aer/aerdrv.h deleted file mode 100644 index daf0cad88fc8..000000000000 --- a/trunk/drivers/pci/pcie/aer/aerdrv.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2006 Intel Corp. - * Tom Long Nguyen (tom.l.nguyen@intel.com) - * Zhang Yanmin (yanmin.zhang@intel.com) - * - */ - -#ifndef _AERDRV_H_ -#define _AERDRV_H_ - -#include -#include - -#define AER_NONFATAL 0 -#define AER_FATAL 1 -#define AER_CORRECTABLE 2 -#define AER_UNCORRECTABLE 4 -#define AER_ERROR_MASK 0x001fffff -#define AER_ERROR(d) (d & AER_ERROR_MASK) - -#define OSC_METHOD_RUN_SUCCESS 0 -#define OSC_METHOD_NOT_SUPPORTED 1 -#define OSC_METHOD_RUN_FAILURE 2 - -/* Root Error Status Register Bits */ -#define ROOT_ERR_STATUS_MASKS 0x0f - -#define SYSTEM_ERROR_INTR_ON_MESG_MASK (PCI_EXP_RTCTL_SECEE| \ - PCI_EXP_RTCTL_SENFEE| \ - PCI_EXP_RTCTL_SEFEE) -#define ROOT_PORT_INTR_ON_MESG_MASK (PCI_ERR_ROOT_CMD_COR_EN| \ - PCI_ERR_ROOT_CMD_NONFATAL_EN| \ - PCI_ERR_ROOT_CMD_FATAL_EN) -#define ERR_COR_ID(d) (d & 0xffff) -#define ERR_UNCOR_ID(d) (d >> 16) - -#define AER_SUCCESS 0 -#define AER_UNSUCCESS 1 -#define AER_ERROR_SOURCES_MAX 100 - -#define AER_LOG_TLP_MASKS (PCI_ERR_UNC_POISON_TLP| \ - PCI_ERR_UNC_ECRC| \ - PCI_ERR_UNC_UNSUP| \ - PCI_ERR_UNC_COMP_ABORT| \ - PCI_ERR_UNC_UNX_COMP| \ - PCI_ERR_UNC_MALF_TLP) - -/* AER Error Info Flags */ -#define AER_TLP_HEADER_VALID_FLAG 0x00000001 -#define AER_MULTI_ERROR_VALID_FLAG 0x00000002 - -#define ERR_CORRECTABLE_ERROR_MASK 0x000031c1 -#define ERR_UNCORRECTABLE_ERROR_MASK 0x001ff010 - -struct header_log_regs { - unsigned int dw0; - unsigned int dw1; - unsigned int dw2; - unsigned int dw3; -}; - -struct aer_err_info { - int severity; /* 0:NONFATAL | 1:FATAL | 2:COR */ - int flags; - unsigned int status; /* COR/UNCOR Error Status */ - struct header_log_regs tlp; /* TLP Header */ -}; - -struct aer_err_source { - unsigned int status; - unsigned int id; -}; - -struct aer_rpc { - struct pcie_device *rpd; /* Root Port device */ - struct work_struct dpc_handler; - struct aer_err_source e_sources[AER_ERROR_SOURCES_MAX]; - unsigned short prod_idx; /* Error Producer Index */ - unsigned short cons_idx; /* Error Consumer Index */ - int isr; - spinlock_t e_lock; /* - * Lock access to Error Status/ID Regs - * and error producer/consumer index - */ - struct mutex rpc_mutex; /* - * only one thread could do - * recovery on the same - * root port hierachy - */ - wait_queue_head_t wait_release; -}; - -struct aer_broadcast_data { - enum pci_channel_state state; - enum pci_ers_result result; -}; - -static inline pci_ers_result_t merge_result(enum pci_ers_result orig, - enum pci_ers_result new) -{ - switch (orig) { - case PCI_ERS_RESULT_CAN_RECOVER: - case PCI_ERS_RESULT_RECOVERED: - orig = new; - break; - case PCI_ERS_RESULT_DISCONNECT: - if (new == PCI_ERS_RESULT_NEED_RESET) - orig = new; - break; - default: - break; - } - - return orig; -} - -extern struct bus_type pcie_port_bus_type; -extern void aer_enable_rootport(struct aer_rpc *rpc); -extern void aer_delete_rootport(struct aer_rpc *rpc); -extern int aer_init(struct pcie_device *dev); -extern void aer_isr(void *context); -extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); -extern int aer_osc_setup(struct pci_dev *dev); - -#endif //_AERDRV_H_ diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c b/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c deleted file mode 100644 index fa68e89ebec9..000000000000 --- a/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Access ACPI _OSC method - * - * Copyright (C) 2006 Intel Corp. - * Tom Long Nguyen (tom.l.nguyen@intel.com) - * Zhang Yanmin (yanmin.zhang@intel.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "aerdrv.h" - -/** - * aer_osc_setup - run ACPI _OSC method - * - * Return: - * Zero if success. Nonzero for otherwise. - * - * Invoked when PCIE bus loads AER service driver. To avoid conflict with - * BIOS AER support requires BIOS to yield AER control to OS native driver. - **/ -int aer_osc_setup(struct pci_dev *dev) -{ - int retval = OSC_METHOD_RUN_SUCCESS; - acpi_status status; - acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); - struct pci_dev *pdev = dev; - struct pci_bus *parent; - - while (!handle) { - if (!pdev || !pdev->bus->parent) - break; - parent = pdev->bus->parent; - if (!parent->self) - /* Parent must be a host bridge */ - handle = acpi_get_pci_rootbridge_handle( - pci_domain_nr(parent), - parent->number); - else - handle = DEVICE_ACPI_HANDLE( - &(parent->self->dev)); - pdev = parent->self; - } - - if (!handle) - return OSC_METHOD_NOT_SUPPORTED; - - pci_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT); - status = pci_osc_control_set(handle, OSC_PCI_EXPRESS_AER_CONTROL | - OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); - if (ACPI_FAILURE(status)) { - if (status == AE_SUPPORT) - retval = OSC_METHOD_NOT_SUPPORTED; - else - retval = OSC_METHOD_RUN_FAILURE; - } - - return retval; -} - diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c deleted file mode 100644 index 1c7e660d6535..000000000000 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ /dev/null @@ -1,758 +0,0 @@ -/* - * drivers/pci/pcie/aer/aerdrv_core.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * This file implements the core part of PCI-Express AER. When an pci-express - * error is delivered, an error message will be collected and printed to - * console, then, an error recovery procedure will be executed by following - * the pci error recovery rules. - * - * Copyright (C) 2006 Intel Corp. - * Tom Long Nguyen (tom.l.nguyen@intel.com) - * Zhang Yanmin (yanmin.zhang@intel.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "aerdrv.h" - -static int forceload; -module_param(forceload, bool, 0); - -#define PCI_CFG_SPACE_SIZE (0x100) -int pci_find_aer_capability(struct pci_dev *dev) -{ - int pos; - u32 reg32 = 0; - - /* Check if it's a pci-express device */ - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (!pos) - return 0; - - /* Check if it supports pci-express AER */ - pos = PCI_CFG_SPACE_SIZE; - while (pos) { - if (pci_read_config_dword(dev, pos, ®32)) - return 0; - - /* some broken boards return ~0 */ - if (reg32 == 0xffffffff) - return 0; - - if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR) - break; - - pos = reg32 >> 20; - } - - return pos; -} - -int pci_enable_pcie_error_reporting(struct pci_dev *dev) -{ - u16 reg16 = 0; - int pos; - - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (!pos) - return -EIO; - - pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, ®16); - reg16 = reg16 | - PCI_EXP_DEVCTL_CERE | - PCI_EXP_DEVCTL_NFERE | - PCI_EXP_DEVCTL_FERE | - PCI_EXP_DEVCTL_URRE; - pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, - reg16); - return 0; -} - -int pci_disable_pcie_error_reporting(struct pci_dev *dev) -{ - u16 reg16 = 0; - int pos; - - pos = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (!pos) - return -EIO; - - pci_read_config_word(dev, pos+PCI_EXP_DEVCTL, ®16); - reg16 = reg16 & ~(PCI_EXP_DEVCTL_CERE | - PCI_EXP_DEVCTL_NFERE | - PCI_EXP_DEVCTL_FERE | - PCI_EXP_DEVCTL_URRE); - pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, - reg16); - return 0; -} - -int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) -{ - int pos; - u32 status, mask; - - pos = pci_find_aer_capability(dev); - if (!pos) - return -EIO; - - pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); - pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); - if (dev->error_state == pci_channel_io_normal) - status &= ~mask; /* Clear corresponding nonfatal bits */ - else - status &= mask; /* Clear corresponding fatal bits */ - pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); - - return 0; -} - -static int find_device_iter(struct device *device, void *data) -{ - struct pci_dev *dev; - u16 id = *(unsigned long *)data; - u8 secondary, subordinate, d_bus = id >> 8; - - if (device->bus == &pci_bus_type) { - dev = to_pci_dev(device); - if (id == ((dev->bus->number << 8) | dev->devfn)) { - /* - * Device ID match - */ - *(unsigned long*)data = (unsigned long)device; - return 1; - } - - /* - * If device is P2P, check if it is an upstream? - */ - if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) { - pci_read_config_byte(dev, PCI_SECONDARY_BUS, - &secondary); - pci_read_config_byte(dev, PCI_SUBORDINATE_BUS, - &subordinate); - if (d_bus >= secondary && d_bus <= subordinate) { - *(unsigned long*)data = (unsigned long)device; - return 1; - } - } - } - - return 0; -} - -/** - * find_source_device - search through device hierarchy for source device - * @p_dev: pointer to Root Port pci_dev data structure - * @id: device ID of agent who sends an error message to this Root Port - * - * Invoked when error is detected at the Root Port. - **/ -static struct device* find_source_device(struct pci_dev *parent, u16 id) -{ - struct pci_dev *dev = parent; - struct device *device; - unsigned long device_addr; - int status; - - /* Is Root Port an agent that sends error message? */ - if (id == ((dev->bus->number << 8) | dev->devfn)) - return &dev->dev; - - do { - device_addr = id; - if ((status = device_for_each_child(&dev->dev, - &device_addr, find_device_iter))) { - device = (struct device*)device_addr; - dev = to_pci_dev(device); - if (id == ((dev->bus->number << 8) | dev->devfn)) - return device; - } - }while (status); - - return NULL; -} - -static void report_error_detected(struct pci_dev *dev, void *data) -{ - pci_ers_result_t vote; - struct pci_error_handlers *err_handler; - struct aer_broadcast_data *result_data; - result_data = (struct aer_broadcast_data *) data; - - dev->error_state = result_data->state; - - if (!dev->driver || - !dev->driver->err_handler || - !dev->driver->err_handler->error_detected) { - if (result_data->state == pci_channel_io_frozen && - !(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) { - /* - * In case of fatal recovery, if one of down- - * stream device has no driver. We might be - * unable to recover because a later insmod - * of a driver for this device is unaware of - * its hw state. - */ - printk(KERN_DEBUG "Device ID[%s] has %s\n", - dev->dev.bus_id, (dev->driver) ? - "no AER-aware driver" : "no driver"); - } - return; - } - - err_handler = dev->driver->err_handler; - vote = err_handler->error_detected(dev, result_data->state); - result_data->result = merge_result(result_data->result, vote); - return; -} - -static void report_mmio_enabled(struct pci_dev *dev, void *data) -{ - pci_ers_result_t vote; - struct pci_error_handlers *err_handler; - struct aer_broadcast_data *result_data; - result_data = (struct aer_broadcast_data *) data; - - if (!dev->driver || - !dev->driver->err_handler || - !dev->driver->err_handler->mmio_enabled) - return; - - err_handler = dev->driver->err_handler; - vote = err_handler->mmio_enabled(dev); - result_data->result = merge_result(result_data->result, vote); - return; -} - -static void report_slot_reset(struct pci_dev *dev, void *data) -{ - pci_ers_result_t vote; - struct pci_error_handlers *err_handler; - struct aer_broadcast_data *result_data; - result_data = (struct aer_broadcast_data *) data; - - if (!dev->driver || - !dev->driver->err_handler || - !dev->driver->err_handler->slot_reset) - return; - - err_handler = dev->driver->err_handler; - vote = err_handler->slot_reset(dev); - result_data->result = merge_result(result_data->result, vote); - return; -} - -static void report_resume(struct pci_dev *dev, void *data) -{ - struct pci_error_handlers *err_handler; - - dev->error_state = pci_channel_io_normal; - - if (!dev->driver || - !dev->driver->err_handler || - !dev->driver->err_handler->slot_reset) - return; - - err_handler = dev->driver->err_handler; - err_handler->resume(dev); - return; -} - -/** - * broadcast_error_message - handle message broadcast to downstream drivers - * @device: pointer to from where in a hierarchy message is broadcasted down - * @api: callback to be broadcasted - * @state: error state - * - * Invoked during error recovery process. Once being invoked, the content - * of error severity will be broadcasted to all downstream drivers in a - * hierarchy in question. - **/ -static pci_ers_result_t broadcast_error_message(struct pci_dev *dev, - enum pci_channel_state state, - char *error_mesg, - void (*cb)(struct pci_dev *, void *)) -{ - struct aer_broadcast_data result_data; - - printk(KERN_DEBUG "Broadcast %s message\n", error_mesg); - result_data.state = state; - if (cb == report_error_detected) - result_data.result = PCI_ERS_RESULT_CAN_RECOVER; - else - result_data.result = PCI_ERS_RESULT_RECOVERED; - - if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) { - /* - * If the error is reported by a bridge, we think this error - * is related to the downstream link of the bridge, so we - * do error recovery on all subordinates of the bridge instead - * of the bridge and clear the error status of the bridge. - */ - if (cb == report_error_detected) - dev->error_state = state; - pci_walk_bus(dev->subordinate, cb, &result_data); - if (cb == report_resume) { - pci_cleanup_aer_uncorrect_error_status(dev); - dev->error_state = pci_channel_io_normal; - } - } - else { - /* - * If the error is reported by an end point, we think this - * error is related to the upstream link of the end point. - */ - pci_walk_bus(dev->bus, cb, &result_data); - } - - return result_data.result; -} - -struct find_aer_service_data { - struct pcie_port_service_driver *aer_driver; - int is_downstream; -}; - -static int find_aer_service_iter(struct device *device, void *data) -{ - struct device_driver *driver; - struct pcie_port_service_driver *service_driver; - struct pcie_device *pcie_dev; - struct find_aer_service_data *result; - - result = (struct find_aer_service_data *) data; - - if (device->bus == &pcie_port_bus_type) { - pcie_dev = to_pcie_device(device); - if (pcie_dev->id.port_type == PCIE_SW_DOWNSTREAM_PORT) - result->is_downstream = 1; - - driver = device->driver; - if (driver) { - service_driver = to_service_driver(driver); - if (service_driver->id_table->service_type == - PCIE_PORT_SERVICE_AER) { - result->aer_driver = service_driver; - return 1; - } - } - } - - return 0; -} - -static void find_aer_service(struct pci_dev *dev, - struct find_aer_service_data *data) -{ - int retval; - retval = device_for_each_child(&dev->dev, data, find_aer_service_iter); -} - -static pci_ers_result_t reset_link(struct pcie_device *aerdev, - struct pci_dev *dev) -{ - struct pci_dev *udev; - pci_ers_result_t status; - struct find_aer_service_data data; - - if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE) - udev = dev; - else - udev= dev->bus->self; - - data.is_downstream = 0; - data.aer_driver = NULL; - find_aer_service(udev, &data); - - /* - * Use the aer driver of the error agent firstly. - * If it hasn't the aer driver, use the root port's - */ - if (!data.aer_driver || !data.aer_driver->reset_link) { - if (data.is_downstream && - aerdev->device.driver && - to_service_driver(aerdev->device.driver)->reset_link) { - data.aer_driver = - to_service_driver(aerdev->device.driver); - } else { - printk(KERN_DEBUG "No link-reset support to Device ID" - "[%s]\n", - dev->dev.bus_id); - return PCI_ERS_RESULT_DISCONNECT; - } - } - - status = data.aer_driver->reset_link(udev); - if (status != PCI_ERS_RESULT_RECOVERED) { - printk(KERN_DEBUG "Link reset at upstream Device ID" - "[%s] failed\n", - udev->dev.bus_id); - return PCI_ERS_RESULT_DISCONNECT; - } - - return status; -} - -/** - * do_recovery - handle nonfatal/fatal error recovery process - * @aerdev: pointer to a pcie_device data structure of root port - * @dev: pointer to a pci_dev data structure of agent detecting an error - * @severity: error severity type - * - * Invoked when an error is nonfatal/fatal. Once being invoked, broadcast - * error detected message to all downstream drivers within a hierarchy in - * question and return the returned code. - **/ -static pci_ers_result_t do_recovery(struct pcie_device *aerdev, - struct pci_dev *dev, - int severity) -{ - pci_ers_result_t status, result = PCI_ERS_RESULT_RECOVERED; - enum pci_channel_state state; - - if (severity == AER_FATAL) - state = pci_channel_io_frozen; - else - state = pci_channel_io_normal; - - status = broadcast_error_message(dev, - state, - "error_detected", - report_error_detected); - - if (severity == AER_FATAL) { - result = reset_link(aerdev, dev); - if (result != PCI_ERS_RESULT_RECOVERED) { - /* TODO: Should panic here? */ - return result; - } - } - - if (status == PCI_ERS_RESULT_CAN_RECOVER) - status = broadcast_error_message(dev, - state, - "mmio_enabled", - report_mmio_enabled); - - if (status == PCI_ERS_RESULT_NEED_RESET) { - /* - * TODO: Should call platform-specific - * functions to reset slot before calling - * drivers' slot_reset callbacks? - */ - status = broadcast_error_message(dev, - state, - "slot_reset", - report_slot_reset); - } - - if (status == PCI_ERS_RESULT_RECOVERED) - broadcast_error_message(dev, - state, - "resume", - report_resume); - - return status; -} - -/** - * handle_error_source - handle logging error into an event log - * @aerdev: pointer to pcie_device data structure of the root port - * @dev: pointer to pci_dev data structure of error source device - * @info: comprehensive error information - * - * Invoked when an error being detected by Root Port. - **/ -static void handle_error_source(struct pcie_device * aerdev, - struct pci_dev *dev, - struct aer_err_info info) -{ - pci_ers_result_t status = 0; - int pos; - - if (info.severity == AER_CORRECTABLE) { - /* - * Correctable error does not need software intevention. - * No need to go through error recovery process. - */ - pos = pci_find_aer_capability(dev); - if (pos) - pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, - info.status); - } else { - status = do_recovery(aerdev, dev, info.severity); - if (status == PCI_ERS_RESULT_RECOVERED) { - printk(KERN_DEBUG "AER driver successfully recovered\n"); - } else { - /* TODO: Should kernel panic here? */ - printk(KERN_DEBUG "AER driver didn't recover\n"); - } - } -} - -/** - * aer_enable_rootport - enable Root Port's interrupts when receiving messages - * @rpc: pointer to a Root Port data structure - * - * Invoked when PCIE bus loads AER service driver. - **/ -void aer_enable_rootport(struct aer_rpc *rpc) -{ - struct pci_dev *pdev = rpc->rpd->port; - int pos, aer_pos; - u16 reg16; - u32 reg32; - - pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); - /* Clear PCIE Capability's Device Status */ - pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); - pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); - - /* Disable system error generation in response to error messages */ - pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, ®16); - reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); - pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); - - aer_pos = pci_find_aer_capability(pdev); - /* Clear error status */ - pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, ®32); - pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); - pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, ®32); - pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32); - pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); - pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); - - /* Enable Root Port device reporting error itself */ - pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, ®16); - reg16 = reg16 | - PCI_EXP_DEVCTL_CERE | - PCI_EXP_DEVCTL_NFERE | - PCI_EXP_DEVCTL_FERE | - PCI_EXP_DEVCTL_URRE; - pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL, - reg16); - - /* Enable Root Port's interrupt in response to error messages */ - pci_write_config_dword(pdev, - aer_pos + PCI_ERR_ROOT_COMMAND, - ROOT_PORT_INTR_ON_MESG_MASK); -} - -/** - * disable_root_aer - disable Root Port's interrupts when receiving messages - * @rpc: pointer to a Root Port data structure - * - * Invoked when PCIE bus unloads AER service driver. - **/ -static void disable_root_aer(struct aer_rpc *rpc) -{ - struct pci_dev *pdev = rpc->rpd->port; - u32 reg32; - int pos; - - pos = pci_find_aer_capability(pdev); - /* Disable Root's interrupt in response to error messages */ - pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); - - /* Clear Root's error status reg */ - pci_read_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, ®32); - pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_STATUS, reg32); -} - -/** - * get_e_source - retrieve an error source - * @rpc: pointer to the root port which holds an error - * - * Invoked by DPC handler to consume an error. - **/ -static struct aer_err_source* get_e_source(struct aer_rpc *rpc) -{ - struct aer_err_source *e_source; - unsigned long flags; - - /* Lock access to Root error producer/consumer index */ - spin_lock_irqsave(&rpc->e_lock, flags); - if (rpc->prod_idx == rpc->cons_idx) { - spin_unlock_irqrestore(&rpc->e_lock, flags); - return NULL; - } - e_source = &rpc->e_sources[rpc->cons_idx]; - rpc->cons_idx++; - if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) - rpc->cons_idx = 0; - spin_unlock_irqrestore(&rpc->e_lock, flags); - - return e_source; -} - -static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) -{ - int pos; - - pos = pci_find_aer_capability(dev); - - /* The device might not support AER */ - if (!pos) - return AER_SUCCESS; - - if (info->severity == AER_CORRECTABLE) { - pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, - &info->status); - if (!(info->status & ERR_CORRECTABLE_ERROR_MASK)) - return AER_UNSUCCESS; - } else if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE || - info->severity == AER_NONFATAL) { - - /* Link is still healthy for IO reads */ - pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, - &info->status); - if (!(info->status & ERR_UNCORRECTABLE_ERROR_MASK)) - return AER_UNSUCCESS; - - if (info->status & AER_LOG_TLP_MASKS) { - info->flags |= AER_TLP_HEADER_VALID_FLAG; - pci_read_config_dword(dev, - pos + PCI_ERR_HEADER_LOG, &info->tlp.dw0); - pci_read_config_dword(dev, - pos + PCI_ERR_HEADER_LOG + 4, &info->tlp.dw1); - pci_read_config_dword(dev, - pos + PCI_ERR_HEADER_LOG + 8, &info->tlp.dw2); - pci_read_config_dword(dev, - pos + PCI_ERR_HEADER_LOG + 12, &info->tlp.dw3); - } - } - - return AER_SUCCESS; -} - -/** - * aer_isr_one_error - consume an error detected by root port - * @p_device: pointer to error root port service device - * @e_src: pointer to an error source - **/ -static void aer_isr_one_error(struct pcie_device *p_device, - struct aer_err_source *e_src) -{ - struct device *s_device; - struct aer_err_info e_info = {0, 0, 0,}; - int i; - u16 id; - - /* - * There is a possibility that both correctable error and - * uncorrectable error being logged. Report correctable error first. - */ - for (i = 1; i & ROOT_ERR_STATUS_MASKS ; i <<= 2) { - if (i > 4) - break; - if (!(e_src->status & i)) - continue; - - /* Init comprehensive error information */ - if (i & PCI_ERR_ROOT_COR_RCV) { - id = ERR_COR_ID(e_src->id); - e_info.severity = AER_CORRECTABLE; - } else { - id = ERR_UNCOR_ID(e_src->id); - e_info.severity = ((e_src->status >> 6) & 1); - } - if (e_src->status & - (PCI_ERR_ROOT_MULTI_COR_RCV | - PCI_ERR_ROOT_MULTI_UNCOR_RCV)) - e_info.flags |= AER_MULTI_ERROR_VALID_FLAG; - if (!(s_device = find_source_device(p_device->port, id))) { - printk(KERN_DEBUG "%s->can't find device of ID%04x\n", - __FUNCTION__, id); - continue; - } - if (get_device_error_info(to_pci_dev(s_device), &e_info) == - AER_SUCCESS) { - aer_print_error(to_pci_dev(s_device), &e_info); - handle_error_source(p_device, - to_pci_dev(s_device), - e_info); - } - } -} - -/** - * aer_isr - consume errors detected by root port - * @context: pointer to a private data of pcie device - * - * Invoked, as DPC, when root port records new detected error - **/ -void aer_isr(void *context) -{ - struct pcie_device *p_device = (struct pcie_device *) context; - struct aer_rpc *rpc = get_service_data(p_device); - struct aer_err_source *e_src; - - mutex_lock(&rpc->rpc_mutex); - e_src = get_e_source(rpc); - while (e_src) { - aer_isr_one_error(p_device, e_src); - e_src = get_e_source(rpc); - } - mutex_unlock(&rpc->rpc_mutex); - - wake_up(&rpc->wait_release); -} - -/** - * aer_delete_rootport - disable root port aer and delete service data - * @rpc: pointer to a root port device being deleted - * - * Invoked when AER service unloaded on a specific Root Port - **/ -void aer_delete_rootport(struct aer_rpc *rpc) -{ - /* Disable root port AER itself */ - disable_root_aer(rpc); - - kfree(rpc); -} - -/** - * aer_init - provide AER initialization - * @dev: pointer to AER pcie device - * - * Invoked when AER service driver is loaded. - **/ -int aer_init(struct pcie_device *dev) -{ - int status; - - /* Run _OSC Method */ - status = aer_osc_setup(dev->port); - - if(status != OSC_METHOD_RUN_SUCCESS) { - printk(KERN_DEBUG "%s: AER service init fails - %s\n", - __FUNCTION__, - (status == OSC_METHOD_NOT_SUPPORTED) ? - "No ACPI _OSC support" : "Run ACPI _OSC fails"); - - if (!forceload) - return status; - } - - return AER_SUCCESS; -} - -EXPORT_SYMBOL_GPL(pci_find_aer_capability); -EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting); -EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); -EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); - diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_errprint.c b/trunk/drivers/pci/pcie/aer/aerdrv_errprint.c deleted file mode 100644 index 3933d4f30e8c..000000000000 --- a/trunk/drivers/pci/pcie/aer/aerdrv_errprint.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * drivers/pci/pcie/aer/aerdrv_errprint.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Format error messages and print them to console. - * - * Copyright (C) 2006 Intel Corp. - * Tom Long Nguyen (tom.l.nguyen@intel.com) - * Zhang Yanmin (yanmin.zhang@intel.com) - * - */ - -#include -#include -#include -#include -#include -#include - -#include "aerdrv.h" - -#define AER_AGENT_RECEIVER 0 -#define AER_AGENT_REQUESTER 1 -#define AER_AGENT_COMPLETER 2 -#define AER_AGENT_TRANSMITTER 3 - -#define AER_AGENT_REQUESTER_MASK (PCI_ERR_UNC_COMP_TIME| \ - PCI_ERR_UNC_UNSUP) - -#define AER_AGENT_COMPLETER_MASK PCI_ERR_UNC_COMP_ABORT - -#define AER_AGENT_TRANSMITTER_MASK(t, e) (e & (PCI_ERR_COR_REP_ROLL| \ - ((t == AER_CORRECTABLE) ? PCI_ERR_COR_REP_TIMER: 0))) - -#define AER_GET_AGENT(t, e) \ - ((e & AER_AGENT_COMPLETER_MASK) ? AER_AGENT_COMPLETER : \ - (e & AER_AGENT_REQUESTER_MASK) ? AER_AGENT_REQUESTER : \ - (AER_AGENT_TRANSMITTER_MASK(t, e)) ? AER_AGENT_TRANSMITTER : \ - AER_AGENT_RECEIVER) - -#define AER_PHYSICAL_LAYER_ERROR_MASK PCI_ERR_COR_RCVR -#define AER_DATA_LINK_LAYER_ERROR_MASK(t, e) \ - (PCI_ERR_UNC_DLP| \ - PCI_ERR_COR_BAD_TLP| \ - PCI_ERR_COR_BAD_DLLP| \ - PCI_ERR_COR_REP_ROLL| \ - ((t == AER_CORRECTABLE) ? \ - PCI_ERR_COR_REP_TIMER: 0)) - -#define AER_PHYSICAL_LAYER_ERROR 0 -#define AER_DATA_LINK_LAYER_ERROR 1 -#define AER_TRANSACTION_LAYER_ERROR 2 - -#define AER_GET_LAYER_ERROR(t, e) \ - ((e & AER_PHYSICAL_LAYER_ERROR_MASK) ? \ - AER_PHYSICAL_LAYER_ERROR : \ - (e & AER_DATA_LINK_LAYER_ERROR_MASK(t, e)) ? \ - AER_DATA_LINK_LAYER_ERROR : \ - AER_TRANSACTION_LAYER_ERROR) - -/* - * AER error strings - */ -static char* aer_error_severity_string[] = { - "Uncorrected (Non-Fatal)", - "Uncorrected (Fatal)", - "Corrected" -}; - -static char* aer_error_layer[] = { - "Physical Layer", - "Data Link Layer", - "Transaction Layer" -}; -static char* aer_correctable_error_string[] = { - "Receiver Error ", /* Bit Position 0 */ - NULL, - NULL, - NULL, - NULL, - NULL, - "Bad TLP ", /* Bit Position 6 */ - "Bad DLLP ", /* Bit Position 7 */ - "RELAY_NUM Rollover ", /* Bit Position 8 */ - NULL, - NULL, - NULL, - "Replay Timer Timeout ", /* Bit Position 12 */ - "Advisory Non-Fatal ", /* Bit Position 13 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; - -static char* aer_uncorrectable_error_string[] = { - NULL, - NULL, - NULL, - NULL, - "Data Link Protocol ", /* Bit Position 4 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "Poisoned TLP ", /* Bit Position 12 */ - "Flow Control Protocol ", /* Bit Position 13 */ - "Completion Timeout ", /* Bit Position 14 */ - "Completer Abort ", /* Bit Position 15 */ - "Unexpected Completion ", /* Bit Position 16 */ - "Receiver Overflow ", /* Bit Position 17 */ - "Malformed TLP ", /* Bit Position 18 */ - "ECRC ", /* Bit Position 19 */ - "Unsupported Request ", /* Bit Position 20 */ - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; - -static char* aer_agent_string[] = { - "Receiver ID", - "Requester ID", - "Completer ID", - "Transmitter ID" -}; - -static char * aer_get_error_source_name(int severity, - unsigned int status, - char errmsg_buff[]) -{ - int i; - char * errmsg = NULL; - - for (i = 0; i < 32; i++) { - if (!(status & (1 << i))) - continue; - - if (severity == AER_CORRECTABLE) - errmsg = aer_correctable_error_string[i]; - else - errmsg = aer_uncorrectable_error_string[i]; - - if (!errmsg) { - sprintf(errmsg_buff, "Unknown Error Bit %2d ", i); - errmsg = errmsg_buff; - } - - break; - } - - return errmsg; -} - -static DEFINE_SPINLOCK(logbuf_lock); -static char errmsg_buff[100]; -void aer_print_error(struct pci_dev *dev, struct aer_err_info *info) -{ - char * errmsg; - int err_layer, agent; - char * loglevel; - - if (info->severity == AER_CORRECTABLE) - loglevel = KERN_WARNING; - else - loglevel = KERN_ERR; - - printk("%s+------ PCI-Express Device Error ------+\n", loglevel); - printk("%sError Severity\t\t: %s\n", loglevel, - aer_error_severity_string[info->severity]); - - if ( info->status == 0) { - printk("%sPCIE Bus Error type\t: (Unaccessible)\n", loglevel); - printk("%sUnaccessible Received\t: %s\n", loglevel, - info->flags & AER_MULTI_ERROR_VALID_FLAG ? - "Multiple" : "First"); - printk("%sUnregistered Agent ID\t: %04x\n", loglevel, - (dev->bus->number << 8) | dev->devfn); - } else { - err_layer = AER_GET_LAYER_ERROR(info->severity, info->status); - printk("%sPCIE Bus Error type\t: %s\n", loglevel, - aer_error_layer[err_layer]); - - spin_lock(&logbuf_lock); - errmsg = aer_get_error_source_name(info->severity, - info->status, - errmsg_buff); - printk("%s%s\t: %s\n", loglevel, errmsg, - info->flags & AER_MULTI_ERROR_VALID_FLAG ? - "Multiple" : "First"); - spin_unlock(&logbuf_lock); - - agent = AER_GET_AGENT(info->severity, info->status); - printk("%s%s\t\t: %04x\n", loglevel, - aer_agent_string[agent], - (dev->bus->number << 8) | dev->devfn); - - printk("%sVendorID=%04xh, DeviceID=%04xh," - " Bus=%02xh, Device=%02xh, Function=%02xh\n", - loglevel, - dev->vendor, - dev->device, - dev->bus->number, - PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn)); - - if (info->flags & AER_TLP_HEADER_VALID_FLAG) { - unsigned char *tlp = (unsigned char *) &info->tlp; - printk("%sTLB Header:\n", loglevel); - printk("%s%02x%02x%02x%02x %02x%02x%02x%02x" - " %02x%02x%02x%02x %02x%02x%02x%02x\n", - loglevel, - *(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp, - *(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4), - *(tlp + 11), *(tlp + 10), *(tlp + 9), - *(tlp + 8), *(tlp + 15), *(tlp + 14), - *(tlp + 13), *(tlp + 12)); - } - } -} - diff --git a/trunk/drivers/pci/pcie/portdrv.h b/trunk/drivers/pci/pcie/portdrv.h index 67fcd176babd..1d317d22ee89 100644 --- a/trunk/drivers/pci/pcie/portdrv.h +++ b/trunk/drivers/pci/pcie/portdrv.h @@ -39,7 +39,7 @@ extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state); extern int pcie_port_device_resume(struct pci_dev *dev); #endif extern void pcie_port_device_remove(struct pci_dev *dev); -extern int pcie_port_bus_register(void); +extern void pcie_port_bus_register(void); extern void pcie_port_bus_unregister(void); #endif /* _PORTDRV_H_ */ diff --git a/trunk/drivers/pci/pcie/portdrv_bus.c b/trunk/drivers/pci/pcie/portdrv_bus.c index 3f0976868eda..3e84b501e6a4 100644 --- a/trunk/drivers/pci/pcie/portdrv_bus.c +++ b/trunk/drivers/pci/pcie/portdrv_bus.c @@ -24,7 +24,6 @@ struct bus_type pcie_port_bus_type = { .suspend = pcie_port_bus_suspend, .resume = pcie_port_bus_resume, }; -EXPORT_SYMBOL_GPL(pcie_port_bus_type); static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) { diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index bd6615b4d40e..55c662267868 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -6,7 +6,6 @@ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) */ -#include #include #include #include @@ -340,7 +339,8 @@ static int suspend_iter(struct device *dev, void *data) int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state) { - return device_for_each_child(&dev->dev, &state, suspend_iter); + device_for_each_child(&dev->dev, &state, suspend_iter); + return 0; } static int resume_iter(struct device *dev, void *data) @@ -358,7 +358,8 @@ static int resume_iter(struct device *dev, void *data) int pcie_port_device_resume(struct pci_dev *dev) { - return device_for_each_child(&dev->dev, NULL, resume_iter); + device_for_each_child(&dev->dev, NULL, resume_iter); + return 0; } #endif @@ -401,9 +402,9 @@ void pcie_port_device_remove(struct pci_dev *dev) pci_disable_msi(dev); } -int __must_check pcie_port_bus_register(void) +void pcie_port_bus_register(void) { - return bus_register(&pcie_port_bus_type); + bus_register(&pcie_port_bus_type); } void pcie_port_bus_unregister(void) diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index 037690e08f5f..478d0d28f7ad 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -14,10 +14,8 @@ #include #include #include -#include #include "portdrv.h" -#include "aer/aerdrv.h" /* * Version Information @@ -32,43 +30,6 @@ MODULE_LICENSE("GPL"); /* global data */ static const char device_name[] = "pcieport-driver"; -static int pcie_portdrv_save_config(struct pci_dev *dev) -{ - return pci_save_state(dev); -} - -#ifdef CONFIG_PM -static int pcie_portdrv_restore_config(struct pci_dev *dev) -{ - int retval; - - pci_restore_state(dev); - retval = pci_enable_device(dev); - if (retval) - return retval; - pci_set_master(dev); - return 0; -} - -static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) -{ - int ret = pcie_port_device_suspend(dev, state); - - if (!ret) - ret = pcie_portdrv_save_config(dev); - return ret; -} - -static int pcie_portdrv_resume(struct pci_dev *dev) -{ - pcie_portdrv_restore_config(dev); - return pcie_port_device_resume(dev); -} -#else -#define pcie_portdrv_suspend NULL -#define pcie_portdrv_resume NULL -#endif - /* * pcie_portdrv_probe - Probe PCI-Express port devices * @dev: PCI-Express port device being probed @@ -100,10 +61,6 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, return -ENOMEM; } - pcie_portdrv_save_config(dev); - - pci_enable_pcie_error_reporting(dev); - return 0; } @@ -113,151 +70,39 @@ static void pcie_portdrv_remove (struct pci_dev *dev) kfree(pci_get_drvdata(dev)); } -static int error_detected_iter(struct device *device, void *data) -{ - struct pcie_device *pcie_device; - struct pcie_port_service_driver *driver; - struct aer_broadcast_data *result_data; - pci_ers_result_t status; - - result_data = (struct aer_broadcast_data *) data; - - if (device->bus == &pcie_port_bus_type && device->driver) { - driver = to_service_driver(device->driver); - if (!driver || - !driver->err_handler || - !driver->err_handler->error_detected) - return 0; - - pcie_device = to_pcie_device(device); - - /* Forward error detected message to service drivers */ - status = driver->err_handler->error_detected( - pcie_device->port, - result_data->state); - result_data->result = - merge_result(result_data->result, status); - } - - return 0; -} - -static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, - enum pci_channel_state error) -{ - struct aer_broadcast_data result_data = - {error, PCI_ERS_RESULT_CAN_RECOVER}; - int retval; - - /* can not fail */ - retval = device_for_each_child(&dev->dev, &result_data, error_detected_iter); - - return result_data.result; -} - -static int mmio_enabled_iter(struct device *device, void *data) +#ifdef CONFIG_PM +static int pcie_portdrv_save_config(struct pci_dev *dev) { - struct pcie_device *pcie_device; - struct pcie_port_service_driver *driver; - pci_ers_result_t status, *result; - - result = (pci_ers_result_t *) data; - - if (device->bus == &pcie_port_bus_type && device->driver) { - driver = to_service_driver(device->driver); - if (driver && - driver->err_handler && - driver->err_handler->mmio_enabled) { - pcie_device = to_pcie_device(device); - - /* Forward error message to service drivers */ - status = driver->err_handler->mmio_enabled( - pcie_device->port); - *result = merge_result(*result, status); - } - } - - return 0; + return pci_save_state(dev); } -static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) +static int pcie_portdrv_restore_config(struct pci_dev *dev) { - pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; int retval; - /* get true return value from &status */ - retval = device_for_each_child(&dev->dev, &status, mmio_enabled_iter); - return status; -} - -static int slot_reset_iter(struct device *device, void *data) -{ - struct pcie_device *pcie_device; - struct pcie_port_service_driver *driver; - pci_ers_result_t status, *result; - - result = (pci_ers_result_t *) data; - - if (device->bus == &pcie_port_bus_type && device->driver) { - driver = to_service_driver(device->driver); - if (driver && - driver->err_handler && - driver->err_handler->slot_reset) { - pcie_device = to_pcie_device(device); - - /* Forward error message to service drivers */ - status = driver->err_handler->slot_reset( - pcie_device->port); - *result = merge_result(*result, status); - } - } - + pci_restore_state(dev); + retval = pci_enable_device(dev); + if (retval) + return retval; + pci_set_master(dev); return 0; } -static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) +static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state) { - pci_ers_result_t status; - int retval; - - /* If fatal, restore cfg space for possible link reset at upstream */ - if (dev->error_state == pci_channel_io_frozen) { - pcie_portdrv_restore_config(dev); - pci_enable_pcie_error_reporting(dev); - } - - /* get true return value from &status */ - retval = device_for_each_child(&dev->dev, &status, slot_reset_iter); - - return status; -} - -static int resume_iter(struct device *device, void *data) -{ - struct pcie_device *pcie_device; - struct pcie_port_service_driver *driver; - - if (device->bus == &pcie_port_bus_type && device->driver) { - driver = to_service_driver(device->driver); - if (driver && - driver->err_handler && - driver->err_handler->resume) { - pcie_device = to_pcie_device(device); - - /* Forward error message to service drivers */ - driver->err_handler->resume(pcie_device->port); - } - } + int ret = pcie_port_device_suspend(dev, state); - return 0; + if (!ret) + ret = pcie_portdrv_save_config(dev); + return ret; } -static void pcie_portdrv_err_resume(struct pci_dev *dev) +static int pcie_portdrv_resume (struct pci_dev *dev) { - int retval; - /* nothing to do with error value, if it ever happens */ - retval = device_for_each_child(&dev->dev, NULL, resume_iter); + pcie_portdrv_restore_config(dev); + return pcie_port_device_resume(dev); } +#endif /* * LINUX Device Driver Model @@ -269,13 +114,6 @@ static const struct pci_device_id port_pci_ids[] = { { }; MODULE_DEVICE_TABLE(pci, port_pci_ids); -static struct pci_error_handlers pcie_portdrv_err_handler = { - .error_detected = pcie_portdrv_error_detected, - .mmio_enabled = pcie_portdrv_mmio_enabled, - .slot_reset = pcie_portdrv_slot_reset, - .resume = pcie_portdrv_err_resume, -}; - static struct pci_driver pcie_portdrv = { .name = (char *)device_name, .id_table = &port_pci_ids[0], @@ -283,25 +121,20 @@ static struct pci_driver pcie_portdrv = { .probe = pcie_portdrv_probe, .remove = pcie_portdrv_remove, +#ifdef CONFIG_PM .suspend = pcie_portdrv_suspend, .resume = pcie_portdrv_resume, - - .err_handler = &pcie_portdrv_err_handler, +#endif /* PM */ }; static int __init pcie_portdrv_init(void) { - int retval; + int retval = 0; - retval = pcie_port_bus_register(); - if (retval) { - printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval); - goto out; - } + pcie_port_bus_register(); retval = pci_register_driver(&pcie_portdrv); if (retval) pcie_port_bus_unregister(); - out: return retval; } diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index a3b0a5eb5054..c5a58d1c6c1c 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -339,7 +339,6 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) { struct pci_bus *child; int i; - int retval; /* * Allocate a new bus, and inherit stuff from the parent.. @@ -357,13 +356,8 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) child->class_dev.class = &pcibus_class; sprintf(child->class_dev.class_id, "%04x:%02x", pci_domain_nr(child), busnr); - retval = class_device_register(&child->class_dev); - if (retval) - goto error_register; - retval = class_device_create_file(&child->class_dev, - &class_device_attr_cpuaffinity); - if (retval) - goto error_file_create; + class_device_register(&child->class_dev); + class_device_create_file(&child->class_dev, &class_device_attr_cpuaffinity); /* * Set up the primary, secondary and subordinate @@ -381,12 +375,6 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) bridge->subordinate = child; return child; - -error_file_create: - class_device_unregister(&child->class_dev); -error_register: - kfree(child); - return NULL; } struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 08cd86a6dd66..def78a2a7c15 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -577,6 +577,8 @@ static void __init quirk_ioapic_rmw(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw ); +int pci_msi_quirk; + #define AMD8131_revA0 0x01 #define AMD8131_revB0 0x11 #define AMD8131_MISC 0x40 @@ -585,6 +587,12 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) { unsigned char revid, tmp; + if (dev->subordinate) { + printk(KERN_WARNING "PCI: MSI quirk detected. " + "PCI_BUS_FLAGS_NO_MSI set for subordinate bus.\n"); + dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; + } + if (nr_ioapics == 0) return; @@ -597,6 +605,13 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); + +static void __init quirk_svw_msi(struct pci_dev *dev) +{ + pci_msi_quirk = 1; + printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n"); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi ); #endif /* CONFIG_X86_IO_APIC */ @@ -1675,95 +1690,6 @@ static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_pcie_aer_ext_cap); -#ifdef CONFIG_PCI_MSI -/* To disable MSI globally */ -int pci_msi_quirk; - -/* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely - * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually - * some other busses controlled by the chipset even if Linux is not aware of it. - * Instead of setting the flag on all busses in the machine, simply disable MSI - * globally. - */ -static void __init quirk_svw_msi(struct pci_dev *dev) -{ - pci_msi_quirk = 1; - printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n"); -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi); - -/* Disable MSI on chipsets that are known to not support it */ -static void __devinit quirk_disable_msi(struct pci_dev *dev) -{ - if (dev->subordinate) { - printk(KERN_WARNING "PCI: MSI quirk detected. " - "PCI_BUS_FLAGS_NO_MSI set for %s subordinate bus.\n", - pci_name(dev)); - dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; - } -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); - -/* Go through the list of Hypertransport capabilities and - * return 1 if a HT MSI capability is found and enabled */ -static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) -{ - u8 pos; - int ttl; - for (pos = pci_find_capability(dev, PCI_CAP_ID_HT), ttl = 48; - pos && ttl; - pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT), ttl--) { - u32 cap_hdr; - /* MSI mapping section according to Hypertransport spec */ - if (pci_read_config_dword(dev, pos, &cap_hdr) == 0 - && (cap_hdr & 0xf8000000) == 0xa8000000 /* MSI mapping */) { - printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n", - pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled"); - return (cap_hdr & 0x10000) != 0; /* MSI mapping cap enabled */ - } - } - return 0; -} - -/* Check the hypertransport MSI mapping to know whether MSI is enabled or not */ -static void __devinit quirk_msi_ht_cap(struct pci_dev *dev) -{ - if (dev->subordinate && !msi_ht_cap_enabled(dev)) { - printk(KERN_WARNING "PCI: MSI quirk detected. " - "MSI disabled on chipset %s.\n", - pci_name(dev)); - dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; - } -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, - quirk_msi_ht_cap); - -/* The nVidia CK804 chipset may have 2 HT MSI mappings. - * MSI are supported if the MSI capability set in any of these mappings. - */ -static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) -{ - struct pci_dev *pdev; - - if (!dev->subordinate) - return; - - /* check HT MSI cap on this chipset and the root one. - * a single one having MSI is enough to be sure that MSI are supported. - */ - pdev = pci_find_slot(dev->bus->number, 0); - if (dev->subordinate && !msi_ht_cap_enabled(dev) - && !msi_ht_cap_enabled(pdev)) { - printk(KERN_WARNING "PCI: MSI quirk detected. " - "MSI disabled on chipset %s.\n", - pci_name(dev)); - dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; - } -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, - quirk_nvidia_ck804_msi_ht_cap); -#endif /* CONFIG_PCI_MSI */ - EXPORT_SYMBOL(pcie_mch_quirk); #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pci_fixup_device); diff --git a/trunk/drivers/pci/remove.c b/trunk/drivers/pci/remove.c index 430281b2e921..99ffbd478b29 100644 --- a/trunk/drivers/pci/remove.c +++ b/trunk/drivers/pci/remove.c @@ -16,11 +16,8 @@ static void pci_free_resources(struct pci_dev *dev) } } -static void pci_stop_dev(struct pci_dev *dev) +static void pci_destroy_dev(struct pci_dev *dev) { - if (!dev->global_list.next) - return; - if (!list_empty(&dev->global_list)) { pci_proc_detach_device(dev); pci_remove_sysfs_dev_files(dev); @@ -30,11 +27,6 @@ static void pci_stop_dev(struct pci_dev *dev) dev->global_list.next = dev->global_list.prev = NULL; up_write(&pci_bus_sem); } -} - -static void pci_destroy_dev(struct pci_dev *dev) -{ - pci_stop_dev(dev); /* Remove the device from the device lists, and prevent any further * list accesses from this device */ @@ -127,32 +119,5 @@ void pci_remove_behind_bridge(struct pci_dev *dev) } } -static void pci_stop_bus_devices(struct pci_bus *bus) -{ - struct list_head *l, *n; - - list_for_each_safe(l, n, &bus->devices) { - struct pci_dev *dev = pci_dev_b(l); - pci_stop_bus_device(dev); - } -} - -/** - * pci_stop_bus_device - stop a PCI device and any children - * @dev: the device to stop - * - * Stop a PCI device (detach the driver, remove from the global list - * and so on). This also stop any subordinate buses and children in a - * depth-first manner. - */ -void pci_stop_bus_device(struct pci_dev *dev) -{ - if (dev->subordinate) - pci_stop_bus_devices(dev->subordinate); - - pci_stop_dev(dev); -} - EXPORT_SYMBOL(pci_remove_bus_device); EXPORT_SYMBOL(pci_remove_behind_bridge); -EXPORT_SYMBOL_GPL(pci_stop_bus_device); diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index 54404917be9a..47c1071ad84e 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -55,19 +55,12 @@ pbus_assign_resources_sorted(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { u16 class = dev->class >> 8; - /* Don't touch classless devices or host bridges. */ + /* Don't touch classless devices or host bridges or ioapics. */ if (class == PCI_CLASS_NOT_DEFINED || - class == PCI_CLASS_BRIDGE_HOST) + class == PCI_CLASS_BRIDGE_HOST || + class == PCI_CLASS_SYSTEM_PIC) continue; - /* Don't touch ioapics if it has the assigned resources. */ - if (class == PCI_CLASS_SYSTEM_PIC) { - res = &dev->resource[0]; - if (res[0].start || res[1].start || res[2].start || - res[3].start || res[4].start || res[5].start) - continue; - } - pdev_sort_resources(dev, &head); } diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index dfd8cfb7fb5d..64802aabd1ac 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -515,8 +515,7 @@ static unsigned long randomize_stack_top(unsigned long stack_top) { unsigned int random_variable = 0; - if ((current->flags & PF_RANDOMIZE) && - !(current->personality & ADDR_NO_RANDOMIZE)) { + if (current->flags & PF_RANDOMIZE) { random_variable = get_random_int() & STACK_RND_MASK; random_variable <<= PAGE_SHIFT; } diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index ce982f6e8c80..e31e9cf96647 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -1855,7 +1855,7 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec)); - if (ret == 0 && tsp && !(current->personality & STICKY_TIMEOUTS)) { + if (tsp && !(current->personality & STICKY_TIMEOUTS)) { struct compat_timespec rts; rts.tv_sec = timeout / HZ; @@ -1866,8 +1866,7 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, } if (compat_timespec_compare(&rts, &ts) >= 0) rts = ts; - if (copy_to_user(tsp, &rts, sizeof(rts))) - ret = -EFAULT; + copy_to_user(tsp, &rts, sizeof(rts)); } if (ret == -ERESTARTNOHAND) { diff --git a/trunk/include/asm-i386/acpi.h b/trunk/include/asm-i386/acpi.h index 6016632d032f..20f523954218 100644 --- a/trunk/include/asm-i386/acpi.h +++ b/trunk/include/asm-i386/acpi.h @@ -131,7 +131,21 @@ static inline void disable_acpi(void) extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); #ifdef CONFIG_X86_IO_APIC +extern int skip_ioapic_setup; extern int acpi_skip_timer_override; + +static inline void disable_ioapic_setup(void) +{ + skip_ioapic_setup = 1; +} + +static inline int ioapic_setup_disabled(void) +{ + return skip_ioapic_setup; +} + +#else +static inline void disable_ioapic_setup(void) { } #endif static inline void acpi_noirq_set(void) { acpi_noirq = 1; } diff --git a/trunk/include/asm-i386/alternative-asm.i b/trunk/include/asm-i386/alternative-asm.i deleted file mode 100644 index 6c47e3b9484b..000000000000 --- a/trunk/include/asm-i386/alternative-asm.i +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#ifdef CONFIG_SMP - .macro LOCK_PREFIX -1: lock - .section .smp_locks,"a" - .align 4 - .long 1b - .previous - .endm -#else - .macro LOCK_PREFIX - .endm -#endif diff --git a/trunk/include/asm-i386/apic.h b/trunk/include/asm-i386/apic.h index 3a42b7d6fc92..2c1e371cebb6 100644 --- a/trunk/include/asm-i386/apic.h +++ b/trunk/include/asm-i386/apic.h @@ -16,8 +16,20 @@ #define APIC_VERBOSE 1 #define APIC_DEBUG 2 +extern int enable_local_apic; extern int apic_verbosity; +static inline void lapic_disable(void) +{ + enable_local_apic = -1; + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); +} + +static inline void lapic_enable(void) +{ + enable_local_apic = 1; +} + /* * Define the default level of output to be very little * This can be turned up by using apic=verbose for more @@ -30,8 +42,6 @@ extern int apic_verbosity; } while (0) -extern void generic_apic_probe(void); - #ifdef CONFIG_X86_LOCAL_APIC /* @@ -107,6 +117,8 @@ extern void enable_APIC_timer(void); extern void enable_NMI_through_LVT0 (void * dummy); +extern int disable_timer_pin_1; + void smp_send_timer_broadcast_ipi(struct pt_regs *regs); void switch_APIC_timer_to_ipi(void *cpumask); void switch_ipi_to_APIC_timer(void *cpumask); diff --git a/trunk/include/asm-i386/desc.h b/trunk/include/asm-i386/desc.h index 5874ef119ffd..89b8b82c82b3 100644 --- a/trunk/include/asm-i386/desc.h +++ b/trunk/include/asm-i386/desc.h @@ -33,99 +33,50 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address; } -/* - * This is the ldt that every process will get unless we need - * something other than this. - */ -extern struct desc_struct default_ldt[]; -extern struct desc_struct idt_table[]; -extern void set_intr_gate(unsigned int irq, void * addr); - -static inline void pack_descriptor(__u32 *a, __u32 *b, - unsigned long base, unsigned long limit, unsigned char type, unsigned char flags) -{ - *a = ((base & 0xffff) << 16) | (limit & 0xffff); - *b = (base & 0xff000000) | ((base & 0xff0000) >> 16) | - (limit & 0x000f0000) | ((type & 0xff) << 8) | ((flags & 0xf) << 20); -} - -static inline void pack_gate(__u32 *a, __u32 *b, - unsigned long base, unsigned short seg, unsigned char type, unsigned char flags) -{ - *a = (seg << 16) | (base & 0xffff); - *b = (base & 0xffff0000) | ((type & 0xff) << 8) | (flags & 0xff); -} - -#define DESCTYPE_LDT 0x82 /* present, system, DPL-0, LDT */ -#define DESCTYPE_TSS 0x89 /* present, system, DPL-0, 32-bit TSS */ -#define DESCTYPE_TASK 0x85 /* present, system, DPL-0, task gate */ -#define DESCTYPE_INT 0x8e /* present, system, DPL-0, interrupt gate */ -#define DESCTYPE_TRAP 0x8f /* present, system, DPL-0, trap gate */ -#define DESCTYPE_DPL3 0x60 /* DPL-3 */ -#define DESCTYPE_S 0x10 /* !system */ - #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8)) #define load_LDT_desc() __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8)) #define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr)) #define load_idt(dtr) __asm__ __volatile("lidt %0"::"m" (*dtr)) -#define load_tr(tr) __asm__ __volatile("ltr %0"::"m" (tr)) -#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"m" (ldt)) +#define load_tr(tr) __asm__ __volatile("ltr %0"::"mr" (tr)) +#define load_ldt(ldt) __asm__ __volatile("lldt %0"::"mr" (ldt)) #define store_gdt(dtr) __asm__ ("sgdt %0":"=m" (*dtr)) #define store_idt(dtr) __asm__ ("sidt %0":"=m" (*dtr)) -#define store_tr(tr) __asm__ ("str %0":"=m" (tr)) -#define store_ldt(ldt) __asm__ ("sldt %0":"=m" (ldt)) +#define store_tr(tr) __asm__ ("str %0":"=mr" (tr)) +#define store_ldt(ldt) __asm__ ("sldt %0":"=mr" (ldt)) -#if TLS_SIZE != 24 -# error update this code. -#endif - -static inline void load_TLS(struct thread_struct *t, unsigned int cpu) -{ -#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i] - C(0); C(1); C(2); -#undef C -} - -static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b) -{ - __u32 *lp = (__u32 *)((char *)dt + entry*8); - *lp = entry_a; - *(lp+1) = entry_b; -} - -#define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) +/* + * This is the ldt that every process will get unless we need + * something other than this. + */ +extern struct desc_struct default_ldt[]; +extern void set_intr_gate(unsigned int irq, void * addr); -static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) +#define _set_tssldt_desc(n,addr,limit,type) \ +__asm__ __volatile__ ("movw %w3,0(%2)\n\t" \ + "movw %w1,2(%2)\n\t" \ + "rorl $16,%1\n\t" \ + "movb %b1,4(%2)\n\t" \ + "movb %4,5(%2)\n\t" \ + "movb $0,6(%2)\n\t" \ + "movb %h1,7(%2)\n\t" \ + "rorl $16,%1" \ + : "=m"(*(n)) : "q" (addr), "r"(n), "ir"(limit), "i"(type)) + +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, void *addr) { - __u32 a, b; - pack_gate(&a, &b, (unsigned long)addr, seg, type, 0); - write_idt_entry(idt_table, gate, a, b); + _set_tssldt_desc(&get_cpu_gdt_table(cpu)[entry], (int)addr, + offsetof(struct tss_struct, __cacheline_filler) - 1, 0x89); } -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) -{ - __u32 a, b; - pack_descriptor(&a, &b, (unsigned long)addr, - offsetof(struct tss_struct, __cacheline_filler) - 1, - DESCTYPE_TSS, 0); - write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); -} +#define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entries) +static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int size) { - __u32 a, b; - pack_descriptor(&a, &b, (unsigned long)addr, - entries * sizeof(struct desc_struct) - 1, - DESCTYPE_LDT, 0); - write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, a, b); + _set_tssldt_desc(&get_cpu_gdt_table(cpu)[GDT_ENTRY_LDT], (int)addr, ((size << 3)-1), 0x82); } -#define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) - #define LDT_entry_a(info) \ ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) @@ -151,6 +102,24 @@ static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entri (info)->seg_not_present == 1 && \ (info)->useable == 0 ) +static inline void write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b) +{ + __u32 *lp = (__u32 *)((char *)ldt + entry*8); + *lp = entry_a; + *(lp+1) = entry_b; +} + +#if TLS_SIZE != 24 +# error update this code. +#endif + +static inline void load_TLS(struct thread_struct *t, unsigned int cpu) +{ +#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i] + C(0); C(1); C(2); +#undef C +} + static inline void clear_LDT(void) { int cpu = get_cpu(); diff --git a/trunk/include/asm-i386/dwarf2.h b/trunk/include/asm-i386/dwarf2.h index 6d66398a307d..2280f6272f80 100644 --- a/trunk/include/asm-i386/dwarf2.h +++ b/trunk/include/asm-i386/dwarf2.h @@ -1,6 +1,8 @@ #ifndef _DWARF2_H #define _DWARF2_H +#include + #ifndef __ASSEMBLY__ #warning "asm/dwarf2.h should be only included in pure assembly files" #endif @@ -26,13 +28,6 @@ #define CFI_RESTORE .cfi_restore #define CFI_REMEMBER_STATE .cfi_remember_state #define CFI_RESTORE_STATE .cfi_restore_state -#define CFI_UNDEFINED .cfi_undefined - -#ifdef CONFIG_AS_CFI_SIGNAL_FRAME -#define CFI_SIGNAL_FRAME .cfi_signal_frame -#else -#define CFI_SIGNAL_FRAME -#endif #else @@ -53,8 +48,6 @@ #define CFI_RESTORE ignore #define CFI_REMEMBER_STATE ignore #define CFI_RESTORE_STATE ignore -#define CFI_UNDEFINED ignore -#define CFI_SIGNAL_FRAME ignore #endif diff --git a/trunk/include/asm-i386/e820.h b/trunk/include/asm-i386/e820.h index f7514fb6e8e4..ca82acb8cb1f 100644 --- a/trunk/include/asm-i386/e820.h +++ b/trunk/include/asm-i386/e820.h @@ -18,7 +18,7 @@ #define E820_RAM 1 #define E820_RESERVED 2 -#define E820_ACPI 3 +#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */ #define E820_NVS 4 #define HIGH_MEMORY (1024*1024) diff --git a/trunk/include/asm-i386/frame.i b/trunk/include/asm-i386/frame.i deleted file mode 100644 index 4d68ddce18b6..000000000000 --- a/trunk/include/asm-i386/frame.i +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -/* The annotation hides the frame from the unwinder and makes it look - like a ordinary ebp save/restore. This avoids some special cases for - frame pointer later */ -#ifdef CONFIG_FRAME_POINTER - .macro FRAME - pushl %ebp - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ebp,0 - movl %esp,%ebp - .endm - .macro ENDFRAME - popl %ebp - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ebp - .endm -#else - .macro FRAME - .endm - .macro ENDFRAME - .endm -#endif diff --git a/trunk/include/asm-i386/genapic.h b/trunk/include/asm-i386/genapic.h index 8ffbb0f07457..b3783a32abee 100644 --- a/trunk/include/asm-i386/genapic.h +++ b/trunk/include/asm-i386/genapic.h @@ -1,8 +1,6 @@ #ifndef _ASM_GENAPIC_H #define _ASM_GENAPIC_H 1 -#include - /* * Generic APIC driver interface. * @@ -65,25 +63,14 @@ struct genapic { unsigned (*get_apic_id)(unsigned long x); unsigned long apic_id_mask; unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask); - -#ifdef CONFIG_SMP + /* ipi */ void (*send_IPI_mask)(cpumask_t mask, int vector); void (*send_IPI_allbutself)(int vector); void (*send_IPI_all)(int vector); -#endif }; -#define APICFUNC(x) .x = x, - -/* More functions could be probably marked IPIFUNC and save some space - in UP GENERICARCH kernels, but I don't have the nerve right now - to untangle this mess. -AK */ -#ifdef CONFIG_SMP -#define IPIFUNC(x) APICFUNC(x) -#else -#define IPIFUNC(x) -#endif +#define APICFUNC(x) .x = x #define APIC_INIT(aname, aprobe) { \ .name = aname, \ @@ -93,33 +80,33 @@ struct genapic { .no_balance_irq = NO_BALANCE_IRQ, \ .ESR_DISABLE = esr_disable, \ .apic_destination_logical = APIC_DEST_LOGICAL, \ - APICFUNC(apic_id_registered) \ - APICFUNC(target_cpus) \ - APICFUNC(check_apicid_used) \ - APICFUNC(check_apicid_present) \ - APICFUNC(init_apic_ldr) \ - APICFUNC(ioapic_phys_id_map) \ - APICFUNC(clustered_apic_check) \ - APICFUNC(multi_timer_check) \ - APICFUNC(apicid_to_node) \ - APICFUNC(cpu_to_logical_apicid) \ - APICFUNC(cpu_present_to_apicid) \ - APICFUNC(apicid_to_cpu_present) \ - APICFUNC(mpc_apic_id) \ - APICFUNC(setup_portio_remap) \ - APICFUNC(check_phys_apicid_present) \ - APICFUNC(mpc_oem_bus_info) \ - APICFUNC(mpc_oem_pci_bus) \ - APICFUNC(mps_oem_check) \ - APICFUNC(get_apic_id) \ + APICFUNC(apic_id_registered), \ + APICFUNC(target_cpus), \ + APICFUNC(check_apicid_used), \ + APICFUNC(check_apicid_present), \ + APICFUNC(init_apic_ldr), \ + APICFUNC(ioapic_phys_id_map), \ + APICFUNC(clustered_apic_check), \ + APICFUNC(multi_timer_check), \ + APICFUNC(apicid_to_node), \ + APICFUNC(cpu_to_logical_apicid), \ + APICFUNC(cpu_present_to_apicid), \ + APICFUNC(apicid_to_cpu_present), \ + APICFUNC(mpc_apic_id), \ + APICFUNC(setup_portio_remap), \ + APICFUNC(check_phys_apicid_present), \ + APICFUNC(mpc_oem_bus_info), \ + APICFUNC(mpc_oem_pci_bus), \ + APICFUNC(mps_oem_check), \ + APICFUNC(get_apic_id), \ .apic_id_mask = APIC_ID_MASK, \ - APICFUNC(cpu_mask_to_apicid) \ - APICFUNC(acpi_madt_oem_check) \ - IPIFUNC(send_IPI_mask) \ - IPIFUNC(send_IPI_allbutself) \ - IPIFUNC(send_IPI_all) \ - APICFUNC(enable_apic_mode) \ - APICFUNC(phys_pkg_id) \ + APICFUNC(cpu_mask_to_apicid), \ + APICFUNC(acpi_madt_oem_check), \ + APICFUNC(send_IPI_mask), \ + APICFUNC(send_IPI_allbutself), \ + APICFUNC(send_IPI_all), \ + APICFUNC(enable_apic_mode), \ + APICFUNC(phys_pkg_id), \ } extern struct genapic *genapic; diff --git a/trunk/include/asm-i386/intel_arch_perfmon.h b/trunk/include/asm-i386/intel_arch_perfmon.h index b52cd60a075b..134ea9cc5283 100644 --- a/trunk/include/asm-i386/intel_arch_perfmon.h +++ b/trunk/include/asm-i386/intel_arch_perfmon.h @@ -14,18 +14,6 @@ #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL (0x3c) #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) -#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX (0) -#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \ - (1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX)) - -union cpuid10_eax { - struct { - unsigned int version_id:8; - unsigned int num_counters:8; - unsigned int bit_width:8; - unsigned int mask_length:8; - } split; - unsigned int full; -}; +#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT (1 << 0) #endif /* X86_INTEL_ARCH_PERFMON_H */ diff --git a/trunk/include/asm-i386/io_apic.h b/trunk/include/asm-i386/io_apic.h index 5d309275a1dc..5092e819b8a2 100644 --- a/trunk/include/asm-i386/io_apic.h +++ b/trunk/include/asm-i386/io_apic.h @@ -188,16 +188,6 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned /* 1 if "noapic" boot option passed */ extern int skip_ioapic_setup; -static inline void disable_ioapic_setup(void) -{ - skip_ioapic_setup = 1; -} - -static inline int ioapic_setup_disabled(void) -{ - return skip_ioapic_setup; -} - /* * If we use the IO-APIC for IRQ routing, disable automatic * assignment of PCI IRQ's. @@ -216,7 +206,6 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq); #else /* !CONFIG_X86_IO_APIC */ #define io_apic_assign_pci_irqs 0 -static inline void disable_ioapic_setup(void) { } #endif extern int assign_irq_vector(int irq); diff --git a/trunk/include/asm-i386/kexec.h b/trunk/include/asm-i386/kexec.h index 4dfc9f5ed031..53f0e06672dc 100644 --- a/trunk/include/asm-i386/kexec.h +++ b/trunk/include/asm-i386/kexec.h @@ -1,26 +1,6 @@ #ifndef _I386_KEXEC_H #define _I386_KEXEC_H -#define PA_CONTROL_PAGE 0 -#define VA_CONTROL_PAGE 1 -#define PA_PGD 2 -#define VA_PGD 3 -#define PA_PTE_0 4 -#define VA_PTE_0 5 -#define PA_PTE_1 6 -#define VA_PTE_1 7 -#ifdef CONFIG_X86_PAE -#define PA_PMD_0 8 -#define VA_PMD_0 9 -#define PA_PMD_1 10 -#define VA_PMD_1 11 -#define PAGES_NR 12 -#else -#define PAGES_NR 8 -#endif - -#ifndef __ASSEMBLY__ - #include #include #include @@ -92,12 +72,5 @@ static inline void crash_setup_regs(struct pt_regs *newregs, newregs->eip = (unsigned long)current_text_addr(); } } -asmlinkage NORET_TYPE void -relocate_kernel(unsigned long indirection_page, - unsigned long control_page, - unsigned long start_address, - unsigned int has_pae) ATTRIB_NORET; - -#endif /* __ASSEMBLY__ */ #endif /* _I386_KEXEC_H */ diff --git a/trunk/include/asm-i386/mach-es7000/mach_apic.h b/trunk/include/asm-i386/mach-es7000/mach_apic.h index 26333685a7fb..b5f3f0d0b2bc 100644 --- a/trunk/include/asm-i386/mach-es7000/mach_apic.h +++ b/trunk/include/asm-i386/mach-es7000/mach_apic.h @@ -123,13 +123,9 @@ extern u8 cpu_2_logical_apicid[]; /* Mapping from cpu number to logical apicid */ static inline int cpu_to_logical_apicid(int cpu) { -#ifdef CONFIG_SMP if (cpu >= NR_CPUS) return BAD_APICID; return (int)cpu_2_logical_apicid[cpu]; -#else - return logical_smp_processor_id(); -#endif } static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused) diff --git a/trunk/include/asm-i386/mach-summit/mach_apic.h b/trunk/include/asm-i386/mach-summit/mach_apic.h index a81b05961595..9fd073286289 100644 --- a/trunk/include/asm-i386/mach-summit/mach_apic.h +++ b/trunk/include/asm-i386/mach-summit/mach_apic.h @@ -46,12 +46,10 @@ extern u8 cpu_2_logical_apicid[]; static inline void init_apic_ldr(void) { unsigned long val, id; - int count = 0; + int i, count; + u8 lid; u8 my_id = (u8)hard_smp_processor_id(); u8 my_cluster = (u8)apicid_cluster(my_id); -#ifdef CONFIG_SMP - u8 lid; - int i; /* Create logical APIC IDs by counting CPUs already in cluster. */ for (count = 0, i = NR_CPUS; --i >= 0; ) { @@ -59,7 +57,6 @@ static inline void init_apic_ldr(void) if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster) ++count; } -#endif /* We only have a 4 wide bitmap in cluster mode. If a deranged * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */ BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT); @@ -94,13 +91,9 @@ static inline int apicid_to_node(int logical_apicid) /* Mapping from cpu number to logical apicid */ static inline int cpu_to_logical_apicid(int cpu) { -#ifdef CONFIG_SMP if (cpu >= NR_CPUS) return BAD_APICID; return (int)cpu_2_logical_apicid[cpu]; -#else - return logical_smp_processor_id(); -#endif } static inline int cpu_present_to_apicid(int mps_cpu) diff --git a/trunk/include/asm-i386/mutex.h b/trunk/include/asm-i386/mutex.h index 7a17d9e58ad6..05a538531229 100644 --- a/trunk/include/asm-i386/mutex.h +++ b/trunk/include/asm-i386/mutex.h @@ -30,10 +30,14 @@ do { \ \ __asm__ __volatile__( \ LOCK_PREFIX " decl (%%eax) \n" \ - " jns 1f \n" \ - " call "#fail_fn" \n" \ + " js 2f \n" \ "1: \n" \ \ + LOCK_SECTION_START("") \ + "2: call "#fail_fn" \n" \ + " jmp 1b \n" \ + LOCK_SECTION_END \ + \ :"=a" (dummy) \ : "a" (count) \ : "memory", "ecx", "edx"); \ @@ -82,10 +86,14 @@ do { \ \ __asm__ __volatile__( \ LOCK_PREFIX " incl (%%eax) \n" \ - " jg 1f \n" \ - " call "#fail_fn" \n" \ + " jle 2f \n" \ "1: \n" \ \ + LOCK_SECTION_START("") \ + "2: call "#fail_fn" \n" \ + " jmp 1b \n" \ + LOCK_SECTION_END \ + \ :"=a" (dummy) \ : "a" (count) \ : "memory", "ecx", "edx"); \ diff --git a/trunk/include/asm-i386/nmi.h b/trunk/include/asm-i386/nmi.h index 303bcd4592bb..67d994799999 100644 --- a/trunk/include/asm-i386/nmi.h +++ b/trunk/include/asm-i386/nmi.h @@ -6,29 +6,32 @@ #include +struct pt_regs; + +typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu); + /** - * do_nmi_callback + * set_nmi_callback * - * Check to see if a callback exists and execute it. Return 1 - * if the handler exists and was handled successfully. + * Set a handler for an NMI. Only one handler may be + * set. Return 1 if the NMI was handled. */ -int do_nmi_callback(struct pt_regs *regs, int cpu); - -extern int nmi_watchdog_enabled; -extern int avail_to_resrv_perfctr_nmi_bit(unsigned int); -extern int avail_to_resrv_perfctr_nmi(unsigned int); -extern int reserve_perfctr_nmi(unsigned int); -extern void release_perfctr_nmi(unsigned int); -extern int reserve_evntsel_nmi(unsigned int); -extern void release_evntsel_nmi(unsigned int); - -extern void setup_apic_nmi_watchdog (void *); -extern void stop_apic_nmi_watchdog (void *); +void set_nmi_callback(nmi_callback_t callback); + +/** + * unset_nmi_callback + * + * Remove the handler previously set. + */ +void unset_nmi_callback(void); + +extern void setup_apic_nmi_watchdog (void); +extern int reserve_lapic_nmi(void); +extern void release_lapic_nmi(void); extern void disable_timer_nmi_watchdog(void); extern void enable_timer_nmi_watchdog(void); -extern int nmi_watchdog_tick (struct pt_regs * regs, unsigned reason); +extern void nmi_watchdog_tick (struct pt_regs * regs); -extern atomic_t nmi_active; extern unsigned int nmi_watchdog; #define NMI_DEFAULT -1 #define NMI_NONE 0 diff --git a/trunk/include/asm-i386/pgtable.h b/trunk/include/asm-i386/pgtable.h index 541b3e234335..0dc051a8078b 100644 --- a/trunk/include/asm-i386/pgtable.h +++ b/trunk/include/asm-i386/pgtable.h @@ -411,6 +411,8 @@ extern pte_t *lookup_address(unsigned long address); static inline int set_kernel_exec(unsigned long vaddr, int enable) { return 0;} #endif +extern void noexec_setup(const char *str); + #if defined(CONFIG_HIGHPTE) #define pte_offset_map(dir, address) \ ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address)) diff --git a/trunk/include/asm-i386/ptrace.h b/trunk/include/asm-i386/ptrace.h index a4a0e5207db5..1910880fcd40 100644 --- a/trunk/include/asm-i386/ptrace.h +++ b/trunk/include/asm-i386/ptrace.h @@ -27,7 +27,6 @@ struct pt_regs { #ifdef __KERNEL__ #include -#include struct task_struct; extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); @@ -41,14 +40,18 @@ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int erro */ static inline int user_mode(struct pt_regs *regs) { - return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL; + return (regs->xcs & 3) != 0; } static inline int user_mode_vm(struct pt_regs *regs) { - return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL; + return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0; } #define instruction_pointer(regs) ((regs)->eip) +#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) extern unsigned long profile_pc(struct pt_regs *regs); +#else +#define profile_pc(regs) instruction_pointer(regs) +#endif #endif /* __KERNEL__ */ #endif diff --git a/trunk/include/asm-i386/rwlock.h b/trunk/include/asm-i386/rwlock.h index c3e5db32fa48..87c069ccba08 100644 --- a/trunk/include/asm-i386/rwlock.h +++ b/trunk/include/asm-i386/rwlock.h @@ -20,6 +20,52 @@ #define RW_LOCK_BIAS 0x01000000 #define RW_LOCK_BIAS_STR "0x01000000" -/* Code is in asm-i386/spinlock.h */ +#define __build_read_lock_ptr(rw, helper) \ + asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" \ + "jns 1f\n" \ + "call " helper "\n\t" \ + "1:\n" \ + ::"a" (rw) : "memory") + +#define __build_read_lock_const(rw, helper) \ + asm volatile(LOCK_PREFIX " subl $1,%0\n\t" \ + "jns 1f\n" \ + "pushl %%eax\n\t" \ + "leal %0,%%eax\n\t" \ + "call " helper "\n\t" \ + "popl %%eax\n\t" \ + "1:\n" \ + :"+m" (*(volatile int *)rw) : : "memory") + +#define __build_read_lock(rw, helper) do { \ + if (__builtin_constant_p(rw)) \ + __build_read_lock_const(rw, helper); \ + else \ + __build_read_lock_ptr(rw, helper); \ + } while (0) + +#define __build_write_lock_ptr(rw, helper) \ + asm volatile(LOCK_PREFIX " subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ + "jz 1f\n" \ + "call " helper "\n\t" \ + "1:\n" \ + ::"a" (rw) : "memory") + +#define __build_write_lock_const(rw, helper) \ + asm volatile(LOCK_PREFIX " subl $" RW_LOCK_BIAS_STR ",%0\n\t" \ + "jz 1f\n" \ + "pushl %%eax\n\t" \ + "leal %0,%%eax\n\t" \ + "call " helper "\n\t" \ + "popl %%eax\n\t" \ + "1:\n" \ + :"+m" (*(volatile int *)rw) : : "memory") + +#define __build_write_lock(rw, helper) do { \ + if (__builtin_constant_p(rw)) \ + __build_write_lock_const(rw, helper); \ + else \ + __build_write_lock_ptr(rw, helper); \ + } while (0) #endif diff --git a/trunk/include/asm-i386/rwsem.h b/trunk/include/asm-i386/rwsem.h index bc598d6388e3..43113f5608eb 100644 --- a/trunk/include/asm-i386/rwsem.h +++ b/trunk/include/asm-i386/rwsem.h @@ -99,9 +99,17 @@ static inline void __down_read(struct rw_semaphore *sem) __asm__ __volatile__( "# beginning down_read\n\t" LOCK_PREFIX " incl (%%eax)\n\t" /* adds 0x00000001, returns the old value */ - " jns 1f\n" - " call call_rwsem_down_read_failed\n" + " js 2f\n\t" /* jump if we weren't granted the lock */ "1:\n\t" + LOCK_SECTION_START("") + "2:\n\t" + " pushl %%ecx\n\t" + " pushl %%edx\n\t" + " call rwsem_down_read_failed\n\t" + " popl %%edx\n\t" + " popl %%ecx\n\t" + " jmp 1b\n" + LOCK_SECTION_END "# ending down_read\n\t" : "+m" (sem->count) : "a" (sem) @@ -143,9 +151,15 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) "# beginning down_write\n\t" LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtract 0x0000ffff, returns the old value */ " testl %%edx,%%edx\n\t" /* was the count 0 before? */ - " jz 1f\n" - " call call_rwsem_down_write_failed\n" - "1:\n" + " jnz 2f\n\t" /* jump if we weren't granted the lock */ + "1:\n\t" + LOCK_SECTION_START("") + "2:\n\t" + " pushl %%ecx\n\t" + " call rwsem_down_write_failed\n\t" + " popl %%ecx\n\t" + " jmp 1b\n" + LOCK_SECTION_END "# ending down_write" : "+m" (sem->count), "=d" (tmp) : "a" (sem), "1" (tmp) @@ -179,9 +193,17 @@ static inline void __up_read(struct rw_semaphore *sem) __asm__ __volatile__( "# beginning __up_read\n\t" LOCK_PREFIX " xadd %%edx,(%%eax)\n\t" /* subtracts 1, returns the old value */ - " jns 1f\n\t" - " call call_rwsem_wake\n" - "1:\n" + " js 2f\n\t" /* jump if the lock is being waited upon */ + "1:\n\t" + LOCK_SECTION_START("") + "2:\n\t" + " decw %%dx\n\t" /* do nothing if still outstanding active readers */ + " jnz 1b\n\t" + " pushl %%ecx\n\t" + " call rwsem_wake\n\t" + " popl %%ecx\n\t" + " jmp 1b\n" + LOCK_SECTION_END "# ending __up_read\n" : "+m" (sem->count), "=d" (tmp) : "a" (sem), "1" (tmp) @@ -197,9 +219,17 @@ static inline void __up_write(struct rw_semaphore *sem) "# beginning __up_write\n\t" " movl %2,%%edx\n\t" LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */ - " jz 1f\n" - " call call_rwsem_wake\n" + " jnz 2f\n\t" /* jump if the lock is being waited upon */ "1:\n\t" + LOCK_SECTION_START("") + "2:\n\t" + " decw %%dx\n\t" /* did the active count reduce to 0? */ + " jnz 1b\n\t" /* jump back if not */ + " pushl %%ecx\n\t" + " call rwsem_wake\n\t" + " popl %%ecx\n\t" + " jmp 1b\n" + LOCK_SECTION_END "# ending __up_write\n" : "+m" (sem->count) : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS) @@ -214,9 +244,17 @@ static inline void __downgrade_write(struct rw_semaphore *sem) __asm__ __volatile__( "# beginning __downgrade_write\n\t" LOCK_PREFIX " addl %2,(%%eax)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */ - " jns 1f\n\t" - " call call_rwsem_downgrade_wake\n" + " js 2f\n\t" /* jump if the lock is being waited upon */ "1:\n\t" + LOCK_SECTION_START("") + "2:\n\t" + " pushl %%ecx\n\t" + " pushl %%edx\n\t" + " call rwsem_downgrade_wake\n\t" + " popl %%edx\n\t" + " popl %%ecx\n\t" + " jmp 1b\n" + LOCK_SECTION_END "# ending __downgrade_write\n" : "+m" (sem->count) : "a" (sem), "i" (-RWSEM_WAITING_BIAS) diff --git a/trunk/include/asm-i386/segment.h b/trunk/include/asm-i386/segment.h index b7ab59685ba7..faf995307b9e 100644 --- a/trunk/include/asm-i386/segment.h +++ b/trunk/include/asm-i386/segment.h @@ -83,11 +83,6 @@ #define GDT_SIZE (GDT_ENTRIES * 8) -/* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */ -#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8) -/* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ -#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) - /* Simple and small GDT entries for booting only */ #define GDT_ENTRY_BOOT_CS 2 @@ -117,16 +112,4 @@ */ #define IDT_ENTRIES 256 -/* Bottom two bits of selector give the ring privilege level */ -#define SEGMENT_RPL_MASK 0x3 -/* Bit 2 is table indicator (LDT/GDT) */ -#define SEGMENT_TI_MASK 0x4 - -/* User mode is privilege level 3 */ -#define USER_RPL 0x3 -/* LDT segment has TI set, GDT has it cleared */ -#define SEGMENT_LDT 0x4 -#define SEGMENT_GDT 0x0 - -#define get_kernel_rpl() 0 #endif diff --git a/trunk/include/asm-i386/semaphore.h b/trunk/include/asm-i386/semaphore.h index e63b6a68f04c..d51e800acf29 100644 --- a/trunk/include/asm-i386/semaphore.h +++ b/trunk/include/asm-i386/semaphore.h @@ -100,10 +100,13 @@ static inline void down(struct semaphore * sem) __asm__ __volatile__( "# atomic down operation\n\t" LOCK_PREFIX "decl %0\n\t" /* --sem->count */ - "jns 2f\n" - "\tlea %0,%%eax\n\t" - "call __down_failed\n" - "2:" + "js 2f\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tlea %0,%%eax\n\t" + "call __down_failed\n\t" + "jmp 1b\n" + LOCK_SECTION_END :"+m" (sem->count) : :"memory","ax"); @@ -120,12 +123,15 @@ static inline int down_interruptible(struct semaphore * sem) might_sleep(); __asm__ __volatile__( "# atomic interruptible down operation\n\t" - "xorl %0,%0\n\t" LOCK_PREFIX "decl %1\n\t" /* --sem->count */ - "jns 2f\n\t" - "lea %1,%%eax\n\t" - "call __down_failed_interruptible\n" - "2:" + "js 2f\n\t" + "xorl %0,%0\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tlea %1,%%eax\n\t" + "call __down_failed_interruptible\n\t" + "jmp 1b\n" + LOCK_SECTION_END :"=a" (result), "+m" (sem->count) : :"memory"); @@ -142,12 +148,15 @@ static inline int down_trylock(struct semaphore * sem) __asm__ __volatile__( "# atomic interruptible down operation\n\t" - "xorl %0,%0\n\t" LOCK_PREFIX "decl %1\n\t" /* --sem->count */ - "jns 2f\n\t" - "lea %1,%%eax\n\t" + "js 2f\n\t" + "xorl %0,%0\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tlea %1,%%eax\n\t" "call __down_failed_trylock\n\t" - "2:\n" + "jmp 1b\n" + LOCK_SECTION_END :"=a" (result), "+m" (sem->count) : :"memory"); @@ -157,16 +166,22 @@ static inline int down_trylock(struct semaphore * sem) /* * Note! This is subtle. We jump to wake people up only if * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). */ static inline void up(struct semaphore * sem) { __asm__ __volatile__( "# atomic up operation\n\t" LOCK_PREFIX "incl %0\n\t" /* ++sem->count */ - "jg 1f\n\t" - "lea %0,%%eax\n\t" - "call __up_wakeup\n" - "1:" + "jle 2f\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tlea %0,%%eax\n\t" + "call __up_wakeup\n\t" + "jmp 1b\n" + LOCK_SECTION_END + ".subsection 0\n" :"+m" (sem->count) : :"memory","ax"); diff --git a/trunk/include/asm-i386/smp.h b/trunk/include/asm-i386/smp.h index 32ac8c91d5c5..142d10e34ade 100644 --- a/trunk/include/asm-i386/smp.h +++ b/trunk/include/asm-i386/smp.h @@ -80,12 +80,17 @@ static inline int hard_smp_processor_id(void) return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID)); } #endif + +static __inline int logical_smp_processor_id(void) +{ + /* we don't want to mark this access volatile - bad code generation */ + return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); +} + #endif extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); -extern unsigned int num_processors; - #endif /* !__ASSEMBLY__ */ #else /* CONFIG_SMP */ @@ -95,15 +100,4 @@ extern unsigned int num_processors; #define NO_PROC_ID 0xFF /* No processor magic marker */ #endif - -#ifndef __ASSEMBLY__ -#ifdef CONFIG_X86_LOCAL_APIC -static __inline int logical_smp_processor_id(void) -{ - /* we don't want to mark this access volatile - bad code generation */ - return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); -} -#endif -#endif - #endif diff --git a/trunk/include/asm-i386/spinlock.h b/trunk/include/asm-i386/spinlock.h index b0b3043f05e1..d1020363c41a 100644 --- a/trunk/include/asm-i386/spinlock.h +++ b/trunk/include/asm-i386/spinlock.h @@ -4,12 +4,8 @@ #include #include #include -#include #include -#define CLI_STRING "cli" -#define STI_STRING "sti" - /* * Your basic SMP spinlocks, allowing only a single CPU anywhere * @@ -21,64 +17,67 @@ * (the type definitions are in asm/spinlock_types.h) */ -static inline int __raw_spin_is_locked(raw_spinlock_t *x) -{ - return *(volatile signed char *)(&(x)->slock) <= 0; -} +#define __raw_spin_is_locked(x) \ + (*(volatile signed char *)(&(x)->slock) <= 0) + +#define __raw_spin_lock_string \ + "\n1:\t" \ + LOCK_PREFIX " ; decb %0\n\t" \ + "jns 3f\n" \ + "2:\t" \ + "rep;nop\n\t" \ + "cmpb $0,%0\n\t" \ + "jle 2b\n\t" \ + "jmp 1b\n" \ + "3:\n\t" + +/* + * NOTE: there's an irqs-on section here, which normally would have to be + * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use + * __raw_spin_lock_string_flags(). + */ +#define __raw_spin_lock_string_flags \ + "\n1:\t" \ + LOCK_PREFIX " ; decb %0\n\t" \ + "jns 5f\n" \ + "2:\t" \ + "testl $0x200, %1\n\t" \ + "jz 4f\n\t" \ + "sti\n" \ + "3:\t" \ + "rep;nop\n\t" \ + "cmpb $0, %0\n\t" \ + "jle 3b\n\t" \ + "cli\n\t" \ + "jmp 1b\n" \ + "4:\t" \ + "rep;nop\n\t" \ + "cmpb $0, %0\n\t" \ + "jg 1b\n\t" \ + "jmp 4b\n" \ + "5:\n\t" static inline void __raw_spin_lock(raw_spinlock_t *lock) { - asm volatile("\n1:\t" - LOCK_PREFIX " ; decb %0\n\t" - "jns 3f\n" - "2:\t" - "rep;nop\n\t" - "cmpb $0,%0\n\t" - "jle 2b\n\t" - "jmp 1b\n" - "3:\n\t" - : "+m" (lock->slock) : : "memory"); + asm(__raw_spin_lock_string : "+m" (lock->slock) : : "memory"); } /* * It is easier for the lock validator if interrupts are not re-enabled * in the middle of a lock-acquire. This is a performance feature anyway * so we turn it off: - * - * NOTE: there's an irqs-on section here, which normally would have to be - * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant. */ #ifndef CONFIG_PROVE_LOCKING static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) { - asm volatile( - "\n1:\t" - LOCK_PREFIX " ; decb %0\n\t" - "jns 5f\n" - "2:\t" - "testl $0x200, %1\n\t" - "jz 4f\n\t" - STI_STRING "\n" - "3:\t" - "rep;nop\n\t" - "cmpb $0, %0\n\t" - "jle 3b\n\t" - CLI_STRING "\n\t" - "jmp 1b\n" - "4:\t" - "rep;nop\n\t" - "cmpb $0, %0\n\t" - "jg 1b\n\t" - "jmp 4b\n" - "5:\n\t" - : "+m" (lock->slock) : "r" (flags) : "memory"); + asm(__raw_spin_lock_string_flags : "+m" (lock->slock) : "r" (flags) : "memory"); } #endif static inline int __raw_spin_trylock(raw_spinlock_t *lock) { char oldval; - asm volatile( + __asm__ __volatile__( "xchgb %b0,%1" :"=q" (oldval), "+m" (lock->slock) :"0" (0) : "memory"); @@ -94,29 +93,38 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) #if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE) +#define __raw_spin_unlock_string \ + "movb $1,%0" \ + :"+m" (lock->slock) : : "memory" + + static inline void __raw_spin_unlock(raw_spinlock_t *lock) { - asm volatile("movb $1,%0" : "+m" (lock->slock) :: "memory"); + __asm__ __volatile__( + __raw_spin_unlock_string + ); } #else +#define __raw_spin_unlock_string \ + "xchgb %b0, %1" \ + :"=q" (oldval), "+m" (lock->slock) \ + :"0" (oldval) : "memory" + static inline void __raw_spin_unlock(raw_spinlock_t *lock) { char oldval = 1; - asm volatile("xchgb %b0, %1" - : "=q" (oldval), "+m" (lock->slock) - : "0" (oldval) : "memory"); + __asm__ __volatile__( + __raw_spin_unlock_string + ); } #endif -static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) -{ - while (__raw_spin_is_locked(lock)) - cpu_relax(); -} +#define __raw_spin_unlock_wait(lock) \ + do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) /* * Read-write spinlocks, allowing multiple readers @@ -143,36 +151,22 @@ static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) * read_can_lock - would read_trylock() succeed? * @lock: the rwlock in question. */ -static inline int __raw_read_can_lock(raw_rwlock_t *x) -{ - return (int)(x)->lock > 0; -} +#define __raw_read_can_lock(x) ((int)(x)->lock > 0) /** * write_can_lock - would write_trylock() succeed? * @lock: the rwlock in question. */ -static inline int __raw_write_can_lock(raw_rwlock_t *x) -{ - return (x)->lock == RW_LOCK_BIAS; -} +#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) static inline void __raw_read_lock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" - "jns 1f\n" - "call __read_lock_failed\n\t" - "1:\n" - ::"a" (rw) : "memory"); + __build_read_lock(rw, "__read_lock_failed"); } static inline void __raw_write_lock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX " subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" - "jz 1f\n" - "call __write_lock_failed\n\t" - "1:\n" - ::"a" (rw) : "memory"); + __build_write_lock(rw, "__write_lock_failed"); } static inline int __raw_read_trylock(raw_rwlock_t *lock) diff --git a/trunk/include/asm-i386/stacktrace.h b/trunk/include/asm-i386/stacktrace.h deleted file mode 100644 index 7d1f6a5cbfca..000000000000 --- a/trunk/include/asm-i386/stacktrace.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-i386/therm_throt.h b/trunk/include/asm-i386/therm_throt.h deleted file mode 100644 index 399bf6026b16..000000000000 --- a/trunk/include/asm-i386/therm_throt.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __ASM_I386_THERM_THROT_H__ -#define __ASM_I386_THERM_THROT_H__ 1 - -#include - -extern atomic_t therm_throt_en; -int therm_throt_process(int curr); - -#endif /* __ASM_I386_THERM_THROT_H__ */ diff --git a/trunk/include/asm-i386/tlbflush.h b/trunk/include/asm-i386/tlbflush.h index 360648b0f2b3..d57ca5c540b6 100644 --- a/trunk/include/asm-i386/tlbflush.h +++ b/trunk/include/asm-i386/tlbflush.h @@ -36,6 +36,8 @@ : "memory"); \ } while (0) +extern unsigned long pgkern_mask; + # define __flush_tlb_all() \ do { \ if (cpu_has_pge) \ @@ -47,7 +49,7 @@ #define cpu_has_invlpg (boot_cpu_data.x86 > 3) #define __flush_tlb_single(addr) \ - __asm__ __volatile__("invlpg (%0)" ::"r" (addr) : "memory") + __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr)) #ifdef CONFIG_X86_INVLPG # define __flush_tlb_one(addr) __flush_tlb_single(addr) diff --git a/trunk/include/asm-i386/tsc.h b/trunk/include/asm-i386/tsc.h index c13933185c1c..97b828ce31e0 100644 --- a/trunk/include/asm-i386/tsc.h +++ b/trunk/include/asm-i386/tsc.h @@ -6,6 +6,7 @@ #ifndef _ASM_i386_TSC_H #define _ASM_i386_TSC_H +#include #include /* diff --git a/trunk/include/asm-i386/unistd.h b/trunk/include/asm-i386/unistd.h index 565d0897b205..fc1c8ddae149 100644 --- a/trunk/include/asm-i386/unistd.h +++ b/trunk/include/asm-i386/unistd.h @@ -323,11 +323,10 @@ #define __NR_tee 315 #define __NR_vmsplice 316 #define __NR_move_pages 317 -#define __NR_getcpu 318 #ifdef __KERNEL__ -#define NR_syscalls 319 +#define NR_syscalls 318 /* * user-visible error numbers are in the range -1 - -128: see diff --git a/trunk/include/asm-i386/unwind.h b/trunk/include/asm-i386/unwind.h index 5031d693b89d..4c1a0b968569 100644 --- a/trunk/include/asm-i386/unwind.h +++ b/trunk/include/asm-i386/unwind.h @@ -18,7 +18,6 @@ struct unwind_frame_info { struct pt_regs regs; struct task_struct *task; - unsigned call_frame:1; }; #define UNW_PC(frame) (frame)->regs.eip @@ -29,8 +28,6 @@ struct unwind_frame_info #define FRAME_LINK_OFFSET 0 #define STACK_BOTTOM(tsk) STACK_LIMIT((tsk)->thread.esp0) #define STACK_TOP(tsk) ((tsk)->thread.esp0) -#else -#define UNW_FP(frame) ((void)(frame), 0) #endif #define STACK_LIMIT(ptr) (((ptr) - 1) & ~(THREAD_SIZE - 1)) @@ -45,10 +42,6 @@ struct unwind_frame_info PTREGS_INFO(edi), \ PTREGS_INFO(eip) -#define UNW_DEFAULT_RA(raItem, dataAlign) \ - ((raItem).where == Memory && \ - !((raItem).value * (dataAlign) + 4)) - static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, /*const*/ struct pt_regs *regs) { @@ -95,7 +88,6 @@ static inline int arch_unw_user_mode(const struct unwind_frame_info *info) #define UNW_PC(frame) ((void)(frame), 0) #define UNW_SP(frame) ((void)(frame), 0) -#define UNW_FP(frame) ((void)(frame), 0) static inline int arch_unw_user_mode(const void *info) { diff --git a/trunk/include/asm-ia64/module.h b/trunk/include/asm-ia64/module.h index d2da61e4c49b..85c82bd819f2 100644 --- a/trunk/include/asm-ia64/module.h +++ b/trunk/include/asm-ia64/module.h @@ -28,8 +28,7 @@ struct mod_arch_specific { #define Elf_Ehdr Elf64_Ehdr #define MODULE_PROC_FAMILY "ia64" -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY \ - "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__) +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY #define ARCH_SHF_SMALL SHF_IA_64_SHORT diff --git a/trunk/include/asm-mips/Kbuild b/trunk/include/asm-mips/Kbuild index 7897f05e3165..c68e1680da01 100644 --- a/trunk/include/asm-mips/Kbuild +++ b/trunk/include/asm-mips/Kbuild @@ -1,3 +1 @@ include include/asm-generic/Kbuild.asm - -header-y += cachectl.h sgidefs.h sysmips.h diff --git a/trunk/include/asm-mips/bootinfo.h b/trunk/include/asm-mips/bootinfo.h index 78c35ec46362..3b745e76f429 100644 --- a/trunk/include/asm-mips/bootinfo.h +++ b/trunk/include/asm-mips/bootinfo.h @@ -112,7 +112,8 @@ * Valid machtype for group GALILEO */ #define MACH_GROUP_GALILEO 11 /* Galileo Eval Boards */ -#define MACH_EV64120A 0 /* EV64120A */ +#define MACH_EV96100 0 /* EV96100 */ +#define MACH_EV64120A 1 /* EV64120A */ /* * Valid machtype for group MOMENCO diff --git a/trunk/include/asm-mips/cacheflush.h b/trunk/include/asm-mips/cacheflush.h index 36416fdfcf68..47bc8f6c20d2 100644 --- a/trunk/include/asm-mips/cacheflush.h +++ b/trunk/include/asm-mips/cacheflush.h @@ -21,6 +21,7 @@ * - flush_cache_range(vma, start, end) flushes a range of pages * - flush_icache_range(start, end) flush a range of instructions * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache + * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache * * MIPS specific flush operations: * @@ -38,7 +39,7 @@ extern void __flush_dcache_page(struct page *page); static inline void flush_dcache_page(struct page *page) { - if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) + if (cpu_has_dc_aliases) __flush_dcache_page(page); } @@ -46,13 +47,8 @@ static inline void flush_dcache_page(struct page *page) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -extern void (*__flush_icache_page)(struct vm_area_struct *vma, +extern void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); -static inline void flush_icache_page(struct vm_area_struct *vma, - struct page *page) -{ -} - extern void (*flush_icache_range)(unsigned long start, unsigned long end); #define flush_cache_vmap(start, end) flush_cache_all() #define flush_cache_vunmap(start, end) flush_cache_all() @@ -64,7 +60,7 @@ static inline void copy_to_user_page(struct vm_area_struct *vma, if (cpu_has_dc_aliases) flush_cache_page(vma, vaddr, page_to_pfn(page)); memcpy(dst, src, len); - __flush_icache_page(vma, page); + flush_icache_page(vma, page); } static inline void copy_from_user_page(struct vm_area_struct *vma, diff --git a/trunk/include/asm-mips/fcntl.h b/trunk/include/asm-mips/fcntl.h index 00a50ec1c19f..787220e6c1fc 100644 --- a/trunk/include/asm-mips/fcntl.h +++ b/trunk/include/asm-mips/fcntl.h @@ -25,6 +25,8 @@ #define F_SETOWN 24 /* for sockets. */ #define F_GETOWN 23 /* for sockets. */ +#define F_SETSIG 10 /* for sockets. */ +#define F_GETSIG 11 /* for sockets. */ #ifndef __mips64 #define F_GETLK64 33 /* using 'struct flock64' */ diff --git a/trunk/include/asm-mips/galileo-boards/gt96100.h b/trunk/include/asm-mips/galileo-boards/gt96100.h new file mode 100644 index 000000000000..aabd1b629c19 --- /dev/null +++ b/trunk/include/asm-mips/galileo-boards/gt96100.h @@ -0,0 +1,427 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Register offsets of the MIPS GT96100 Advanced Communication Controller. + */ +#ifndef _GT96100_H +#define _GT96100_H + +/* + * Galileo GT96100 internal register base. + */ +#define MIPS_GT96100_BASE (KSEG1ADDR(0x14000000)) + +#define GT96100_WRITE(ofs, data) \ + *(volatile u32 *)(MIPS_GT96100_BASE+ofs) = cpu_to_le32(data) +#define GT96100_READ(ofs) \ + le32_to_cpu(*(volatile u32 *)(MIPS_GT96100_BASE+ofs)) + +#define GT96100_ETH_IO_SIZE 0x4000 + +/************************************************************************ + * Register offset addresses follow + ************************************************************************/ + +/* CPU Interface Control Registers */ +#define GT96100_CPU_INTERF_CONFIG 0x000000 + +/* Ethernet Ports */ +#define GT96100_ETH_PHY_ADDR_REG 0x080800 +#define GT96100_ETH_SMI_REG 0x080810 +/* + These are offsets to port 0 registers. Add GT96100_ETH_IO_SIZE to + get offsets to port 1 registers. +*/ +#define GT96100_ETH_PORT_CONFIG 0x084800 +#define GT96100_ETH_PORT_CONFIG_EXT 0x084808 +#define GT96100_ETH_PORT_COMM 0x084810 +#define GT96100_ETH_PORT_STATUS 0x084818 +#define GT96100_ETH_SER_PARAM 0x084820 +#define GT96100_ETH_HASH_TBL_PTR 0x084828 +#define GT96100_ETH_FLOW_CNTRL_SRC_ADDR_L 0x084830 +#define GT96100_ETH_FLOW_CNTRL_SRC_ADDR_H 0x084838 +#define GT96100_ETH_SDMA_CONFIG 0x084840 +#define GT96100_ETH_SDMA_COMM 0x084848 +#define GT96100_ETH_INT_CAUSE 0x084850 +#define GT96100_ETH_INT_MASK 0x084858 +#define GT96100_ETH_1ST_RX_DESC_PTR0 0x084880 +#define GT96100_ETH_1ST_RX_DESC_PTR1 0x084884 +#define GT96100_ETH_1ST_RX_DESC_PTR2 0x084888 +#define GT96100_ETH_1ST_RX_DESC_PTR3 0x08488C +#define GT96100_ETH_CURR_RX_DESC_PTR0 0x0848A0 +#define GT96100_ETH_CURR_RX_DESC_PTR1 0x0848A4 +#define GT96100_ETH_CURR_RX_DESC_PTR2 0x0848A8 +#define GT96100_ETH_CURR_RX_DESC_PTR3 0x0848AC +#define GT96100_ETH_CURR_TX_DESC_PTR0 0x0848E0 +#define GT96100_ETH_CURR_TX_DESC_PTR1 0x0848E4 +#define GT96100_ETH_MIB_COUNT_BASE 0x085800 + +/* SDMAs */ +#define GT96100_SDMA_GROUP_CONFIG 0x101AF0 +/* SDMA Group 0 */ +#define GT96100_SDMA_G0_CHAN0_CONFIG 0x000900 +#define GT96100_SDMA_G0_CHAN0_COMM 0x000908 +#define GT96100_SDMA_G0_CHAN0_RX_DESC_BASE 0x008900 +#define GT96100_SDMA_G0_CHAN0_CURR_RX_DESC_PTR 0x008910 +#define GT96100_SDMA_G0_CHAN0_TX_DESC_BASE 0x00C900 +#define GT96100_SDMA_G0_CHAN0_CURR_TX_DESC_PTR 0x00C910 +#define GT96100_SDMA_G0_CHAN0_1ST_TX_DESC_PTR 0x00C914 +#define GT96100_SDMA_G0_CHAN1_CONFIG 0x010900 +#define GT96100_SDMA_G0_CHAN1_COMM 0x010908 +#define GT96100_SDMA_G0_CHAN1_RX_DESC_BASE 0x018900 +#define GT96100_SDMA_G0_CHAN1_CURR_RX_DESC_PTR 0x018910 +#define GT96100_SDMA_G0_CHAN1_TX_DESC_BASE 0x01C900 +#define GT96100_SDMA_G0_CHAN1_CURR_TX_DESC_PTR 0x01C910 +#define GT96100_SDMA_G0_CHAN1_1ST_TX_DESC_PTR 0x01C914 +#define GT96100_SDMA_G0_CHAN2_CONFIG 0x020900 +#define GT96100_SDMA_G0_CHAN2_COMM 0x020908 +#define GT96100_SDMA_G0_CHAN2_RX_DESC_BASE 0x028900 +#define GT96100_SDMA_G0_CHAN2_CURR_RX_DESC_PTR 0x028910 +#define GT96100_SDMA_G0_CHAN2_TX_DESC_BASE 0x02C900 +#define GT96100_SDMA_G0_CHAN2_CURR_TX_DESC_PTR 0x02C910 +#define GT96100_SDMA_G0_CHAN2_1ST_TX_DESC_PTR 0x02C914 +#define GT96100_SDMA_G0_CHAN3_CONFIG 0x030900 +#define GT96100_SDMA_G0_CHAN3_COMM 0x030908 +#define GT96100_SDMA_G0_CHAN3_RX_DESC_BASE 0x038900 +#define GT96100_SDMA_G0_CHAN3_CURR_RX_DESC_PTR 0x038910 +#define GT96100_SDMA_G0_CHAN3_TX_DESC_BASE 0x03C900 +#define GT96100_SDMA_G0_CHAN3_CURR_TX_DESC_PTR 0x03C910 +#define GT96100_SDMA_G0_CHAN3_1ST_TX_DESC_PTR 0x03C914 +#define GT96100_SDMA_G0_CHAN4_CONFIG 0x040900 +#define GT96100_SDMA_G0_CHAN4_COMM 0x040908 +#define GT96100_SDMA_G0_CHAN4_RX_DESC_BASE 0x048900 +#define GT96100_SDMA_G0_CHAN4_CURR_RX_DESC_PTR 0x048910 +#define GT96100_SDMA_G0_CHAN4_TX_DESC_BASE 0x04C900 +#define GT96100_SDMA_G0_CHAN4_CURR_TX_DESC_PTR 0x04C910 +#define GT96100_SDMA_G0_CHAN4_1ST_TX_DESC_PTR 0x04C914 +#define GT96100_SDMA_G0_CHAN5_CONFIG 0x050900 +#define GT96100_SDMA_G0_CHAN5_COMM 0x050908 +#define GT96100_SDMA_G0_CHAN5_RX_DESC_BASE 0x058900 +#define GT96100_SDMA_G0_CHAN5_CURR_RX_DESC_PTR 0x058910 +#define GT96100_SDMA_G0_CHAN5_TX_DESC_BASE 0x05C900 +#define GT96100_SDMA_G0_CHAN5_CURR_TX_DESC_PTR 0x05C910 +#define GT96100_SDMA_G0_CHAN5_1ST_TX_DESC_PTR 0x05C914 +#define GT96100_SDMA_G0_CHAN6_CONFIG 0x060900 +#define GT96100_SDMA_G0_CHAN6_COMM 0x060908 +#define GT96100_SDMA_G0_CHAN6_RX_DESC_BASE 0x068900 +#define GT96100_SDMA_G0_CHAN6_CURR_RX_DESC_PTR 0x068910 +#define GT96100_SDMA_G0_CHAN6_TX_DESC_BASE 0x06C900 +#define GT96100_SDMA_G0_CHAN6_CURR_TX_DESC_PTR 0x06C910 +#define GT96100_SDMA_G0_CHAN6_1ST_TX_DESC_PTR 0x06C914 +#define GT96100_SDMA_G0_CHAN7_CONFIG 0x070900 +#define GT96100_SDMA_G0_CHAN7_COMM 0x070908 +#define GT96100_SDMA_G0_CHAN7_RX_DESC_BASE 0x078900 +#define GT96100_SDMA_G0_CHAN7_CURR_RX_DESC_PTR 0x078910 +#define GT96100_SDMA_G0_CHAN7_TX_DESC_BASE 0x07C900 +#define GT96100_SDMA_G0_CHAN7_CURR_TX_DESC_PTR 0x07C910 +#define GT96100_SDMA_G0_CHAN7_1ST_TX_DESC_PTR 0x07C914 +/* SDMA Group 1 */ +#define GT96100_SDMA_G1_CHAN0_CONFIG 0x100900 +#define GT96100_SDMA_G1_CHAN0_COMM 0x100908 +#define GT96100_SDMA_G1_CHAN0_RX_DESC_BASE 0x108900 +#define GT96100_SDMA_G1_CHAN0_CURR_RX_DESC_PTR 0x108910 +#define GT96100_SDMA_G1_CHAN0_TX_DESC_BASE 0x10C900 +#define GT96100_SDMA_G1_CHAN0_CURR_TX_DESC_PTR 0x10C910 +#define GT96100_SDMA_G1_CHAN0_1ST_TX_DESC_PTR 0x10C914 +#define GT96100_SDMA_G1_CHAN1_CONFIG 0x110900 +#define GT96100_SDMA_G1_CHAN1_COMM 0x110908 +#define GT96100_SDMA_G1_CHAN1_RX_DESC_BASE 0x118900 +#define GT96100_SDMA_G1_CHAN1_CURR_RX_DESC_PTR 0x118910 +#define GT96100_SDMA_G1_CHAN1_TX_DESC_BASE 0x11C900 +#define GT96100_SDMA_G1_CHAN1_CURR_TX_DESC_PTR 0x11C910 +#define GT96100_SDMA_G1_CHAN1_1ST_TX_DESC_PTR 0x11C914 +#define GT96100_SDMA_G1_CHAN2_CONFIG 0x120900 +#define GT96100_SDMA_G1_CHAN2_COMM 0x120908 +#define GT96100_SDMA_G1_CHAN2_RX_DESC_BASE 0x128900 +#define GT96100_SDMA_G1_CHAN2_CURR_RX_DESC_PTR 0x128910 +#define GT96100_SDMA_G1_CHAN2_TX_DESC_BASE 0x12C900 +#define GT96100_SDMA_G1_CHAN2_CURR_TX_DESC_PTR 0x12C910 +#define GT96100_SDMA_G1_CHAN2_1ST_TX_DESC_PTR 0x12C914 +#define GT96100_SDMA_G1_CHAN3_CONFIG 0x130900 +#define GT96100_SDMA_G1_CHAN3_COMM 0x130908 +#define GT96100_SDMA_G1_CHAN3_RX_DESC_BASE 0x138900 +#define GT96100_SDMA_G1_CHAN3_CURR_RX_DESC_PTR 0x138910 +#define GT96100_SDMA_G1_CHAN3_TX_DESC_BASE 0x13C900 +#define GT96100_SDMA_G1_CHAN3_CURR_TX_DESC_PTR 0x13C910 +#define GT96100_SDMA_G1_CHAN3_1ST_TX_DESC_PTR 0x13C914 +#define GT96100_SDMA_G1_CHAN4_CONFIG 0x140900 +#define GT96100_SDMA_G1_CHAN4_COMM 0x140908 +#define GT96100_SDMA_G1_CHAN4_RX_DESC_BASE 0x148900 +#define GT96100_SDMA_G1_CHAN4_CURR_RX_DESC_PTR 0x148910 +#define GT96100_SDMA_G1_CHAN4_TX_DESC_BASE 0x14C900 +#define GT96100_SDMA_G1_CHAN4_CURR_TX_DESC_PTR 0x14C910 +#define GT96100_SDMA_G1_CHAN4_1ST_TX_DESC_PTR 0x14C914 +#define GT96100_SDMA_G1_CHAN5_CONFIG 0x150900 +#define GT96100_SDMA_G1_CHAN5_COMM 0x150908 +#define GT96100_SDMA_G1_CHAN5_RX_DESC_BASE 0x158900 +#define GT96100_SDMA_G1_CHAN5_CURR_RX_DESC_PTR 0x158910 +#define GT96100_SDMA_G1_CHAN5_TX_DESC_BASE 0x15C900 +#define GT96100_SDMA_G1_CHAN5_CURR_TX_DESC_PTR 0x15C910 +#define GT96100_SDMA_G1_CHAN5_1ST_TX_DESC_PTR 0x15C914 +#define GT96100_SDMA_G1_CHAN6_CONFIG 0x160900 +#define GT96100_SDMA_G1_CHAN6_COMM 0x160908 +#define GT96100_SDMA_G1_CHAN6_RX_DESC_BASE 0x168900 +#define GT96100_SDMA_G1_CHAN6_CURR_RX_DESC_PTR 0x168910 +#define GT96100_SDMA_G1_CHAN6_TX_DESC_BASE 0x16C900 +#define GT96100_SDMA_G1_CHAN6_CURR_TX_DESC_PTR 0x16C910 +#define GT96100_SDMA_G1_CHAN6_1ST_TX_DESC_PTR 0x16C914 +#define GT96100_SDMA_G1_CHAN7_CONFIG 0x170900 +#define GT96100_SDMA_G1_CHAN7_COMM 0x170908 +#define GT96100_SDMA_G1_CHAN7_RX_DESC_BASE 0x178900 +#define GT96100_SDMA_G1_CHAN7_CURR_RX_DESC_PTR 0x178910 +#define GT96100_SDMA_G1_CHAN7_TX_DESC_BASE 0x17C900 +#define GT96100_SDMA_G1_CHAN7_CURR_TX_DESC_PTR 0x17C910 +#define GT96100_SDMA_G1_CHAN7_1ST_TX_DESC_PTR 0x17C914 +/* MPSCs */ +#define GT96100_MPSC0_MAIN_CONFIG_LOW 0x000A00 +#define GT96100_MPSC0_MAIN_CONFIG_HIGH 0x000A04 +#define GT96100_MPSC0_PROTOCOL_CONFIG 0x000A08 +#define GT96100_MPSC_CHAN0_REG1 0x000A0C +#define GT96100_MPSC_CHAN0_REG2 0x000A10 +#define GT96100_MPSC_CHAN0_REG3 0x000A14 +#define GT96100_MPSC_CHAN0_REG4 0x000A18 +#define GT96100_MPSC_CHAN0_REG5 0x000A1C +#define GT96100_MPSC_CHAN0_REG6 0x000A20 +#define GT96100_MPSC_CHAN0_REG7 0x000A24 +#define GT96100_MPSC_CHAN0_REG8 0x000A28 +#define GT96100_MPSC_CHAN0_REG9 0x000A2C +#define GT96100_MPSC_CHAN0_REG10 0x000A30 +#define GT96100_MPSC_CHAN0_REG11 0x000A34 +#define GT96100_MPSC1_MAIN_CONFIG_LOW 0x008A00 +#define GT96100_MPSC1_MAIN_CONFIG_HIGH 0x008A04 +#define GT96100_MPSC1_PROTOCOL_CONFIG 0x008A08 +#define GT96100_MPSC_CHAN1_REG1 0x008A0C +#define GT96100_MPSC_CHAN1_REG2 0x008A10 +#define GT96100_MPSC_CHAN1_REG3 0x008A14 +#define GT96100_MPSC_CHAN1_REG4 0x008A18 +#define GT96100_MPSC_CHAN1_REG5 0x008A1C +#define GT96100_MPSC_CHAN1_REG6 0x008A20 +#define GT96100_MPSC_CHAN1_REG7 0x008A24 +#define GT96100_MPSC_CHAN1_REG8 0x008A28 +#define GT96100_MPSC_CHAN1_REG9 0x008A2C +#define GT96100_MPSC_CHAN1_REG10 0x008A30 +#define GT96100_MPSC_CHAN1_REG11 0x008A34 +#define GT96100_MPSC2_MAIN_CONFIG_LOW 0x010A00 +#define GT96100_MPSC2_MAIN_CONFIG_HIGH 0x010A04 +#define GT96100_MPSC2_PROTOCOL_CONFIG 0x010A08 +#define GT96100_MPSC_CHAN2_REG1 0x010A0C +#define GT96100_MPSC_CHAN2_REG2 0x010A10 +#define GT96100_MPSC_CHAN2_REG3 0x010A14 +#define GT96100_MPSC_CHAN2_REG4 0x010A18 +#define GT96100_MPSC_CHAN2_REG5 0x010A1C +#define GT96100_MPSC_CHAN2_REG6 0x010A20 +#define GT96100_MPSC_CHAN2_REG7 0x010A24 +#define GT96100_MPSC_CHAN2_REG8 0x010A28 +#define GT96100_MPSC_CHAN2_REG9 0x010A2C +#define GT96100_MPSC_CHAN2_REG10 0x010A30 +#define GT96100_MPSC_CHAN2_REG11 0x010A34 +#define GT96100_MPSC3_MAIN_CONFIG_LOW 0x018A00 +#define GT96100_MPSC3_MAIN_CONFIG_HIGH 0x018A04 +#define GT96100_MPSC3_PROTOCOL_CONFIG 0x018A08 +#define GT96100_MPSC_CHAN3_REG1 0x018A0C +#define GT96100_MPSC_CHAN3_REG2 0x018A10 +#define GT96100_MPSC_CHAN3_REG3 0x018A14 +#define GT96100_MPSC_CHAN3_REG4 0x018A18 +#define GT96100_MPSC_CHAN3_REG5 0x018A1C +#define GT96100_MPSC_CHAN3_REG6 0x018A20 +#define GT96100_MPSC_CHAN3_REG7 0x018A24 +#define GT96100_MPSC_CHAN3_REG8 0x018A28 +#define GT96100_MPSC_CHAN3_REG9 0x018A2C +#define GT96100_MPSC_CHAN3_REG10 0x018A30 +#define GT96100_MPSC_CHAN3_REG11 0x018A34 +#define GT96100_MPSC4_MAIN_CONFIG_LOW 0x020A00 +#define GT96100_MPSC4_MAIN_CONFIG_HIGH 0x020A04 +#define GT96100_MPSC4_PROTOCOL_CONFIG 0x020A08 +#define GT96100_MPSC_CHAN4_REG1 0x020A0C +#define GT96100_MPSC_CHAN4_REG2 0x020A10 +#define GT96100_MPSC_CHAN4_REG3 0x020A14 +#define GT96100_MPSC_CHAN4_REG4 0x020A18 +#define GT96100_MPSC_CHAN4_REG5 0x020A1C +#define GT96100_MPSC_CHAN4_REG6 0x020A20 +#define GT96100_MPSC_CHAN4_REG7 0x020A24 +#define GT96100_MPSC_CHAN4_REG8 0x020A28 +#define GT96100_MPSC_CHAN4_REG9 0x020A2C +#define GT96100_MPSC_CHAN4_REG10 0x020A30 +#define GT96100_MPSC_CHAN4_REG11 0x020A34 +#define GT96100_MPSC5_MAIN_CONFIG_LOW 0x028A00 +#define GT96100_MPSC5_MAIN_CONFIG_HIGH 0x028A04 +#define GT96100_MPSC5_PROTOCOL_CONFIG 0x028A08 +#define GT96100_MPSC_CHAN5_REG1 0x028A0C +#define GT96100_MPSC_CHAN5_REG2 0x028A10 +#define GT96100_MPSC_CHAN5_REG3 0x028A14 +#define GT96100_MPSC_CHAN5_REG4 0x028A18 +#define GT96100_MPSC_CHAN5_REG5 0x028A1C +#define GT96100_MPSC_CHAN5_REG6 0x028A20 +#define GT96100_MPSC_CHAN5_REG7 0x028A24 +#define GT96100_MPSC_CHAN5_REG8 0x028A28 +#define GT96100_MPSC_CHAN5_REG9 0x028A2C +#define GT96100_MPSC_CHAN5_REG10 0x028A30 +#define GT96100_MPSC_CHAN5_REG11 0x028A34 +#define GT96100_MPSC6_MAIN_CONFIG_LOW 0x030A00 +#define GT96100_MPSC6_MAIN_CONFIG_HIGH 0x030A04 +#define GT96100_MPSC6_PROTOCOL_CONFIG 0x030A08 +#define GT96100_MPSC_CHAN6_REG1 0x030A0C +#define GT96100_MPSC_CHAN6_REG2 0x030A10 +#define GT96100_MPSC_CHAN6_REG3 0x030A14 +#define GT96100_MPSC_CHAN6_REG4 0x030A18 +#define GT96100_MPSC_CHAN6_REG5 0x030A1C +#define GT96100_MPSC_CHAN6_REG6 0x030A20 +#define GT96100_MPSC_CHAN6_REG7 0x030A24 +#define GT96100_MPSC_CHAN6_REG8 0x030A28 +#define GT96100_MPSC_CHAN6_REG9 0x030A2C +#define GT96100_MPSC_CHAN6_REG10 0x030A30 +#define GT96100_MPSC_CHAN6_REG11 0x030A34 +#define GT96100_MPSC7_MAIN_CONFIG_LOW 0x038A00 +#define GT96100_MPSC7_MAIN_CONFIG_HIGH 0x038A04 +#define GT96100_MPSC7_PROTOCOL_CONFIG 0x038A08 +#define GT96100_MPSC_CHAN7_REG1 0x038A0C +#define GT96100_MPSC_CHAN7_REG2 0x038A10 +#define GT96100_MPSC_CHAN7_REG3 0x038A14 +#define GT96100_MPSC_CHAN7_REG4 0x038A18 +#define GT96100_MPSC_CHAN7_REG5 0x038A1C +#define GT96100_MPSC_CHAN7_REG6 0x038A20 +#define GT96100_MPSC_CHAN7_REG7 0x038A24 +#define GT96100_MPSC_CHAN7_REG8 0x038A28 +#define GT96100_MPSC_CHAN7_REG9 0x038A2C +#define GT96100_MPSC_CHAN7_REG10 0x038A30 +#define GT96100_MPSC_CHAN7_REG11 0x038A34 +/* FlexTDMs */ +/* TDPR0 - Transmit Dual Port RAM. block size 0xff */ +#define GT96100_FXTDM0_TDPR0_BLK0_BASE 0x000B00 +#define GT96100_FXTDM0_TDPR0_BLK1_BASE 0x001B00 +#define GT96100_FXTDM0_TDPR0_BLK2_BASE 0x002B00 +#define GT96100_FXTDM0_TDPR0_BLK3_BASE 0x003B00 +/* RDPR0 - Receive Dual Port RAM. block size 0xff */ +#define GT96100_FXTDM0_RDPR0_BLK0_BASE 0x004B00 +#define GT96100_FXTDM0_RDPR0_BLK1_BASE 0x005B00 +#define GT96100_FXTDM0_RDPR0_BLK2_BASE 0x006B00 +#define GT96100_FXTDM0_RDPR0_BLK3_BASE 0x007B00 +#define GT96100_FXTDM0_TX_READ_PTR 0x008B00 +#define GT96100_FXTDM0_RX_READ_PTR 0x008B04 +#define GT96100_FXTDM0_CONFIG 0x008B08 +#define GT96100_FXTDM0_AUX_CHANA_TX 0x008B0C +#define GT96100_FXTDM0_AUX_CHANA_RX 0x008B10 +#define GT96100_FXTDM0_AUX_CHANB_TX 0x008B14 +#define GT96100_FXTDM0_AUX_CHANB_RX 0x008B18 +#define GT96100_FXTDM1_TDPR1_BLK0_BASE 0x010B00 +#define GT96100_FXTDM1_TDPR1_BLK1_BASE 0x011B00 +#define GT96100_FXTDM1_TDPR1_BLK2_BASE 0x012B00 +#define GT96100_FXTDM1_TDPR1_BLK3_BASE 0x013B00 +#define GT96100_FXTDM1_RDPR1_BLK0_BASE 0x014B00 +#define GT96100_FXTDM1_RDPR1_BLK1_BASE 0x015B00 +#define GT96100_FXTDM1_RDPR1_BLK2_BASE 0x016B00 +#define GT96100_FXTDM1_RDPR1_BLK3_BASE 0x017B00 +#define GT96100_FXTDM1_TX_READ_PTR 0x018B00 +#define GT96100_FXTDM1_RX_READ_PTR 0x018B04 +#define GT96100_FXTDM1_CONFIG 0x018B08 +#define GT96100_FXTDM1_AUX_CHANA_TX 0x018B0C +#define GT96100_FXTDM1_AUX_CHANA_RX 0x018B10 +#define GT96100_FLTDM1_AUX_CHANB_TX 0x018B14 +#define GT96100_FLTDM1_AUX_CHANB_RX 0x018B18 +#define GT96100_FLTDM2_TDPR2_BLK0_BASE 0x020B00 +#define GT96100_FLTDM2_TDPR2_BLK1_BASE 0x021B00 +#define GT96100_FLTDM2_TDPR2_BLK2_BASE 0x022B00 +#define GT96100_FLTDM2_TDPR2_BLK3_BASE 0x023B00 +#define GT96100_FLTDM2_RDPR2_BLK0_BASE 0x024B00 +#define GT96100_FLTDM2_RDPR2_BLK1_BASE 0x025B00 +#define GT96100_FLTDM2_RDPR2_BLK2_BASE 0x026B00 +#define GT96100_FLTDM2_RDPR2_BLK3_BASE 0x027B00 +#define GT96100_FLTDM2_TX_READ_PTR 0x028B00 +#define GT96100_FLTDM2_RX_READ_PTR 0x028B04 +#define GT96100_FLTDM2_CONFIG 0x028B08 +#define GT96100_FLTDM2_AUX_CHANA_TX 0x028B0C +#define GT96100_FLTDM2_AUX_CHANA_RX 0x028B10 +#define GT96100_FLTDM2_AUX_CHANB_TX 0x028B14 +#define GT96100_FLTDM2_AUX_CHANB_RX 0x028B18 +#define GT96100_FLTDM3_TDPR3_BLK0_BASE 0x030B00 +#define GT96100_FLTDM3_TDPR3_BLK1_BASE 0x031B00 +#define GT96100_FLTDM3_TDPR3_BLK2_BASE 0x032B00 +#define GT96100_FLTDM3_TDPR3_BLK3_BASE 0x033B00 +#define GT96100_FXTDM3_RDPR3_BLK0_BASE 0x034B00 +#define GT96100_FXTDM3_RDPR3_BLK1_BASE 0x035B00 +#define GT96100_FXTDM3_RDPR3_BLK2_BASE 0x036B00 +#define GT96100_FXTDM3_RDPR3_BLK3_BASE 0x037B00 +#define GT96100_FXTDM3_TX_READ_PTR 0x038B00 +#define GT96100_FXTDM3_RX_READ_PTR 0x038B04 +#define GT96100_FXTDM3_CONFIG 0x038B08 +#define GT96100_FXTDM3_AUX_CHANA_TX 0x038B0C +#define GT96100_FXTDM3_AUX_CHANA_RX 0x038B10 +#define GT96100_FXTDM3_AUX_CHANB_TX 0x038B14 +#define GT96100_FXTDM3_AUX_CHANB_RX 0x038B18 +/* Baud Rate Generators */ +#define GT96100_BRG0_CONFIG 0x102A00 +#define GT96100_BRG0_BAUD_TUNE 0x102A04 +#define GT96100_BRG1_CONFIG 0x102A08 +#define GT96100_BRG1_BAUD_TUNE 0x102A0C +#define GT96100_BRG2_CONFIG 0x102A10 +#define GT96100_BRG2_BAUD_TUNE 0x102A14 +#define GT96100_BRG3_CONFIG 0x102A18 +#define GT96100_BRG3_BAUD_TUNE 0x102A1C +#define GT96100_BRG4_CONFIG 0x102A20 +#define GT96100_BRG4_BAUD_TUNE 0x102A24 +#define GT96100_BRG5_CONFIG 0x102A28 +#define GT96100_BRG5_BAUD_TUNE 0x102A2C +#define GT96100_BRG6_CONFIG 0x102A30 +#define GT96100_BRG6_BAUD_TUNE 0x102A34 +#define GT96100_BRG7_CONFIG 0x102A38 +#define GT96100_BRG7_BAUD_TUNE 0x102A3C +/* Routing Registers */ +#define GT96100_ROUTE_MAIN 0x101A00 +#define GT96100_ROUTE_RX_CLOCK 0x101A10 +#define GT96100_ROUTE_TX_CLOCK 0x101A20 +/* General Purpose Ports */ +#define GT96100_GPP_CONFIG0 0x100A00 +#define GT96100_GPP_CONFIG1 0x100A04 +#define GT96100_GPP_CONFIG2 0x100A08 +#define GT96100_GPP_CONFIG3 0x100A0C +#define GT96100_GPP_IO0 0x100A20 +#define GT96100_GPP_IO1 0x100A24 +#define GT96100_GPP_IO2 0x100A28 +#define GT96100_GPP_IO3 0x100A2C +#define GT96100_GPP_DATA0 0x100A40 +#define GT96100_GPP_DATA1 0x100A44 +#define GT96100_GPP_DATA2 0x100A48 +#define GT96100_GPP_DATA3 0x100A4C +#define GT96100_GPP_LEVEL0 0x100A60 +#define GT96100_GPP_LEVEL1 0x100A64 +#define GT96100_GPP_LEVEL2 0x100A68 +#define GT96100_GPP_LEVEL3 0x100A6C +/* Watchdog */ +#define GT96100_WD_CONFIG 0x101A80 +#define GT96100_WD_VALUE 0x101A84 +/* Communication Unit Arbiter */ +#define GT96100_COMM_UNIT_ARBTR_CONFIG 0x101AC0 +/* PCI Arbiters */ +#define GT96100_PCI0_ARBTR_CONFIG 0x101AE0 +#define GT96100_PCI1_ARBTR_CONFIG 0x101AE4 +/* CIU Arbiter */ +#define GT96100_CIU_ARBITER_CONFIG 0x101AC0 +/* Interrupt Controller */ +#define GT96100_MAIN_CAUSE 0x000C18 +#define GT96100_INT0_MAIN_MASK 0x000C1C +#define GT96100_INT1_MAIN_MASK 0x000C24 +#define GT96100_HIGH_CAUSE 0x000C98 +#define GT96100_INT0_HIGH_MASK 0x000C9C +#define GT96100_INT1_HIGH_MASK 0x000CA4 +#define GT96100_INT0_SELECT 0x000C70 +#define GT96100_INT1_SELECT 0x000C74 +#define GT96100_SERIAL_CAUSE 0x103A00 +#define GT96100_SERINT0_MASK 0x103A80 +#define GT96100_SERINT1_MASK 0x103A88 + +#endif /* _GT96100_H */ diff --git a/trunk/include/asm-mips/hazards.h b/trunk/include/asm-mips/hazards.h index 0fe02945feba..25f5e8a4177d 100644 --- a/trunk/include/asm-mips/hazards.h +++ b/trunk/include/asm-mips/hazards.h @@ -12,95 +12,102 @@ #ifdef __ASSEMBLY__ -#define ASMMACRO(name, code...) .macro name; code; .endm -#else -#define ASMMACRO(name, code...) \ -__asm__(".macro " #name "; " #code "; .endm"); \ - \ -static inline void name(void) \ -{ \ - __asm__ __volatile__ (#name); \ -} + .macro _ssnop + sll $0, $0, 1 + .endm -#endif + .macro _ehb + sll $0, $0, 3 + .endm + +/* + * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent + * use of the JTLB for instructions should not occur for 4 cpu cycles and use + * for data translations should not occur for 3 cpu cycles. + */ +#ifdef CONFIG_CPU_RM9000 + + .macro mtc0_tlbw_hazard + .set push + .set mips32 + _ssnop; _ssnop; _ssnop; _ssnop + .set pop + .endm -ASMMACRO(_ssnop, - sll $0, $0, 1 - ) + .macro tlbw_eret_hazard + .set push + .set mips32 + _ssnop; _ssnop; _ssnop; _ssnop + .set pop + .endm -ASMMACRO(_ehb, - sll $0, $0, 3 - ) +#else /* - * TLB hazards + * The taken branch will result in a two cycle penalty for the two killed + * instructions on R4000 / R4400. Other processors only have a single cycle + * hazard so this is nice trick to have an optimal code for a range of + * processors. */ -#if defined(CONFIG_CPU_MIPSR2) + .macro mtc0_tlbw_hazard + b . + 8 + .endm + + .macro tlbw_eret_hazard + .endm +#endif /* - * MIPSR2 defines ehb for hazard avoidance + * mtc0->mfc0 hazard + * The 24K has a 2 cycle mtc0/mfc0 execution hazard. + * It is a MIPS32R2 processor so ehb will clear the hazard. */ -ASMMACRO(mtc0_tlbw_hazard, - _ehb - ) -ASMMACRO(tlbw_use_hazard, - _ehb - ) -ASMMACRO(tlb_probe_hazard, - _ehb - ) -ASMMACRO(irq_enable_hazard, - ) -ASMMACRO(irq_disable_hazard, - _ehb - ) -ASMMACRO(back_to_back_c0_hazard, - _ehb - ) +#ifdef CONFIG_CPU_MIPSR2 /* - * gcc has a tradition of misscompiling the previous construct using the - * address of a label as argument to inline assembler. Gas otoh has the - * annoying difference between la and dla which are only usable for 32-bit - * rsp. 64-bit code, so can't be used without conditional compilation. - * The alterantive is switching the assembler to 64-bit code which happens - * to work right even for 32-bit code ... + * Use a macro for ehb unless explicit support for MIPSR2 is enabled */ -#define instruction_hazard() \ -do { \ - unsigned long tmp; \ - \ - __asm__ __volatile__( \ - " .set mips64r2 \n" \ - " dla %0, 1f \n" \ - " jr.hb %0 \n" \ - " .set mips0 \n" \ - "1: \n" \ - : "=r" (tmp)); \ -} while (0) -#elif defined(CONFIG_CPU_R10000) +#define irq_enable_hazard \ + _ehb + +#define irq_disable_hazard \ + _ehb + +#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) /* * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. */ -ASMMACRO(mtc0_tlbw_hazard, - ) -ASMMACRO(tlbw_use_hazard, - ) -ASMMACRO(tlb_probe_hazard, - ) -ASMMACRO(irq_enable_hazard, - ) -ASMMACRO(irq_disable_hazard, - ) -ASMMACRO(back_to_back_c0_hazard, - ) -#define instruction_hazard() do { } while (0) +#define irq_enable_hazard -#elif defined(CONFIG_CPU_RM9000) +#define irq_disable_hazard + +#else + +/* + * Classic MIPS needs 1 - 3 nops or ssnops + */ +#define irq_enable_hazard +#define irq_disable_hazard \ + _ssnop; _ssnop; _ssnop + +#endif + +#else /* __ASSEMBLY__ */ + +__asm__( + " .macro _ssnop \n" + " sll $0, $0, 1 \n" + " .endm \n" + " \n" + " .macro _ehb \n" + " sll $0, $0, 3 \n" + " .endm \n"); + +#ifdef CONFIG_CPU_RM9000 /* * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent @@ -108,73 +115,176 @@ ASMMACRO(back_to_back_c0_hazard, * for data translations should not occur for 3 cpu cycles. */ -ASMMACRO(mtc0_tlbw_hazard, - _ssnop; _ssnop; _ssnop; _ssnop - ) -ASMMACRO(tlbw_use_hazard, - _ssnop; _ssnop; _ssnop; _ssnop - ) -ASMMACRO(tlb_probe_hazard, - _ssnop; _ssnop; _ssnop; _ssnop - ) -ASMMACRO(irq_enable_hazard, - ) -ASMMACRO(irq_disable_hazard, - ) -ASMMACRO(back_to_back_c0_hazard, - ) -#define instruction_hazard() do { } while (0) +#define mtc0_tlbw_hazard() \ + __asm__ __volatile__( \ + " .set mips32 \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " .set mips0 \n") -#elif defined(CONFIG_CPU_SB1) +#define tlbw_use_hazard() \ + __asm__ __volatile__( \ + " .set mips32 \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " _ssnop \n" \ + " .set mips0 \n") + +#else /* - * Mostly like R4000 for historic reasons + * Overkill warning ... */ -ASMMACRO(mtc0_tlbw_hazard, - ) -ASMMACRO(tlbw_use_hazard, - ) -ASMMACRO(tlb_probe_hazard, - ) -ASMMACRO(irq_enable_hazard, - ) -ASMMACRO(irq_disable_hazard, - _ssnop; _ssnop; _ssnop - ) -ASMMACRO(back_to_back_c0_hazard, - ) -#define instruction_hazard() do { } while (0) +#define mtc0_tlbw_hazard() \ + __asm__ __volatile__( \ + " .set noreorder \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " .set reorder \n") + +#define tlbw_use_hazard() \ + __asm__ __volatile__( \ + " .set noreorder \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " nop \n" \ + " .set reorder \n") + +#endif + +/* + * Interrupt enable/disable hazards + * Some processors have hazards when modifying + * the status register to change the interrupt state + */ + +#ifdef CONFIG_CPU_MIPSR2 + +__asm__(" .macro irq_enable_hazard \n" + " _ehb \n" + " .endm \n" + " \n" + " .macro irq_disable_hazard \n" + " _ehb \n" + " .endm \n"); + +#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) + +/* + * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. + */ + +__asm__( + " .macro irq_enable_hazard \n" + " .endm \n" + " \n" + " .macro irq_disable_hazard \n" + " .endm \n"); #else /* - * Finally the catchall case for all other processors including R4000, R4400, - * R4600, R4700, R5000, RM7000, NEC VR41xx etc. + * Default for classic MIPS processors. Assume worst case hazards but don't + * care about the irq_enable_hazard - sooner or later the hardware will + * enable it and we don't care when exactly. + */ + +__asm__( + " # \n" + " # There is a hazard but we do not care \n" + " # \n" + " .macro\tirq_enable_hazard \n" + " .endm \n" + " \n" + " .macro\tirq_disable_hazard \n" + " _ssnop \n" + " _ssnop \n" + " _ssnop \n" + " .endm \n"); + +#endif + +#define irq_enable_hazard() \ + __asm__ __volatile__("irq_enable_hazard") +#define irq_disable_hazard() \ + __asm__ __volatile__("irq_disable_hazard") + + +/* + * Back-to-back hazards - * - * The taken branch will result in a two cycle penalty for the two killed - * instructions on R4000 / R4400. Other processors only have a single cycle - * hazard so this is nice trick to have an optimal code for a range of - * processors. + * What is needed to separate a move to cp0 from a subsequent read from the + * same cp0 register? */ -ASMMACRO(mtc0_tlbw_hazard, - nop - ) -ASMMACRO(tlbw_use_hazard, - nop; nop; nop - ) -ASMMACRO(tlb_probe_hazard, - nop; nop; nop - ) -ASMMACRO(irq_enable_hazard, - ) -ASMMACRO(irq_disable_hazard, - nop; nop; nop - ) -ASMMACRO(back_to_back_c0_hazard, - _ssnop; _ssnop; _ssnop; - ) -#define instruction_hazard() do { } while (0) +#ifdef CONFIG_CPU_MIPSR2 + +__asm__(" .macro back_to_back_c0_hazard \n" + " _ehb \n" + " .endm \n"); + +#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) || \ + defined(CONFIG_CPU_SB1) + +__asm__(" .macro back_to_back_c0_hazard \n" + " .endm \n"); + +#else + +__asm__(" .macro back_to_back_c0_hazard \n" + " .set noreorder \n" + " _ssnop \n" + " _ssnop \n" + " _ssnop \n" + " .set reorder \n" + " .endm"); #endif +#define back_to_back_c0_hazard() \ + __asm__ __volatile__("back_to_back_c0_hazard") + + +/* + * Instruction execution hazard + */ +#ifdef CONFIG_CPU_MIPSR2 +/* + * gcc has a tradition of misscompiling the previous construct using the + * address of a label as argument to inline assembler. Gas otoh has the + * annoying difference between la and dla which are only usable for 32-bit + * rsp. 64-bit code, so can't be used without conditional compilation. + * The alterantive is switching the assembler to 64-bit code which happens + * to work right even for 32-bit code ... + */ +#define instruction_hazard() \ +do { \ + unsigned long tmp; \ + \ + __asm__ __volatile__( \ + " .set mips64r2 \n" \ + " dla %0, 1f \n" \ + " jr.hb %0 \n" \ + " .set mips0 \n" \ + "1: \n" \ + : "=r" (tmp)); \ +} while (0) + +#else +#define instruction_hazard() do { } while (0) +#endif + +extern void mips_ihb(void); + +#endif /* __ASSEMBLY__ */ + #endif /* _ASM_HAZARDS_H */ diff --git a/trunk/include/asm-mips/irq.h b/trunk/include/asm-mips/irq.h index d35c61776a02..896550bad322 100644 --- a/trunk/include/asm-mips/irq.h +++ b/trunk/include/asm-mips/irq.h @@ -76,4 +76,8 @@ extern int setup_irq_smtc(unsigned int irq, struct irqaction * new, unsigned long hwmask); #endif /* CONFIG_MIPS_MT_SMTC */ +#ifdef CONFIG_SMP +#define ARCH_HAS_IRQ_PER_CPU +#endif + #endif /* _ASM_IRQ_H */ diff --git a/trunk/include/asm-mips/mach-atlas/mc146818rtc.h b/trunk/include/asm-mips/mach-atlas/mc146818rtc.h index a73a5698420c..397522ea5565 100644 --- a/trunk/include/asm-mips/mach-atlas/mc146818rtc.h +++ b/trunk/include/asm-mips/mach-atlas/mc146818rtc.h @@ -28,12 +28,10 @@ #include #include -#define ARCH_RTC_LOCATION - #define RTC_PORT(x) (ATLAS_RTC_ADR_REG + (x) * 8) #define RTC_IO_EXTENT 0x100 #define RTC_IOMAPPED 0 -#define RTC_IRQ ATLAS_INT_RTC +#define RTC_IRQ ATLASINT_RTC static inline unsigned char CMOS_READ(unsigned long addr) { diff --git a/trunk/include/asm-mips/mach-ev96100/mach-gt64120.h b/trunk/include/asm-mips/mach-ev96100/mach-gt64120.h new file mode 100644 index 000000000000..0ef1e6c25acf --- /dev/null +++ b/trunk/include/asm-mips/mach-ev96100/mach-gt64120.h @@ -0,0 +1,46 @@ +/* + * This is a direct copy of the ev96100.h file, with a global + * search and replace. The numbers are the same. + * + * The reason I'm duplicating this is so that the 64120/96100 + * defines won't be confusing in the source code. + */ +#ifndef _ASM_GT64120_EV96100_GT64120_DEP_H +#define _ASM_GT64120_EV96100_GT64120_DEP_H + +/* + * GT96100 config space base address + */ +#define GT64120_BASE (KSEG1ADDR(0x14000000)) + +/* + * PCI Bus allocation + * + * (Guessing ...) + */ +#define GT_PCI_MEM_BASE 0x12000000UL +#define GT_PCI_MEM_SIZE 0x02000000UL +#define GT_PCI_IO_BASE 0x10000000UL +#define GT_PCI_IO_SIZE 0x02000000UL +#define GT_ISA_IO_BASE PCI_IO_BASE + +/* + * Duart I/O ports. + */ +#define EV96100_COM1_BASE_ADDR (0xBD000000 + 0x20) +#define EV96100_COM2_BASE_ADDR (0xBD000000 + 0x00) + + +/* + * EV96100 interrupt controller register base. + */ +#define EV96100_ICTRL_REGS_BASE (KSEG1ADDR(0x1f000000)) + +/* + * EV96100 UART register base. + */ +#define EV96100_UART0_REGS_BASE EV96100_COM1_BASE_ADDR +#define EV96100_UART1_REGS_BASE EV96100_COM2_BASE_ADDR +#define EV96100_BASE_BAUD ( 3686400 / 16 ) + +#endif /* _ASM_GT64120_EV96100_GT64120_DEP_H */ diff --git a/trunk/include/asm-mips/mach-excite/excite.h b/trunk/include/asm-mips/mach-excite/excite.h index 4c29ba44992c..130bd4b8edce 100644 --- a/trunk/include/asm-mips/mach-excite/excite.h +++ b/trunk/include/asm-mips/mach-excite/excite.h @@ -7,7 +7,7 @@ #define EXCITE_CPU_EXT_CLOCK 100000000 -#if !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLER__) void __init excite_kgdb_init(void); void excite_procfs_init(void); extern unsigned long memsize; diff --git a/trunk/include/asm-mips/mach-qemu/cpu-feature-overrides.h b/trunk/include/asm-mips/mach-qemu/cpu-feature-overrides.h index 529445dacedb..f4e370e27168 100644 --- a/trunk/include/asm-mips/mach-qemu/cpu-feature-overrides.h +++ b/trunk/include/asm-mips/mach-qemu/cpu-feature-overrides.h @@ -20,7 +20,7 @@ #define cpu_has_llsc 1 #define cpu_has_vtag_icache 0 -#define cpu_has_dc_aliases 0 +#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) #define cpu_has_ic_fills_f_dc 0 #define cpu_has_dsp 0 diff --git a/trunk/include/asm-mips/mips-boards/atlasint.h b/trunk/include/asm-mips/mips-boards/atlasint.h index b15e4ea0b091..fd7ebc54fa90 100644 --- a/trunk/include/asm-mips/mips-boards/atlasint.h +++ b/trunk/include/asm-mips/mips-boards/atlasint.h @@ -1,7 +1,6 @@ /* - * Copyright (C) 1999, 2006 MIPS Technologies, Inc. All rights reserved. - * Authors: Carsten Langgaard - * Maciej W. Rozycki + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. * * ######################################################################## * @@ -26,88 +25,41 @@ #ifndef _MIPS_ATLASINT_H #define _MIPS_ATLASINT_H -/* - * Interrupts 0..7 are used for Atlas CPU interrupts (nonEIC mode) - */ -#define MIPSCPU_INT_BASE 0 - -/* CPU interrupt offsets */ -#define MIPSCPU_INT_SW0 0 -#define MIPSCPU_INT_SW1 1 -#define MIPSCPU_INT_MB0 2 -#define MIPSCPU_INT_ATLAS MIPSCPU_INT_MB0 -#define MIPSCPU_INT_MB1 3 -#define MIPSCPU_INT_MB2 4 -#define MIPSCPU_INT_MB3 5 -#define MIPSCPU_INT_MB4 6 -#define MIPSCPU_INT_CPUCTR 7 - -/* - * Interrupts 8..39 are used for Atlas interrupt controller interrupts - */ -#define ATLAS_INT_BASE 8 -#define ATLAS_INT_UART (ATLAS_INT_BASE + 0) -#define ATLAS_INT_TIM0 (ATLAS_INT_BASE + 1) -#define ATLAS_INT_RES2 (ATLAS_INT_BASE + 2) -#define ATLAS_INT_RES3 (ATLAS_INT_BASE + 3) -#define ATLAS_INT_RTC (ATLAS_INT_BASE + 4) -#define ATLAS_INT_COREHI (ATLAS_INT_BASE + 5) -#define ATLAS_INT_CORELO (ATLAS_INT_BASE + 6) -#define ATLAS_INT_RES7 (ATLAS_INT_BASE + 7) -#define ATLAS_INT_PCIA (ATLAS_INT_BASE + 8) -#define ATLAS_INT_PCIB (ATLAS_INT_BASE + 9) -#define ATLAS_INT_PCIC (ATLAS_INT_BASE + 10) -#define ATLAS_INT_PCID (ATLAS_INT_BASE + 11) -#define ATLAS_INT_ENUM (ATLAS_INT_BASE + 12) -#define ATLAS_INT_DEG (ATLAS_INT_BASE + 13) -#define ATLAS_INT_ATXFAIL (ATLAS_INT_BASE + 14) -#define ATLAS_INT_INTA (ATLAS_INT_BASE + 15) -#define ATLAS_INT_INTB (ATLAS_INT_BASE + 16) -#define ATLAS_INT_ETH ATLAS_INT_INTB -#define ATLAS_INT_INTC (ATLAS_INT_BASE + 17) -#define ATLAS_INT_SCSI ATLAS_INT_INTC -#define ATLAS_INT_INTD (ATLAS_INT_BASE + 18) -#define ATLAS_INT_SERR (ATLAS_INT_BASE + 19) -#define ATLAS_INT_RES20 (ATLAS_INT_BASE + 20) -#define ATLAS_INT_RES21 (ATLAS_INT_BASE + 21) -#define ATLAS_INT_RES22 (ATLAS_INT_BASE + 22) -#define ATLAS_INT_RES23 (ATLAS_INT_BASE + 23) -#define ATLAS_INT_RES24 (ATLAS_INT_BASE + 24) -#define ATLAS_INT_RES25 (ATLAS_INT_BASE + 25) -#define ATLAS_INT_RES26 (ATLAS_INT_BASE + 26) -#define ATLAS_INT_RES27 (ATLAS_INT_BASE + 27) -#define ATLAS_INT_RES28 (ATLAS_INT_BASE + 28) -#define ATLAS_INT_RES29 (ATLAS_INT_BASE + 29) -#define ATLAS_INT_RES30 (ATLAS_INT_BASE + 30) -#define ATLAS_INT_RES31 (ATLAS_INT_BASE + 31) -#define ATLAS_INT_END (ATLAS_INT_BASE + 31) - -/* - * Interrupts 64..127 are used for Soc-it Classic interrupts - */ -#define MSC01C_INT_BASE 64 - -/* SOC-it Classic interrupt offsets */ -#define MSC01C_INT_TMR 0 -#define MSC01C_INT_PCI 1 - -/* - * Interrupts 64..127 are used for Soc-it EIC interrupts - */ -#define MSC01E_INT_BASE 64 - -/* SOC-it EIC interrupt offsets */ -#define MSC01E_INT_SW0 1 -#define MSC01E_INT_SW1 2 -#define MSC01E_INT_MB0 3 -#define MSC01E_INT_ATLAS MSC01E_INT_MB0 -#define MSC01E_INT_MB1 4 -#define MSC01E_INT_MB2 5 -#define MSC01E_INT_MB3 6 -#define MSC01E_INT_MB4 7 -#define MSC01E_INT_TMR 8 -#define MSC01E_INT_PCI 9 -#define MSC01E_INT_PERFCTR 10 -#define MSC01E_INT_CPUCTR 11 +#define ATLASINT_BASE 1 +#define ATLASINT_UART (ATLASINT_BASE+0) +#define ATLASINT_TIM0 (ATLASINT_BASE+1) +#define ATLASINT_RES2 (ATLASINT_BASE+2) +#define ATLASINT_RES3 (ATLASINT_BASE+3) +#define ATLASINT_RTC (ATLASINT_BASE+4) +#define ATLASINT_COREHI (ATLASINT_BASE+5) +#define ATLASINT_CORELO (ATLASINT_BASE+6) +#define ATLASINT_RES7 (ATLASINT_BASE+7) +#define ATLASINT_PCIA (ATLASINT_BASE+8) +#define ATLASINT_PCIB (ATLASINT_BASE+9) +#define ATLASINT_PCIC (ATLASINT_BASE+10) +#define ATLASINT_PCID (ATLASINT_BASE+11) +#define ATLASINT_ENUM (ATLASINT_BASE+12) +#define ATLASINT_DEG (ATLASINT_BASE+13) +#define ATLASINT_ATXFAIL (ATLASINT_BASE+14) +#define ATLASINT_INTA (ATLASINT_BASE+15) +#define ATLASINT_INTB (ATLASINT_BASE+16) +#define ATLASINT_ETH ATLASINT_INTB +#define ATLASINT_INTC (ATLASINT_BASE+17) +#define ATLASINT_SCSI ATLASINT_INTC +#define ATLASINT_INTD (ATLASINT_BASE+18) +#define ATLASINT_SERR (ATLASINT_BASE+19) +#define ATLASINT_RES20 (ATLASINT_BASE+20) +#define ATLASINT_RES21 (ATLASINT_BASE+21) +#define ATLASINT_RES22 (ATLASINT_BASE+22) +#define ATLASINT_RES23 (ATLASINT_BASE+23) +#define ATLASINT_RES24 (ATLASINT_BASE+24) +#define ATLASINT_RES25 (ATLASINT_BASE+25) +#define ATLASINT_RES26 (ATLASINT_BASE+26) +#define ATLASINT_RES27 (ATLASINT_BASE+27) +#define ATLASINT_RES28 (ATLASINT_BASE+28) +#define ATLASINT_RES29 (ATLASINT_BASE+29) +#define ATLASINT_RES30 (ATLASINT_BASE+30) +#define ATLASINT_RES31 (ATLASINT_BASE+31) +#define ATLASINT_END (ATLASINT_BASE+31) #endif /* !(_MIPS_ATLASINT_H) */ diff --git a/trunk/include/asm-mips/mmu_context.h b/trunk/include/asm-mips/mmu_context.h index fe065d6070ca..18b69de87daa 100644 --- a/trunk/include/asm-mips/mmu_context.h +++ b/trunk/include/asm-mips/mmu_context.h @@ -262,10 +262,10 @@ drop_mmu_context(struct mm_struct *mm, unsigned cpu) /* See comments for similar code above */ prevvpe = dvpe(); oldasid = (read_c0_entryhi() & ASID_MASK); - if (smtc_live_asid[mytlb][oldasid]) { - smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); - if(smtc_live_asid[mytlb][oldasid] == 0) - smtc_flush_tlb_asid(oldasid); + if(smtc_live_asid[mytlb][oldasid]) { + smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); + if(smtc_live_asid[mytlb][oldasid] == 0) + smtc_flush_tlb_asid(oldasid); } /* See comments for similar code above */ write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) diff --git a/trunk/include/asm-mips/page.h b/trunk/include/asm-mips/page.h index 85b258ee7090..219d359861f3 100644 --- a/trunk/include/asm-mips/page.h +++ b/trunk/include/asm-mips/page.h @@ -34,8 +34,6 @@ #ifndef __ASSEMBLY__ -#include - extern void clear_page(void * page); extern void copy_page(void * to, void * from); @@ -55,7 +53,7 @@ static inline void clear_user_page(void *addr, unsigned long vaddr, extern void (*flush_data_cache_page)(unsigned long addr); clear_page(addr); - if (pages_do_alias((unsigned long) addr, vaddr & PAGE_MASK)) + if (pages_do_alias((unsigned long) addr, vaddr)) flush_data_cache_page((unsigned long)addr); } @@ -65,8 +63,7 @@ static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, extern void (*flush_data_cache_page)(unsigned long addr); copy_page(vto, vfrom); - if (!cpu_has_ic_fills_f_dc || - pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) + if (pages_do_alias((unsigned long)vto, vaddr)) flush_data_cache_page((unsigned long)vto); } @@ -77,17 +74,15 @@ static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, #ifdef CONFIG_CPU_MIPS32 typedef struct { unsigned long pte_low, pte_high; } pte_t; #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) - #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; }) #else typedef struct { unsigned long long pte; } pte_t; #define pte_val(x) ((x).pte) - #define __pte(x) ((pte_t) { (x) } ) #endif #else typedef struct { unsigned long pte; } pte_t; #define pte_val(x) ((x).pte) -#define __pte(x) ((pte_t) { (x) } ) #endif +#define __pte(x) ((pte_t) { (x) } ) /* * For 3-level pagetables we defines these ourselves, for 2-level the diff --git a/trunk/include/asm-mips/pgtable-64.h b/trunk/include/asm-mips/pgtable-64.h index d05fb6f38aa7..c59a1e21f5b0 100644 --- a/trunk/include/asm-mips/pgtable-64.h +++ b/trunk/include/asm-mips/pgtable-64.h @@ -93,12 +93,8 @@ #define PTRS_PER_PMD ((PAGE_SIZE << PMD_ORDER) / sizeof(pmd_t)) #define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) -#if PGDIR_SIZE >= TASK_SIZE -#define USER_PTRS_PER_PGD (1) -#else #define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) -#endif -#define FIRST_USER_ADDRESS 0UL +#define FIRST_USER_ADDRESS 0 #define VMALLOC_START MAP_BASE #define VMALLOC_END \ diff --git a/trunk/include/asm-mips/ptrace.h b/trunk/include/asm-mips/ptrace.h index 4fb0fc43ffd7..4113316ee0da 100644 --- a/trunk/include/asm-mips/ptrace.h +++ b/trunk/include/asm-mips/ptrace.h @@ -10,6 +10,8 @@ #define _ASM_PTRACE_H +#include + /* 0 - 31 are integer registers, 32 - 63 are fp registers. */ #define FPR_BASE 32 #define PC 64 @@ -71,7 +73,6 @@ struct pt_regs { #ifdef __KERNEL__ #include -#include /* * Does the process account for user or for system time? diff --git a/trunk/include/asm-mips/serial.h b/trunk/include/asm-mips/serial.h index 035637c67e7c..584bd9c0ab2e 100644 --- a/trunk/include/asm-mips/serial.h +++ b/trunk/include/asm-mips/serial.h @@ -52,9 +52,9 @@ #endif /* - * Galileo EV64120 evaluation board + * Both Galileo boards have the same UART mappings. */ -#ifdef CONFIG_MIPS_EV64120 +#if defined (CONFIG_MIPS_EV96100) || defined (CONFIG_MIPS_EV64120) #include #include #define EV96100_SERIAL_PORT_DEFNS \ diff --git a/trunk/include/asm-mips/sibyte/sb1250_defs.h b/trunk/include/asm-mips/sibyte/sb1250_defs.h index a885491217c1..335dbaf1d831 100644 --- a/trunk/include/asm-mips/sibyte/sb1250_defs.h +++ b/trunk/include/asm-mips/sibyte/sb1250_defs.h @@ -212,7 +212,7 @@ * Note: you'll need to define uint32_t and uint64_t in your headers. */ -#if !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLER__) #define _SB_MAKE64(x) ((uint64_t)(x)) #define _SB_MAKE32(x) ((uint32_t)(x)) #else @@ -251,9 +251,9 @@ */ -#if defined(__mips64) && !defined(__ASSEMBLY__) +#if defined(__mips64) && !defined(__ASSEMBLER__) #define SBWRITECSR(csr,val) *((volatile uint64_t *) PHYS_TO_K1(csr)) = (val) #define SBREADCSR(csr) (*((volatile uint64_t *) PHYS_TO_K1(csr))) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif diff --git a/trunk/include/asm-mips/sibyte/sb1250_scd.h b/trunk/include/asm-mips/sibyte/sb1250_scd.h index 7ed0bb611e56..f4178bdcfcb0 100644 --- a/trunk/include/asm-mips/sibyte/sb1250_scd.h +++ b/trunk/include/asm-mips/sibyte/sb1250_scd.h @@ -149,7 +149,7 @@ * (For the assembler version, sysrev and dest may be the same register. * Also, it clobbers AT.) */ -#ifdef __ASSEMBLY__ +#ifdef __ASSEMBLER__ #define SYS_SOC_TYPE(dest, sysrev) \ .set push ; \ .set reorder ; \ diff --git a/trunk/include/asm-mips/signal.h b/trunk/include/asm-mips/signal.h index 8b391a2f0814..87a1dff95199 100644 --- a/trunk/include/asm-mips/signal.h +++ b/trunk/include/asm-mips/signal.h @@ -108,8 +108,17 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ #define SIG_BLOCK 1 /* for blocking signals */ #define SIG_UNBLOCK 2 /* for unblocking signals */ #define SIG_SETMASK 3 /* for setting the signal mask */ +#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility: + set only the low 32 bit of the sigset. */ -#include +/* Type of a signal handler. */ +typedef void __signalfn_t(int); +typedef __signalfn_t __user *__sighandler_t; + +/* Fake signal functions */ +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ struct sigaction { unsigned int sa_flags; diff --git a/trunk/include/asm-mips/spinlock.h b/trunk/include/asm-mips/spinlock.h index 4c1a1b53aeaf..669b8e349ff2 100644 --- a/trunk/include/asm-mips/spinlock.h +++ b/trunk/include/asm-mips/spinlock.h @@ -239,51 +239,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) : "memory"); } -static inline int __raw_read_trylock(raw_rwlock_t *rw) -{ - unsigned int tmp; - int ret; - - if (R10000_LLSC_WAR) { - __asm__ __volatile__( - " .set noreorder # __raw_read_trylock \n" - " li %2, 0 \n" - "1: ll %1, %3 \n" - " bnez %1, 2f \n" - " addu %1, 1 \n" - " sc %1, %0 \n" - " beqzl %1, 1b \n" - " .set reorder \n" -#ifdef CONFIG_SMP - " sync \n" -#endif - " li %2, 1 \n" - "2: \n" - : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) - : "m" (rw->lock) - : "memory"); - } else { - __asm__ __volatile__( - " .set noreorder # __raw_read_trylock \n" - " li %2, 0 \n" - "1: ll %1, %3 \n" - " bnez %1, 2f \n" - " addu %1, 1 \n" - " sc %1, %0 \n" - " beqz %1, 1b \n" - " .set reorder \n" -#ifdef CONFIG_SMP - " sync \n" -#endif - " li %2, 1 \n" - "2: \n" - : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) - : "m" (rw->lock) - : "memory"); - } - - return ret; -} +#define __raw_read_trylock(lock) generic__raw_read_trylock(lock) static inline int __raw_write_trylock(raw_rwlock_t *rw) { @@ -327,5 +283,4 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) return ret; } - #endif /* _ASM_SPINLOCK_H */ diff --git a/trunk/include/asm-mips/timex.h b/trunk/include/asm-mips/timex.h index b80de8e0fbbd..98aa737b34aa 100644 --- a/trunk/include/asm-mips/timex.h +++ b/trunk/include/asm-mips/timex.h @@ -8,8 +8,6 @@ #ifndef _ASM_TIMEX_H #define _ASM_TIMEX_H -#ifdef __KERNEL__ - #include /* @@ -53,6 +51,4 @@ static inline cycles_t get_cycles (void) return read_c0_count(); } -#endif /* __KERNEL__ */ - #endif /* _ASM_TIMEX_H */ diff --git a/trunk/include/asm-mips/unistd.h b/trunk/include/asm-mips/unistd.h index c39142920fe6..610ccb8a50b3 100644 --- a/trunk/include/asm-mips/unistd.h +++ b/trunk/include/asm-mips/unistd.h @@ -313,7 +313,7 @@ #define __NR_mknodat (__NR_Linux + 290) #define __NR_fchownat (__NR_Linux + 291) #define __NR_futimesat (__NR_Linux + 292) -#define __NR_fstatat64 (__NR_Linux + 293) +#define __NR_fstatat (__NR_Linux + 293) #define __NR_unlinkat (__NR_Linux + 294) #define __NR_renameat (__NR_Linux + 295) #define __NR_linkat (__NR_Linux + 296) @@ -329,18 +329,16 @@ #define __NR_tee (__NR_Linux + 306) #define __NR_vmsplice (__NR_Linux + 307) #define __NR_move_pages (__NR_Linux + 308) -#define __NR_set_robust_list (__NR_Linux + 309) -#define __NR_get_robust_list (__NR_Linux + 310) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 310 +#define __NR_Linux_syscalls 308 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 310 +#define __NR_O32_Linux_syscalls 308 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -600,7 +598,7 @@ #define __NR_mknodat (__NR_Linux + 249) #define __NR_fchownat (__NR_Linux + 250) #define __NR_futimesat (__NR_Linux + 251) -#define __NR_newfstatat (__NR_Linux + 252) +#define __NR_fstatat (__NR_Linux + 252) #define __NR_unlinkat (__NR_Linux + 253) #define __NR_renameat (__NR_Linux + 254) #define __NR_linkat (__NR_Linux + 255) @@ -616,18 +614,16 @@ #define __NR_tee (__NR_Linux + 265) #define __NR_vmsplice (__NR_Linux + 266) #define __NR_move_pages (__NR_Linux + 267) -#define __NR_set_robust_list (__NR_Linux + 268) -#define __NR_get_robust_list (__NR_Linux + 269) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 269 +#define __NR_Linux_syscalls 267 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 269 +#define __NR_64_Linux_syscalls 267 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -891,7 +887,7 @@ #define __NR_mknodat (__NR_Linux + 253) #define __NR_fchownat (__NR_Linux + 254) #define __NR_futimesat (__NR_Linux + 255) -#define __NR_newfstatat (__NR_Linux + 256) +#define __NR_fstatat (__NR_Linux + 256) #define __NR_unlinkat (__NR_Linux + 257) #define __NR_renameat (__NR_Linux + 258) #define __NR_linkat (__NR_Linux + 259) @@ -907,18 +903,16 @@ #define __NR_tee (__NR_Linux + 269) #define __NR_vmsplice (__NR_Linux + 270) #define __NR_move_pages (__NR_Linux + 271) -#define __NR_set_robust_list (__NR_Linux + 272) -#define __NR_get_robust_list (__NR_Linux + 273) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 273 +#define __NR_Linux_syscalls 271 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 273 +#define __NR_N32_Linux_syscalls 271 #ifdef __KERNEL__ diff --git a/trunk/include/asm-mips/user.h b/trunk/include/asm-mips/user.h index 61f2a093b91b..89bf8b4cab3c 100644 --- a/trunk/include/asm-mips/user.h +++ b/trunk/include/asm-mips/user.h @@ -8,8 +8,6 @@ #ifndef _ASM_USER_H #define _ASM_USER_H -#ifdef __KERNEL__ - #include #include @@ -57,6 +55,4 @@ struct user { #define HOST_DATA_START_ADDR (u.start_data) #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -#endif /* __KERNEL__ */ - #endif /* _ASM_USER_H */ diff --git a/trunk/include/asm-um/alternative-asm.i b/trunk/include/asm-um/alternative-asm.i deleted file mode 100644 index cae9faca132f..000000000000 --- a/trunk/include/asm-um/alternative-asm.i +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_ALTERNATIVE_ASM_I -#define __UM_ALTERNATIVE_ASM_I - -#include "asm/arch/alternative-asm.i" - -#endif diff --git a/trunk/include/asm-um/frame.i b/trunk/include/asm-um/frame.i deleted file mode 100644 index 09d5dca5d928..000000000000 --- a/trunk/include/asm-um/frame.i +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __UM_FRAME_I -#define __UM_FRAME_I - -#include "asm/arch/frame.i" - -#endif diff --git a/trunk/include/asm-x86_64/acpi.h b/trunk/include/asm-x86_64/acpi.h index ed59aa4c6ff9..2c95a319c056 100644 --- a/trunk/include/asm-x86_64/acpi.h +++ b/trunk/include/asm-x86_64/acpi.h @@ -155,6 +155,8 @@ extern void acpi_reserve_bootmem(void); #endif /*CONFIG_ACPI_SLEEP*/ +#define boot_cpu_physical_apicid boot_cpu_id + extern int acpi_disabled; extern int acpi_pci_disabled; diff --git a/trunk/include/asm-x86_64/alternative-asm.i b/trunk/include/asm-x86_64/alternative-asm.i deleted file mode 100644 index e4041f4fa4dc..000000000000 --- a/trunk/include/asm-x86_64/alternative-asm.i +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#ifdef CONFIG_SMP - .macro LOCK_PREFIX -1: lock - .section .smp_locks,"a" - .align 8 - .quad 1b - .previous - .endm -#else - .macro LOCK_PREFIX - .endm -#endif diff --git a/trunk/include/asm-x86_64/apic.h b/trunk/include/asm-x86_64/apic.h index 9e66d32330c9..9c96a0a8d1bd 100644 --- a/trunk/include/asm-x86_64/apic.h +++ b/trunk/include/asm-x86_64/apic.h @@ -17,8 +17,6 @@ extern int apic_verbosity; extern int apic_runs_main_timer; -extern int ioapic_force; -extern int apic_mapped; /* * Define the default level of output to be very little @@ -31,6 +29,8 @@ extern int apic_mapped; printk(s, ##a); \ } while (0) +#ifdef CONFIG_X86_LOCAL_APIC + struct pt_regs; /* @@ -95,12 +95,17 @@ extern void setup_APIC_extened_lvt(unsigned char lvt_off, unsigned char vector, #define K8_APIC_EXT_INT_MSG_EXT 0x7 #define K8_APIC_EXT_LVT_ENTRY_THRESHOLD 0 +extern int disable_timer_pin_1; + + void smp_send_timer_broadcast_ipi(void); void switch_APIC_timer_to_ipi(void *cpumask); void switch_ipi_to_APIC_timer(void *cpumask); #define ARCH_APICTIMER_STOPS_ON_C3 1 +#endif /* CONFIG_X86_LOCAL_APIC */ + extern unsigned boot_cpu_id; #endif /* __ASM_APIC_H */ diff --git a/trunk/include/asm-x86_64/bitops.h b/trunk/include/asm-x86_64/bitops.h index 5b535eaf5309..f7ba57b1cc08 100644 --- a/trunk/include/asm-x86_64/bitops.h +++ b/trunk/include/asm-x86_64/bitops.h @@ -399,8 +399,6 @@ static __inline__ int fls(int x) return r+1; } -#define ARCH_HAS_FAST_MULTIPLIER 1 - #include #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-x86_64/calgary.h b/trunk/include/asm-x86_64/calgary.h index 6b93f5a3a5c8..4e3919524240 100644 --- a/trunk/include/asm-x86_64/calgary.h +++ b/trunk/include/asm-x86_64/calgary.h @@ -24,6 +24,7 @@ #ifndef _ASM_X86_64_CALGARY_H #define _ASM_X86_64_CALGARY_H +#include #include #include #include @@ -33,12 +34,12 @@ struct iommu_table { unsigned long it_base; /* mapped address of tce table */ unsigned long it_hint; /* Hint for next alloc */ unsigned long *it_map; /* A simple allocation bitmap for now */ - void __iomem *bbar; /* Bridge BAR */ - u64 tar_val; /* Table Address Register */ - struct timer_list watchdog_timer; spinlock_t it_lock; /* Protects it_map */ unsigned int it_size; /* Size of iommu table in entries */ unsigned char it_busno; /* Bus number this table belongs to */ + void __iomem *bbar; + u64 tar_val; + struct timer_list watchdog_timer; }; #define TCE_TABLE_SIZE_UNSPECIFIED ~0 diff --git a/trunk/include/asm-x86_64/dwarf2.h b/trunk/include/asm-x86_64/dwarf2.h index eedc08526b0b..0744db777676 100644 --- a/trunk/include/asm-x86_64/dwarf2.h +++ b/trunk/include/asm-x86_64/dwarf2.h @@ -13,7 +13,7 @@ away for older version. */ -#ifdef CONFIG_AS_CFI +#ifdef CONFIG_UNWIND_INFO #define CFI_STARTPROC .cfi_startproc #define CFI_ENDPROC .cfi_endproc @@ -28,11 +28,6 @@ #define CFI_REMEMBER_STATE .cfi_remember_state #define CFI_RESTORE_STATE .cfi_restore_state #define CFI_UNDEFINED .cfi_undefined -#ifdef CONFIG_AS_CFI_SIGNAL_FRAME -#define CFI_SIGNAL_FRAME .cfi_signal_frame -#else -#define CFI_SIGNAL_FRAME -#endif #else @@ -50,7 +45,6 @@ #define CFI_REMEMBER_STATE # #define CFI_RESTORE_STATE # #define CFI_UNDEFINED # -#define CFI_SIGNAL_FRAME # #endif diff --git a/trunk/include/asm-x86_64/e820.h b/trunk/include/asm-x86_64/e820.h index e15d3c8628f3..f65674832318 100644 --- a/trunk/include/asm-x86_64/e820.h +++ b/trunk/include/asm-x86_64/e820.h @@ -19,9 +19,13 @@ #define E820_RAM 1 #define E820_RESERVED 2 -#define E820_ACPI 3 +#define E820_ACPI 3 /* usable as RAM once ACPI tables have been read */ #define E820_NVS 4 +#define HIGH_MEMORY (1024*1024) + +#define LOWMEMSIZE() (0x9f000) + #ifndef __ASSEMBLY__ struct e820entry { u64 addr; /* start of memory segment */ @@ -52,7 +56,8 @@ extern void e820_setup_gap(void); extern unsigned long e820_hole_size(unsigned long start_pfn, unsigned long end_pfn); -extern void finish_e820_parsing(void); +extern void __init parse_memopt(char *p, char **end); +extern void __init parse_memmapopt(char *p, char **end); extern struct e820map e820; diff --git a/trunk/include/asm-x86_64/fixmap.h b/trunk/include/asm-x86_64/fixmap.h index 1b620db5b9e3..0b4ffbd1a125 100644 --- a/trunk/include/asm-x86_64/fixmap.h +++ b/trunk/include/asm-x86_64/fixmap.h @@ -37,9 +37,13 @@ enum fixed_addresses { VSYSCALL_FIRST_PAGE = VSYSCALL_LAST_PAGE + ((VSYSCALL_END-VSYSCALL_START) >> PAGE_SHIFT) - 1, VSYSCALL_HPET, FIX_HPET_BASE, +#ifdef CONFIG_X86_LOCAL_APIC FIX_APIC_BASE, /* local (CPU) APIC) -- required for SMP or not */ +#endif +#ifdef CONFIG_X86_IO_APIC FIX_IO_APIC_BASE_0, FIX_IO_APIC_BASE_END = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1, +#endif __end_of_fixed_addresses }; diff --git a/trunk/include/asm-x86_64/genapic.h b/trunk/include/asm-x86_64/genapic.h index 81e714665344..50b38e7c58e4 100644 --- a/trunk/include/asm-x86_64/genapic.h +++ b/trunk/include/asm-x86_64/genapic.h @@ -16,6 +16,7 @@ struct genapic { char *name; u32 int_delivery_mode; u32 int_dest_mode; + u32 int_delivery_dest; /* for quick IPIs */ int (*apic_id_registered)(void); cpumask_t (*target_cpus)(void); void (*init_apic_ldr)(void); diff --git a/trunk/include/asm-x86_64/i387.h b/trunk/include/asm-x86_64/i387.h index 0217b74cc9fc..cba8a3b0cded 100644 --- a/trunk/include/asm-x86_64/i387.h +++ b/trunk/include/asm-x86_64/i387.h @@ -24,7 +24,6 @@ extern unsigned int mxcsr_feature_mask; extern void mxcsr_feature_mask_init(void); extern void init_fpu(struct task_struct *child); extern int save_i387(struct _fpstate __user *buf); -extern asmlinkage void math_state_restore(void); /* * FPU lazy state save handling... @@ -32,9 +31,7 @@ extern asmlinkage void math_state_restore(void); #define unlazy_fpu(tsk) do { \ if (task_thread_info(tsk)->status & TS_USEDFPU) \ - save_init_fpu(tsk); \ - else \ - tsk->fpu_counter = 0; \ + save_init_fpu(tsk); \ } while (0) /* Ignore delayed exceptions from user space */ @@ -137,8 +134,8 @@ static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) #else : [fx] "cdaSDb" (fx), "0" (0)); #endif - if (unlikely(err) && __clear_user(fx, sizeof(struct i387_fxsave_struct))) - err = -EFAULT; + if (unlikely(err)) + __clear_user(fx, sizeof(struct i387_fxsave_struct)); /* No need to clear here because the caller clears USED_MATH */ return err; } diff --git a/trunk/include/asm-x86_64/intel_arch_perfmon.h b/trunk/include/asm-x86_64/intel_arch_perfmon.h index 8633331420ec..59c396431569 100644 --- a/trunk/include/asm-x86_64/intel_arch_perfmon.h +++ b/trunk/include/asm-x86_64/intel_arch_perfmon.h @@ -14,18 +14,6 @@ #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL (0x3c) #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) -#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX (0) -#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \ - (1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX)) - -union cpuid10_eax { - struct { - unsigned int version_id:8; - unsigned int num_counters:8; - unsigned int bit_width:8; - unsigned int mask_length:8; - } split; - unsigned int full; -}; +#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT (1 << 0) #endif /* X86_64_INTEL_ARCH_PERFMON_H */ diff --git a/trunk/include/asm-x86_64/io_apic.h b/trunk/include/asm-x86_64/io_apic.h index 5d1b5c68e36e..fb7a0909a174 100644 --- a/trunk/include/asm-x86_64/io_apic.h +++ b/trunk/include/asm-x86_64/io_apic.h @@ -10,6 +10,8 @@ * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar */ +#ifdef CONFIG_X86_IO_APIC + #ifdef CONFIG_PCI_MSI static inline int use_pci_vector(void) {return 1;} static inline void disable_edge_ioapic_vector(unsigned int vector) { } @@ -207,6 +209,10 @@ extern int timer_uses_ioapic_pin_0; extern int sis_apic_bug; /* dummy */ +#else /* !CONFIG_X86_IO_APIC */ +#define io_apic_assign_pci_irqs 0 +#endif + extern int assign_irq_vector(int irq); void enable_NMI_through_LVT0 (void * dummy); diff --git a/trunk/include/asm-x86_64/irq.h b/trunk/include/asm-x86_64/irq.h index 43469d8ab71a..9db5a1b4f7b1 100644 --- a/trunk/include/asm-x86_64/irq.h +++ b/trunk/include/asm-x86_64/irq.h @@ -44,7 +44,9 @@ static __inline__ int irq_canonicalize(int irq) return ((irq == 2) ? 9 : irq); } +#ifdef CONFIG_X86_LOCAL_APIC #define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ +#endif #ifdef CONFIG_HOTPLUG_CPU #include diff --git a/trunk/include/asm-x86_64/kexec.h b/trunk/include/asm-x86_64/kexec.h index 5fab957e1091..c564bae03433 100644 --- a/trunk/include/asm-x86_64/kexec.h +++ b/trunk/include/asm-x86_64/kexec.h @@ -1,27 +1,6 @@ #ifndef _X86_64_KEXEC_H #define _X86_64_KEXEC_H -#define PA_CONTROL_PAGE 0 -#define VA_CONTROL_PAGE 1 -#define PA_PGD 2 -#define VA_PGD 3 -#define PA_PUD_0 4 -#define VA_PUD_0 5 -#define PA_PMD_0 6 -#define VA_PMD_0 7 -#define PA_PTE_0 8 -#define VA_PTE_0 9 -#define PA_PUD_1 10 -#define VA_PUD_1 11 -#define PA_PMD_1 12 -#define VA_PMD_1 13 -#define PA_PTE_1 14 -#define VA_PTE_1 15 -#define PA_TABLE_PAGE 16 -#define PAGES_NR 17 - -#ifndef __ASSEMBLY__ - #include #include @@ -85,12 +64,4 @@ static inline void crash_setup_regs(struct pt_regs *newregs, newregs->rip = (unsigned long)current_text_addr(); } } - -NORET_TYPE void -relocate_kernel(unsigned long indirection_page, - unsigned long page_list, - unsigned long start_address) ATTRIB_NORET; - -#endif /* __ASSEMBLY__ */ - #endif /* _X86_64_KEXEC_H */ diff --git a/trunk/include/asm-x86_64/linkage.h b/trunk/include/asm-x86_64/linkage.h index b5f39d0189ce..291c2d01c44f 100644 --- a/trunk/include/asm-x86_64/linkage.h +++ b/trunk/include/asm-x86_64/linkage.h @@ -1,6 +1,6 @@ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H -#define __ALIGN .p2align 4,,15 +/* Nothing to see here... */ #endif diff --git a/trunk/include/asm-x86_64/mach_apic.h b/trunk/include/asm-x86_64/mach_apic.h index d33422450c00..0acea44c9377 100644 --- a/trunk/include/asm-x86_64/mach_apic.h +++ b/trunk/include/asm-x86_64/mach_apic.h @@ -16,6 +16,7 @@ #define INT_DELIVERY_MODE (genapic->int_delivery_mode) #define INT_DEST_MODE (genapic->int_dest_mode) +#define INT_DELIVERY_DEST (genapic->int_delivery_dest) #define TARGET_CPUS (genapic->target_cpus()) #define apic_id_registered (genapic->apic_id_registered) #define init_apic_ldr (genapic->init_apic_ldr) diff --git a/trunk/include/asm-x86_64/mce.h b/trunk/include/asm-x86_64/mce.h index 5a11146d6d9c..d13687dfd691 100644 --- a/trunk/include/asm-x86_64/mce.h +++ b/trunk/include/asm-x86_64/mce.h @@ -99,8 +99,6 @@ static inline void mce_amd_feature_init(struct cpuinfo_x86 *c) } #endif -void mce_log_therm_throt_event(unsigned int cpu, __u64 status); - extern atomic_t mce_entry; #endif diff --git a/trunk/include/asm-x86_64/mmx.h b/trunk/include/asm-x86_64/mmx.h new file mode 100644 index 000000000000..46b71da99869 --- /dev/null +++ b/trunk/include/asm-x86_64/mmx.h @@ -0,0 +1,14 @@ +#ifndef _ASM_MMX_H +#define _ASM_MMX_H + +/* + * MMX 3Dnow! helper operations + */ + +#include + +extern void *_mmx_memcpy(void *to, const void *from, size_t size); +extern void mmx_clear_page(void *page); +extern void mmx_copy_page(void *to, void *from); + +#endif diff --git a/trunk/include/asm-x86_64/mpspec.h b/trunk/include/asm-x86_64/mpspec.h index 017fddb61dc5..14fc3ddd9031 100644 --- a/trunk/include/asm-x86_64/mpspec.h +++ b/trunk/include/asm-x86_64/mpspec.h @@ -159,7 +159,13 @@ struct mpc_config_lintsrc #define MAX_MP_BUSSES 256 /* Each PCI slot may be a combo card with its own bus. 4 IRQ pins per slot. */ #define MAX_IRQ_SOURCES (MAX_MP_BUSSES * 4) -extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); +enum mp_bustype { + MP_BUS_ISA = 1, + MP_BUS_EISA, + MP_BUS_PCI, + MP_BUS_MCA +}; +extern unsigned char mp_bus_id_to_type [MAX_MP_BUSSES]; extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES]; extern unsigned int boot_cpu_physical_apicid; @@ -172,15 +178,18 @@ extern int mp_irq_entries; extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES]; extern int mpc_default_type; extern unsigned long mp_lapic_addr; +extern int pic_mode; #ifdef CONFIG_ACPI extern void mp_register_lapic (u8 id, u8 enabled); extern void mp_register_lapic_address (u64 address); +#ifdef CONFIG_X86_IO_APIC extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base); extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi); extern void mp_config_acpi_legacy_irqs (void); extern int mp_register_gsi (u32 gsi, int triggering, int polarity); +#endif /*CONFIG_X86_IO_APIC*/ #endif extern int using_apic_timer; diff --git a/trunk/include/asm-x86_64/msr.h b/trunk/include/asm-x86_64/msr.h index 37e194169fac..10f8b51cec8b 100644 --- a/trunk/include/asm-x86_64/msr.h +++ b/trunk/include/asm-x86_64/msr.h @@ -66,25 +66,14 @@ #define rdtscl(low) \ __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") -#define rdtscp(low,high,aux) \ - asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux)) - #define rdtscll(val) do { \ unsigned int __a,__d; \ asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \ (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \ } while(0) -#define rdtscpll(val, aux) do { \ - unsigned long __a, __d; \ - asm volatile (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \ - (val) = (__d << 32) | __a; \ -} while (0) - #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) -#define write_rdtscp_aux(val) wrmsr(0xc0000103, val, 0) - #define rdpmc(counter,low,high) \ __asm__ __volatile__("rdpmc" \ : "=a" (low), "=d" (high) \ diff --git a/trunk/include/asm-x86_64/mutex.h b/trunk/include/asm-x86_64/mutex.h index 16396b1de3e4..06fab6de2a88 100644 --- a/trunk/include/asm-x86_64/mutex.h +++ b/trunk/include/asm-x86_64/mutex.h @@ -25,9 +25,13 @@ do { \ \ __asm__ __volatile__( \ LOCK_PREFIX " decl (%%rdi) \n" \ - " jns 1f \n" \ - " call "#fail_fn" \n" \ - "1:" \ + " js 2f \n" \ + "1: \n" \ + \ + LOCK_SECTION_START("") \ + "2: call "#fail_fn" \n" \ + " jmp 1b \n" \ + LOCK_SECTION_END \ \ :"=D" (dummy) \ : "D" (v) \ @@ -71,9 +75,13 @@ do { \ \ __asm__ __volatile__( \ LOCK_PREFIX " incl (%%rdi) \n" \ - " jg 1f \n" \ - " call "#fail_fn" \n" \ - "1: " \ + " jle 2f \n" \ + "1: \n" \ + \ + LOCK_SECTION_START("") \ + "2: call "#fail_fn" \n" \ + " jmp 1b \n" \ + LOCK_SECTION_END \ \ :"=D" (dummy) \ : "D" (v) \ diff --git a/trunk/include/asm-x86_64/nmi.h b/trunk/include/asm-x86_64/nmi.h index cbf2669bca71..efb45c894d76 100644 --- a/trunk/include/asm-x86_64/nmi.h +++ b/trunk/include/asm-x86_64/nmi.h @@ -7,13 +7,24 @@ #include #include +struct pt_regs; + +typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu); + +/** + * set_nmi_callback + * + * Set a handler for an NMI. Only one handler may be + * set. Return 1 if the NMI was handled. + */ +void set_nmi_callback(nmi_callback_t callback); + /** - * do_nmi_callback + * unset_nmi_callback * - * Check to see if a callback exists and execute it. Return 1 - * if the handler exists and was handled successfully. + * Remove the handler previously set. */ -int do_nmi_callback(struct pt_regs *regs, int cpu); +void unset_nmi_callback(void); #ifdef CONFIG_PM @@ -37,32 +48,25 @@ static inline void unset_nmi_pm_callback(struct pm_dev * dev) #endif /* CONFIG_PM */ extern void default_do_nmi(struct pt_regs *); -extern void die_nmi(char *str, struct pt_regs *regs, int do_panic); +extern void die_nmi(char *str, struct pt_regs *regs); #define get_nmi_reason() inb(0x61) extern int panic_on_timeout; extern int unknown_nmi_panic; -extern int nmi_watchdog_enabled; extern int check_nmi_watchdog(void); -extern int avail_to_resrv_perfctr_nmi_bit(unsigned int); -extern int avail_to_resrv_perfctr_nmi(unsigned int); -extern int reserve_perfctr_nmi(unsigned int); -extern void release_perfctr_nmi(unsigned int); -extern int reserve_evntsel_nmi(unsigned int); -extern void release_evntsel_nmi(unsigned int); - -extern void setup_apic_nmi_watchdog (void *); -extern void stop_apic_nmi_watchdog (void *); + +extern void setup_apic_nmi_watchdog (void); +extern int reserve_lapic_nmi(void); +extern void release_lapic_nmi(void); extern void disable_timer_nmi_watchdog(void); extern void enable_timer_nmi_watchdog(void); -extern int nmi_watchdog_tick (struct pt_regs * regs, unsigned reason); +extern void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason); extern void nmi_watchdog_default(void); extern int setup_nmi_watchdog(char *); -extern atomic_t nmi_active; extern unsigned int nmi_watchdog; #define NMI_DEFAULT -1 #define NMI_NONE 0 diff --git a/trunk/include/asm-x86_64/pci-direct.h b/trunk/include/asm-x86_64/pci-direct.h index eba9cb471df3..036b6ca5b53b 100644 --- a/trunk/include/asm-x86_64/pci-direct.h +++ b/trunk/include/asm-x86_64/pci-direct.h @@ -2,15 +2,47 @@ #define ASM_PCI_DIRECT_H 1 #include +#include /* Direct PCI access. This is used for PCI accesses in early boot before the PCI subsystem works. */ -extern u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset); -extern u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset); -extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset); -extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val); +#define PDprintk(x...) -extern int early_pci_allowed(void); +static inline u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) +{ + u32 v; + outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); + v = inl(0xcfc); + if (v != 0xffffffff) + PDprintk("%x reading 4 from %x: %x\n", slot, offset, v); + return v; +} + +static inline u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset) +{ + u8 v; + outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); + v = inb(0xcfc + (offset&3)); + PDprintk("%x reading 1 from %x: %x\n", slot, offset, v); + return v; +} + +static inline u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset) +{ + u16 v; + outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); + v = inw(0xcfc + (offset&2)); + PDprintk("%x reading 2 from %x: %x\n", slot, offset, v); + return v; +} + +static inline void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, + u32 val) +{ + PDprintk("%x writing to %x: %x\n", slot, offset, val); + outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); + outl(val, 0xcfc); +} #endif diff --git a/trunk/include/asm-x86_64/pda.h b/trunk/include/asm-x86_64/pda.h index 14996d962bac..b47c3df9ed1d 100644 --- a/trunk/include/asm-x86_64/pda.h +++ b/trunk/include/asm-x86_64/pda.h @@ -9,24 +9,20 @@ /* Per processor datastructure. %gs points to it while the kernel runs */ struct x8664_pda { - struct task_struct *pcurrent; /* 0 Current process */ - unsigned long data_offset; /* 8 Per cpu data offset from linker - address */ - unsigned long kernelstack; /* 16 top of kernel stack for current */ - unsigned long oldrsp; /* 24 user rsp for system call */ - int irqcount; /* 32 Irq nesting counter. Starts with -1 */ - int cpunumber; /* 36 Logical CPU number */ -#ifdef CONFIG_CC_STACKPROTECTOR - unsigned long stack_canary; /* 40 stack canary value */ - /* gcc-ABI: this canary MUST be at - offset 40!!! */ + struct task_struct *pcurrent; /* Current process */ + unsigned long data_offset; /* Per cpu data offset from linker address */ + unsigned long kernelstack; /* top of kernel stack for current */ + unsigned long oldrsp; /* user rsp for system call */ +#if DEBUG_STKSZ > EXCEPTION_STKSZ + unsigned long debugstack; /* #DB/#BP stack. */ #endif - char *irqstackptr; + int irqcount; /* Irq nesting counter. Starts with -1 */ + int cpunumber; /* Logical CPU number */ + char *irqstackptr; /* top of irqstack */ int nodenumber; /* number of current node */ unsigned int __softirq_pending; unsigned int __nmi_count; /* number of NMI on this CPUs */ - short mmu_state; - short isidle; + int mmu_state; struct mm_struct *active_mm; unsigned apic_timer_irqs; } ____cacheline_aligned_in_smp; @@ -40,69 +36,44 @@ extern struct x8664_pda boot_cpu_pda[]; * There is no fast way to get the base address of the PDA, all the accesses * have to mention %fs/%gs. So it needs to be done this Torvaldian way. */ -extern void __bad_pda_field(void) __attribute__((noreturn)); +#define sizeof_field(type,field) (sizeof(((type *)0)->field)) +#define typeof_field(type,field) typeof(((type *)0)->field) -/* - * proxy_pda doesn't actually exist, but tell gcc it is accessed for - * all PDA accesses so it gets read/write dependencies right. - */ -extern struct x8664_pda _proxy_pda; +extern void __bad_pda_field(void); #define pda_offset(field) offsetof(struct x8664_pda, field) -#define pda_to_op(op,field,val) do { \ - typedef typeof(_proxy_pda.field) T__; \ - if (0) { T__ tmp__; tmp__ = (val); } /* type checking */ \ - switch (sizeof(_proxy_pda.field)) { \ - case 2: \ - asm(op "w %1,%%gs:%c2" : \ - "+m" (_proxy_pda.field) : \ - "ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - case 4: \ - asm(op "l %1,%%gs:%c2" : \ - "+m" (_proxy_pda.field) : \ - "ri" ((T__)val), \ - "i" (pda_offset(field))); \ - break; \ - case 8: \ - asm(op "q %1,%%gs:%c2": \ - "+m" (_proxy_pda.field) : \ - "ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - default: \ - __bad_pda_field(); \ - } \ +#define pda_to_op(op,field,val) do { \ + typedef typeof_field(struct x8664_pda, field) T__; \ + switch (sizeof_field(struct x8664_pda, field)) { \ +case 2: \ +asm volatile(op "w %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \ +case 4: \ +asm volatile(op "l %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \ +case 8: \ +asm volatile(op "q %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \ + default: __bad_pda_field(); \ + } \ } while (0) -#define pda_from_op(op,field) ({ \ - typeof(_proxy_pda.field) ret__; \ - switch (sizeof(_proxy_pda.field)) { \ - case 2: \ - asm(op "w %%gs:%c1,%0" : \ - "=r" (ret__) : \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 4: \ - asm(op "l %%gs:%c1,%0": \ - "=r" (ret__): \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 8: \ - asm(op "q %%gs:%c1,%0": \ - "=r" (ret__) : \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - default: \ - __bad_pda_field(); \ - } \ +/* + * AK: PDA read accesses should be neither volatile nor have an memory clobber. + * Unfortunately removing them causes all hell to break lose currently. + */ +#define pda_from_op(op,field) ({ \ + typeof_field(struct x8664_pda, field) ret__; \ + switch (sizeof_field(struct x8664_pda, field)) { \ +case 2: \ +asm volatile(op "w %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\ +case 4: \ +asm volatile(op "l %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\ +case 8: \ +asm volatile(op "q %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\ + default: __bad_pda_field(); \ + } \ ret__; }) + #define read_pda(field) pda_from_op("mov",field) #define write_pda(field,val) pda_to_op("mov",field,val) #define add_pda(field,val) pda_to_op("add",field,val) diff --git a/trunk/include/asm-x86_64/percpu.h b/trunk/include/asm-x86_64/percpu.h index 285756010c51..bffb2f886a51 100644 --- a/trunk/include/asm-x86_64/percpu.h +++ b/trunk/include/asm-x86_64/percpu.h @@ -11,16 +11,6 @@ #include -#ifdef CONFIG_MODULES -# define PERCPU_MODULE_RESERVE 8192 -#else -# define PERCPU_MODULE_RESERVE 0 -#endif - -#define PERCPU_ENOUGH_ROOM \ - (ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES) + \ - PERCPU_MODULE_RESERVE) - #define __per_cpu_offset(cpu) (cpu_pda(cpu)->data_offset) #define __my_cpu_offset() read_pda(data_offset) diff --git a/trunk/include/asm-x86_64/pgtable.h b/trunk/include/asm-x86_64/pgtable.h index 6899e770b173..51eba2395171 100644 --- a/trunk/include/asm-x86_64/pgtable.h +++ b/trunk/include/asm-x86_64/pgtable.h @@ -21,9 +21,12 @@ extern unsigned long __supported_pte_mask; #define swapper_pg_dir init_level4_pgt +extern int nonx_setup(char *str); extern void paging_init(void); extern void clear_kernel_mapping(unsigned long addr, unsigned long size); +extern unsigned long pgkern_mask; + /* * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. @@ -262,7 +265,7 @@ static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT) static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; } static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } -static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); } +static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } @@ -275,12 +278,11 @@ static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; } static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; } static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } -static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); return pte; } +static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; } static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; } static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; } static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; } static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_PSE)); return pte; } -static inline pte_t pte_clrhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_PSE)); return pte; } struct vm_area_struct; diff --git a/trunk/include/asm-x86_64/proto.h b/trunk/include/asm-x86_64/proto.h index b73d0c76613c..038fe1f47e6f 100644 --- a/trunk/include/asm-x86_64/proto.h +++ b/trunk/include/asm-x86_64/proto.h @@ -51,8 +51,10 @@ extern unsigned long long monotonic_base; extern int sysctl_vsyscall; extern int nohpet; extern unsigned long vxtime_hz; -extern void time_init_gtod(void); +extern int numa_setup(char *opt); + +extern int setup_early_printk(char *); extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2))); extern void early_identify_cpu(struct cpuinfo_x86 *c); @@ -89,7 +91,7 @@ extern void syscall32_cpu_init(void); extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); -extern void early_quirks(void); +extern void check_ioapic(void); extern void check_efer(void); extern int unhandled_signal(struct task_struct *tsk, int sig); @@ -101,7 +103,13 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c); extern unsigned long table_start, table_end; extern int exception_trace; +extern int using_apic_timer; +extern int disable_apic; extern unsigned cpu_khz; +extern int ioapic_force; +extern int skip_ioapic_setup; +extern int acpi_ht; +extern int acpi_disabled; extern void no_iommu_init(void); extern int force_iommu, no_iommu; @@ -123,8 +131,7 @@ extern int fix_aperture; extern int reboot_force; extern int notsc_setup(char *); - -extern int gsi_irq_sharing(int gsi); +extern int setup_additional_cpus(char *); extern void smp_local_timer_interrupt(struct pt_regs * regs); diff --git a/trunk/include/asm-x86_64/rwlock.h b/trunk/include/asm-x86_64/rwlock.h index 72aeebed920b..dea0e9459264 100644 --- a/trunk/include/asm-x86_64/rwlock.h +++ b/trunk/include/asm-x86_64/rwlock.h @@ -18,9 +18,69 @@ #ifndef _ASM_X86_64_RWLOCK_H #define _ASM_X86_64_RWLOCK_H +#include + #define RW_LOCK_BIAS 0x01000000 -#define RW_LOCK_BIAS_STR "0x01000000" +#define RW_LOCK_BIAS_STR "0x01000000" + +#define __build_read_lock_ptr(rw, helper) \ + asm volatile(LOCK_PREFIX "subl $1,(%0)\n\t" \ + "js 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2:\tcall " helper "\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + ::"a" (rw) : "memory") + +#define __build_read_lock_const(rw, helper) \ + asm volatile(LOCK_PREFIX "subl $1,%0\n\t" \ + "js 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2:\tpushq %%rax\n\t" \ + "leaq %0,%%rax\n\t" \ + "call " helper "\n\t" \ + "popq %%rax\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + :"=m" (*((volatile int *)rw))::"memory") + +#define __build_read_lock(rw, helper) do { \ + if (__builtin_constant_p(rw)) \ + __build_read_lock_const(rw, helper); \ + else \ + __build_read_lock_ptr(rw, helper); \ + } while (0) + +#define __build_write_lock_ptr(rw, helper) \ + asm volatile(LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ + "jnz 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2:\tcall " helper "\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + ::"a" (rw) : "memory") + +#define __build_write_lock_const(rw, helper) \ + asm volatile(LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \ + "jnz 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2:\tpushq %%rax\n\t" \ + "leaq %0,%%rax\n\t" \ + "call " helper "\n\t" \ + "popq %%rax\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + :"=m" (*((volatile long *)rw))::"memory") -/* Actual code is in asm/spinlock.h or in arch/x86_64/lib/rwlock.S */ +#define __build_write_lock(rw, helper) do { \ + if (__builtin_constant_p(rw)) \ + __build_write_lock_const(rw, helper); \ + else \ + __build_write_lock_ptr(rw, helper); \ + } while (0) #endif diff --git a/trunk/include/asm-x86_64/segment.h b/trunk/include/asm-x86_64/segment.h index 334ddcdd8f92..d4bed33fb32c 100644 --- a/trunk/include/asm-x86_64/segment.h +++ b/trunk/include/asm-x86_64/segment.h @@ -20,16 +20,15 @@ #define __USER_CS 0x33 /* 6*8+3 */ #define __USER32_DS __USER_DS +#define GDT_ENTRY_TLS 1 #define GDT_ENTRY_TSS 8 /* needs two entries */ #define GDT_ENTRY_LDT 10 /* needs two entries */ #define GDT_ENTRY_TLS_MIN 12 #define GDT_ENTRY_TLS_MAX 14 +/* 15 free */ #define GDT_ENTRY_TLS_ENTRIES 3 -#define GDT_ENTRY_PER_CPU 15 /* Abused to load per CPU data from limit */ -#define __PER_CPU_SEG (GDT_ENTRY_PER_CPU * 8 + 3) - /* TLS indexes for 64bit - hardcoded in arch_prctl */ #define FS_TLS 0 #define GS_TLS 1 diff --git a/trunk/include/asm-x86_64/semaphore.h b/trunk/include/asm-x86_64/semaphore.h index 107bd90429e8..064df08b9a0f 100644 --- a/trunk/include/asm-x86_64/semaphore.h +++ b/trunk/include/asm-x86_64/semaphore.h @@ -107,9 +107,12 @@ static inline void down(struct semaphore * sem) __asm__ __volatile__( "# atomic down operation\n\t" LOCK_PREFIX "decl %0\n\t" /* --sem->count */ - "jns 1f\n\t" - "call __down_failed\n" - "1:" + "js 2f\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tcall __down_failed\n\t" + "jmp 1b\n" + LOCK_SECTION_END :"=m" (sem->count) :"D" (sem) :"memory"); @@ -127,11 +130,14 @@ static inline int down_interruptible(struct semaphore * sem) __asm__ __volatile__( "# atomic interruptible down operation\n\t" - "xorl %0,%0\n\t" LOCK_PREFIX "decl %1\n\t" /* --sem->count */ - "jns 2f\n\t" - "call __down_failed_interruptible\n" - "2:\n" + "js 2f\n\t" + "xorl %0,%0\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tcall __down_failed_interruptible\n\t" + "jmp 1b\n" + LOCK_SECTION_END :"=a" (result), "=m" (sem->count) :"D" (sem) :"memory"); @@ -148,11 +154,14 @@ static inline int down_trylock(struct semaphore * sem) __asm__ __volatile__( "# atomic interruptible down operation\n\t" - "xorl %0,%0\n\t" LOCK_PREFIX "decl %1\n\t" /* --sem->count */ - "jns 2f\n\t" - "call __down_failed_trylock\n\t" - "2:\n" + "js 2f\n\t" + "xorl %0,%0\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tcall __down_failed_trylock\n\t" + "jmp 1b\n" + LOCK_SECTION_END :"=a" (result), "=m" (sem->count) :"D" (sem) :"memory","cc"); @@ -170,9 +179,12 @@ static inline void up(struct semaphore * sem) __asm__ __volatile__( "# atomic up operation\n\t" LOCK_PREFIX "incl %0\n\t" /* ++sem->count */ - "jg 1f\n\t" - "call __up_wakeup\n" - "1:" + "jle 2f\n" + "1:\n" + LOCK_SECTION_START("") + "2:\tcall __up_wakeup\n\t" + "jmp 1b\n" + LOCK_SECTION_END :"=m" (sem->count) :"D" (sem) :"memory"); diff --git a/trunk/include/asm-x86_64/signal.h b/trunk/include/asm-x86_64/signal.h index 4581f978b299..3ede2a61973a 100644 --- a/trunk/include/asm-x86_64/signal.h +++ b/trunk/include/asm-x86_64/signal.h @@ -24,6 +24,10 @@ typedef struct { } sigset_t; +struct pt_regs; +asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); + + #else /* Here we must cater to libcs that poke about in kernel headers. */ diff --git a/trunk/include/asm-x86_64/smp.h b/trunk/include/asm-x86_64/smp.h index d6b7c057edba..ce97f65e1d10 100644 --- a/trunk/include/asm-x86_64/smp.h +++ b/trunk/include/asm-x86_64/smp.h @@ -4,18 +4,27 @@ /* * We need the APIC definitions automatically as part of 'smp.h' */ +#ifndef __ASSEMBLY__ #include #include #include extern int disable_apic; +#endif +#ifdef CONFIG_X86_LOCAL_APIC +#ifndef __ASSEMBLY__ #include #include +#ifdef CONFIG_X86_IO_APIC #include +#endif #include #include +#endif +#endif #ifdef CONFIG_SMP +#ifndef ASSEMBLY #include @@ -33,6 +42,7 @@ extern cpumask_t cpu_initialized; extern void smp_alloc_memory(void); extern volatile unsigned long smp_invalidate_needed; +extern int pic_mode; extern void lock_ipi_call_lock(void); extern void unlock_ipi_call_lock(void); extern int smp_num_siblings; @@ -64,16 +74,20 @@ static inline int hard_smp_processor_id(void) return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID)); } +extern int safe_smp_processor_id(void); extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); extern void prefill_possible_map(void); extern unsigned num_processors; extern unsigned disabled_cpus; +#endif /* !ASSEMBLY */ + #define NO_PROC_ID 0xFF /* No processor magic marker */ #endif +#ifndef ASSEMBLY /* * Some lowlevel functions might want to know about * the real APIC ID <-> CPU # mapping. @@ -95,8 +109,11 @@ static inline int cpu_present_to_apicid(int mps_cpu) return BAD_APICID; } +#endif /* !ASSEMBLY */ + #ifndef CONFIG_SMP #define stack_smp_processor_id() 0 +#define safe_smp_processor_id() 0 #define cpu_logical_map(x) (x) #else #include @@ -108,23 +125,19 @@ static inline int cpu_present_to_apicid(int mps_cpu) }) #endif +#ifndef __ASSEMBLY__ static __inline int logical_smp_processor_id(void) { /* we don't want to mark this access volatile - bad code generation */ return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); } +#endif #ifdef CONFIG_SMP #define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu] #else #define cpu_physical_id(cpu) boot_cpu_id -static inline int smp_call_function_single(int cpuid, void (*func) (void *info), - void *info, int retry, int wait) -{ - /* Disable interrupts here? */ - func(info); - return 0; -} -#endif /* !CONFIG_SMP */ +#endif + #endif diff --git a/trunk/include/asm-x86_64/spinlock.h b/trunk/include/asm-x86_64/spinlock.h index be7a9e629fb2..248a79f0eaff 100644 --- a/trunk/include/asm-x86_64/spinlock.h +++ b/trunk/include/asm-x86_64/spinlock.h @@ -16,23 +16,31 @@ * (the type definitions are in asm/spinlock_types.h) */ -static inline int __raw_spin_is_locked(raw_spinlock_t *lock) -{ - return *(volatile signed int *)(&(lock)->slock) <= 0; -} +#define __raw_spin_is_locked(x) \ + (*(volatile signed int *)(&(x)->slock) <= 0) + +#define __raw_spin_lock_string \ + "\n1:\t" \ + LOCK_PREFIX " ; decl %0\n\t" \ + "js 2f\n" \ + LOCK_SECTION_START("") \ + "2:\t" \ + "rep;nop\n\t" \ + "cmpl $0,%0\n\t" \ + "jle 2b\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END + +#define __raw_spin_lock_string_up \ + "\n\tdecl %0" + +#define __raw_spin_unlock_string \ + "movl $1,%0" \ + :"=m" (lock->slock) : : "memory" static inline void __raw_spin_lock(raw_spinlock_t *lock) { - asm volatile( - "\n1:\t" - LOCK_PREFIX " ; decl %0\n\t" - "jns 2f\n" - "3:\n" - "rep;nop\n\t" - "cmpl $0,%0\n\t" - "jle 3b\n\t" - "jmp 1b\n" - "2:\t" : "=m" (lock->slock) : : "memory"); + asm volatile(__raw_spin_lock_string : "=m" (lock->slock) : : "memory"); } #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) @@ -41,7 +49,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) { int oldval; - asm volatile( + __asm__ __volatile__( "xchgl %0,%1" :"=q" (oldval), "=m" (lock->slock) :"0" (0) : "memory"); @@ -51,14 +59,13 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) static inline void __raw_spin_unlock(raw_spinlock_t *lock) { - asm volatile("movl $1,%0" :"=m" (lock->slock) :: "memory"); + __asm__ __volatile__( + __raw_spin_unlock_string + ); } -static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) -{ - while (__raw_spin_is_locked(lock)) - cpu_relax(); -} +#define __raw_spin_unlock_wait(lock) \ + do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) /* * Read-write spinlocks, allowing multiple readers @@ -72,34 +79,26 @@ static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) * * On x86, we implement read-write locks as a 32-bit counter * with the high bit (sign) being the "contended" bit. + * + * The inline assembly is non-obvious. Think about it. + * + * Changed to use the same technique as rw semaphores. See + * semaphore.h for details. -ben + * + * the helpers are in arch/i386/kernel/semaphore.c */ -static inline int __raw_read_can_lock(raw_rwlock_t *lock) -{ - return (int)(lock)->lock > 0; -} - -static inline int __raw_write_can_lock(raw_rwlock_t *lock) -{ - return (lock)->lock == RW_LOCK_BIAS; -} +#define __raw_read_can_lock(x) ((int)(x)->lock > 0) +#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) static inline void __raw_read_lock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX "subl $1,(%0)\n\t" - "jns 1f\n" - "call __read_lock_failed\n" - "1:\n" - ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); + __build_read_lock(rw, "__read_lock_failed"); } static inline void __raw_write_lock(raw_rwlock_t *rw) { - asm volatile(LOCK_PREFIX "subl %1,(%0)\n\t" - "jz 1f\n" - "\tcall __write_lock_failed\n\t" - "1:\n" - ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); + __build_write_lock(rw, "__write_lock_failed"); } static inline int __raw_read_trylock(raw_rwlock_t *lock) diff --git a/trunk/include/asm-x86_64/stacktrace.h b/trunk/include/asm-x86_64/stacktrace.h deleted file mode 100644 index 5eb9799bef76..000000000000 --- a/trunk/include/asm-x86_64/stacktrace.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _ASM_STACKTRACE_H -#define _ASM_STACKTRACE_H 1 - -/* Generic stack tracer with callbacks */ - -struct stacktrace_ops { - void (*warning)(void *data, char *msg); - /* msg must contain %s for the symbol */ - void (*warning_symbol)(void *data, char *msg, unsigned long symbol); - void (*address)(void *data, unsigned long address); - /* On negative return stop dumping */ - int (*stack)(void *data, char *name); -}; - -void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack, - struct stacktrace_ops *ops, void *data); - -#endif diff --git a/trunk/include/asm-x86_64/system.h b/trunk/include/asm-x86_64/system.h index bd376bc8c4ab..6bf170bceae1 100644 --- a/trunk/include/asm-x86_64/system.h +++ b/trunk/include/asm-x86_64/system.h @@ -14,13 +14,12 @@ #define __RESTORE(reg,offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t" /* frame pointer must be last for get_wchan */ -#define SAVE_CONTEXT "pushf ; pushq %%rbp ; movq %%rsi,%%rbp\n\t" -#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp ; popf\t" +#define SAVE_CONTEXT "pushq %%rbp ; movq %%rsi,%%rbp\n\t" +#define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp\n\t" #define __EXTRA_CLOBBER \ ,"rcx","rbx","rdx","r8","r9","r10","r11","r12","r13","r14","r15" -/* Save restore flags to clear handle leaking NT */ #define switch_to(prev,next,last) \ asm volatile(SAVE_CONTEXT \ "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \ diff --git a/trunk/include/asm-x86_64/tce.h b/trunk/include/asm-x86_64/tce.h index dbb047febc5e..53e9a68b3336 100644 --- a/trunk/include/asm-x86_64/tce.h +++ b/trunk/include/asm-x86_64/tce.h @@ -24,6 +24,7 @@ #ifndef _ASM_X86_64_TCE_H #define _ASM_X86_64_TCE_H +extern void* tce_table_kva[]; extern unsigned int specified_table_size; struct iommu_table; diff --git a/trunk/include/asm-x86_64/therm_throt.h b/trunk/include/asm-x86_64/therm_throt.h deleted file mode 100644 index 5aac059007ba..000000000000 --- a/trunk/include/asm-x86_64/therm_throt.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-x86_64/thread_info.h b/trunk/include/asm-x86_64/thread_info.h index 787a08114b48..2029b00351f3 100644 --- a/trunk/include/asm-x86_64/thread_info.h +++ b/trunk/include/asm-x86_64/thread_info.h @@ -114,14 +114,11 @@ static inline struct thread_info *stack_thread_info(void) #define TIF_IRET 5 /* force IRET */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SECCOMP 8 /* secure computing */ -#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */ /* 16 free */ #define TIF_IA32 17 /* 32bit process */ #define TIF_FORK 18 /* ret_from_fork */ #define TIF_ABI_PENDING 19 #define TIF_MEMDIE 20 -#define TIF_DEBUG 21 /* uses debug registers */ -#define TIF_IO_BITMAP 22 /* uses I/O bitmap */ #define _TIF_SYSCALL_TRACE (1< #include -static inline unsigned long get_cr3(void) -{ - unsigned long cr3; - asm volatile("mov %%cr3,%0" : "=r" (cr3)); - return cr3; -} - -static inline void set_cr3(unsigned long cr3) -{ - asm volatile("mov %0,%%cr3" :: "r" (cr3) : "memory"); -} - -static inline void __flush_tlb(void) -{ - set_cr3(get_cr3()); -} - -static inline unsigned long get_cr4(void) -{ - unsigned long cr4; - asm volatile("mov %%cr4,%0" : "=r" (cr4)); - return cr4; -} - -static inline void set_cr4(unsigned long cr4) -{ - asm volatile("mov %0,%%cr4" :: "r" (cr4) : "memory"); -} +#define __flush_tlb() \ + do { \ + unsigned long tmpreg; \ + \ + __asm__ __volatile__( \ + "movq %%cr3, %0; # flush TLB \n" \ + "movq %0, %%cr3; \n" \ + : "=r" (tmpreg) \ + :: "memory"); \ + } while (0) -static inline void __flush_tlb_all(void) -{ - unsigned long cr4 = get_cr4(); - set_cr4(cr4 & ~X86_CR4_PGE); /* clear PGE */ - set_cr4(cr4); /* write old PGE again and flush TLBs */ -} +/* + * Global pages have to be flushed a bit differently. Not a real + * performance problem because this does not happen often. + */ +#define __flush_tlb_global() \ + do { \ + unsigned long tmpreg, cr4, cr4_orig; \ + \ + __asm__ __volatile__( \ + "movq %%cr4, %2; # turn off PGE \n" \ + "movq %2, %1; \n" \ + "andq %3, %1; \n" \ + "movq %1, %%cr4; \n" \ + "movq %%cr3, %0; # flush TLB \n" \ + "movq %0, %%cr3; \n" \ + "movq %2, %%cr4; # turn PGE back on \n" \ + : "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig) \ + : "i" (~X86_CR4_PGE) \ + : "memory"); \ + } while (0) + +extern unsigned long pgkern_mask; + +#define __flush_tlb_all() __flush_tlb_global() #define __flush_tlb_one(addr) \ - __asm__ __volatile__("invlpg (%0)" :: "r" (addr) : "memory") + __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr)) /* diff --git a/trunk/include/asm-x86_64/uaccess.h b/trunk/include/asm-x86_64/uaccess.h index e856570c0689..1e1fa003daa3 100644 --- a/trunk/include/asm-x86_64/uaccess.h +++ b/trunk/include/asm-x86_64/uaccess.h @@ -84,7 +84,7 @@ struct exception_table_entry */ #define __get_user_x(size,ret,x,ptr) \ - asm volatile("call __get_user_" #size \ + __asm__ __volatile__("call __get_user_" #size \ :"=a" (ret),"=d" (x) \ :"c" (ptr) \ :"r8") @@ -101,7 +101,7 @@ struct exception_table_entry case 8: __get_user_x(8,__ret_gu,__val_gu,ptr); break; \ default: __get_user_bad(); break; \ } \ - (x) = (typeof(*(ptr)))__val_gu; \ + (x) = (__typeof__(*(ptr)))__val_gu; \ __ret_gu; \ }) @@ -112,7 +112,7 @@ extern void __put_user_8(void); extern void __put_user_bad(void); #define __put_user_x(size,ret,x,ptr) \ - asm volatile("call __put_user_" #size \ + __asm__ __volatile__("call __put_user_" #size \ :"=a" (ret) \ :"c" (ptr),"d" (x) \ :"r8") @@ -139,7 +139,7 @@ extern void __put_user_bad(void); #define __put_user_check(x,ptr,size) \ ({ \ int __pu_err; \ - typeof(*(ptr)) __user *__pu_addr = (ptr); \ + __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ switch (size) { \ case 1: __put_user_x(1,__pu_err,x,__pu_addr); break; \ case 2: __put_user_x(2,__pu_err,x,__pu_addr); break; \ @@ -173,7 +173,7 @@ struct __large_struct { unsigned long buf[100]; }; * aliasing issues. */ #define __put_user_asm(x, addr, err, itype, rtype, ltype, errno) \ - asm volatile( \ + __asm__ __volatile__( \ "1: mov"itype" %"rtype"1,%2\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ @@ -193,7 +193,7 @@ struct __large_struct { unsigned long buf[100]; }; int __gu_err; \ unsigned long __gu_val; \ __get_user_size(__gu_val,(ptr),(size),__gu_err); \ - (x) = (typeof(*(ptr)))__gu_val; \ + (x) = (__typeof__(*(ptr)))__gu_val; \ __gu_err; \ }) @@ -217,7 +217,7 @@ do { \ } while (0) #define __get_user_asm(x, addr, err, itype, rtype, ltype, errno) \ - asm volatile( \ + __asm__ __volatile__( \ "1: mov"itype" %2,%"rtype"1\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ @@ -237,20 +237,15 @@ do { \ */ /* Handles exceptions in both to and from, but doesn't do access_ok */ -__must_check unsigned long -copy_user_generic(void *to, const void *from, unsigned len); - -__must_check unsigned long -copy_to_user(void __user *to, const void *from, unsigned len); -__must_check unsigned long -copy_from_user(void *to, const void __user *from, unsigned len); -__must_check unsigned long -copy_in_user(void __user *to, const void __user *from, unsigned len); - -static __always_inline __must_check -int __copy_from_user(void *dst, const void __user *src, unsigned size) +extern unsigned long copy_user_generic(void *to, const void *from, unsigned len); + +extern unsigned long copy_to_user(void __user *to, const void *from, unsigned len); +extern unsigned long copy_from_user(void *to, const void __user *from, unsigned len); +extern unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len); + +static __always_inline int __copy_from_user(void *dst, const void __user *src, unsigned size) { - int ret = 0; + int ret = 0; if (!__builtin_constant_p(size)) return copy_user_generic(dst,(__force void *)src,size); switch (size) { @@ -277,10 +272,9 @@ int __copy_from_user(void *dst, const void __user *src, unsigned size) } } -static __always_inline __must_check -int __copy_to_user(void __user *dst, const void *src, unsigned size) +static __always_inline int __copy_to_user(void __user *dst, const void *src, unsigned size) { - int ret = 0; + int ret = 0; if (!__builtin_constant_p(size)) return copy_user_generic((__force void *)dst,src,size); switch (size) { @@ -309,10 +303,10 @@ int __copy_to_user(void __user *dst, const void *src, unsigned size) } } -static __always_inline __must_check -int __copy_in_user(void __user *dst, const void __user *src, unsigned size) + +static __always_inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size) { - int ret = 0; + int ret = 0; if (!__builtin_constant_p(size)) return copy_user_generic((__force void *)dst,(__force void *)src,size); switch (size) { @@ -350,17 +344,15 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size) } } -__must_check long -strncpy_from_user(char *dst, const char __user *src, long count); -__must_check long -__strncpy_from_user(char *dst, const char __user *src, long count); -__must_check long strnlen_user(const char __user *str, long n); -__must_check long __strnlen_user(const char __user *str, long n); -__must_check long strlen_user(const char __user *str); -__must_check unsigned long clear_user(void __user *mem, unsigned long len); -__must_check unsigned long __clear_user(void __user *mem, unsigned long len); - -__must_check long __copy_from_user_inatomic(void *dst, const void __user *src, unsigned size); -#define __copy_to_user_inatomic copy_user_generic +long strncpy_from_user(char *dst, const char __user *src, long count); +long __strncpy_from_user(char *dst, const char __user *src, long count); +long strnlen_user(const char __user *str, long n); +long __strnlen_user(const char __user *str, long n); +long strlen_user(const char __user *str); +unsigned long clear_user(void __user *mem, unsigned long len); +unsigned long __clear_user(void __user *mem, unsigned long len); + +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user #endif /* __X86_64_UACCESS_H */ diff --git a/trunk/include/asm-x86_64/unistd.h b/trunk/include/asm-x86_64/unistd.h index eeb98c168e98..80fd48e84bbb 100644 --- a/trunk/include/asm-x86_64/unistd.h +++ b/trunk/include/asm-x86_64/unistd.h @@ -600,9 +600,9 @@ __SYSCALL(__NR_fchmodat, sys_fchmodat) #define __NR_faccessat 269 __SYSCALL(__NR_faccessat, sys_faccessat) #define __NR_pselect6 270 -__SYSCALL(__NR_pselect6, sys_pselect6) +__SYSCALL(__NR_pselect6, sys_ni_syscall) /* for now */ #define __NR_ppoll 271 -__SYSCALL(__NR_ppoll, sys_ppoll) +__SYSCALL(__NR_ppoll, sys_ni_syscall) /* for now */ #define __NR_unshare 272 __SYSCALL(__NR_unshare, sys_unshare) #define __NR_set_robust_list 273 @@ -658,7 +658,6 @@ do { \ #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_RT_SIGACTION -#define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_TIME #define __ARCH_WANT_COMPAT_SYS_TIME diff --git a/trunk/include/asm-x86_64/unwind.h b/trunk/include/asm-x86_64/unwind.h index 2e7ff10fd775..1f6e9bfb569e 100644 --- a/trunk/include/asm-x86_64/unwind.h +++ b/trunk/include/asm-x86_64/unwind.h @@ -18,7 +18,6 @@ struct unwind_frame_info { struct pt_regs regs; struct task_struct *task; - unsigned call_frame:1; }; #define UNW_PC(frame) (frame)->regs.rip @@ -58,10 +57,6 @@ struct unwind_frame_info PTREGS_INFO(r15), \ PTREGS_INFO(rip) -#define UNW_DEFAULT_RA(raItem, dataAlign) \ - ((raItem).where == Memory && \ - !((raItem).value * (dataAlign) + 8)) - static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, /*const*/ struct pt_regs *regs) { @@ -99,8 +94,8 @@ static inline int arch_unw_user_mode(const struct unwind_frame_info *info) #else -#define UNW_PC(frame) ((void)(frame), 0UL) -#define UNW_SP(frame) ((void)(frame), 0UL) +#define UNW_PC(frame) ((void)(frame), 0) +#define UNW_SP(frame) ((void)(frame), 0) static inline int arch_unw_user_mode(const void *info) { diff --git a/trunk/include/asm-x86_64/vsyscall.h b/trunk/include/asm-x86_64/vsyscall.h index 2281e9399b96..146b24402a5f 100644 --- a/trunk/include/asm-x86_64/vsyscall.h +++ b/trunk/include/asm-x86_64/vsyscall.h @@ -4,7 +4,6 @@ enum vsyscall_num { __NR_vgettimeofday, __NR_vtime, - __NR_vgetcpu, }; #define VSYSCALL_START (-10UL << 20) @@ -16,7 +15,6 @@ enum vsyscall_num { #include #define __section_vxtime __attribute__ ((unused, __section__ (".vxtime"), aligned(16))) -#define __section_vgetcpu_mode __attribute__ ((unused, __section__ (".vgetcpu_mode"), aligned(16))) #define __section_wall_jiffies __attribute__ ((unused, __section__ (".wall_jiffies"), aligned(16))) #define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16))) #define __section_sys_tz __attribute__ ((unused, __section__ (".sys_tz"), aligned(16))) @@ -28,9 +26,6 @@ enum vsyscall_num { #define VXTIME_HPET 2 #define VXTIME_PMTMR 3 -#define VGETCPU_RDTSCP 1 -#define VGETCPU_LSL 2 - struct vxtime_data { long hpet_address; /* HPET base address */ int last; @@ -45,7 +40,6 @@ struct vxtime_data { /* vsyscall space (readonly) */ extern struct vxtime_data __vxtime; -extern int __vgetcpu_mode; extern struct timespec __xtime; extern volatile unsigned long __jiffies; extern unsigned long __wall_jiffies; @@ -54,7 +48,6 @@ extern seqlock_t __xtime_lock; /* kernel space (writeable) */ extern struct vxtime_data vxtime; -extern int vgetcpu_mode; extern unsigned long wall_jiffies; extern struct timezone sys_tz; extern int sysctl_vsyscall; @@ -62,8 +55,6 @@ extern seqlock_t xtime_lock; extern int sysctl_vsyscall; -extern void vsyscall_set_cpu(int cpu); - #define ARCH_HAVE_XTIME_LOCK 1 #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/aer.h b/trunk/include/linux/aer.h deleted file mode 100644 index 402e178b38eb..000000000000 --- a/trunk/include/linux/aer.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2006 Intel Corp. - * Tom Long Nguyen (tom.l.nguyen@intel.com) - * Zhang Yanmin (yanmin.zhang@intel.com) - */ - -#ifndef _AER_H_ -#define _AER_H_ - -#if defined(CONFIG_PCIEAER) -/* pci-e port driver needs this function to enable aer */ -extern int pci_enable_pcie_error_reporting(struct pci_dev *dev); -extern int pci_find_aer_capability(struct pci_dev *dev); -extern int pci_disable_pcie_error_reporting(struct pci_dev *dev); -extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); -#else -#define pci_enable_pcie_error_reporting(dev) do { } while (0) -#define pci_find_aer_capability(dev) do { } while (0) -#define pci_disable_pcie_error_reporting(dev) do { } while (0) -#define pci_cleanup_aer_uncorrect_error_status(dev) do { } while (0) -#endif - -#endif //_AER_H_ - diff --git a/trunk/include/linux/edd.h b/trunk/include/linux/edd.h index b2b3e68aa512..162512b886f7 100644 --- a/trunk/include/linux/edd.h +++ b/trunk/include/linux/edd.h @@ -52,7 +52,6 @@ #define EDD_CL_EQUALS 0x3d646465 /* "edd=" */ #define EDD_CL_OFF 0x666f /* "of" for off */ #define EDD_CL_SKIP 0x6b73 /* "sk" for skipmbr */ -#define EDD_CL_ON 0x6e6f /* "on" for on */ #ifndef __ASSEMBLY__ diff --git a/trunk/include/linux/getcpu.h b/trunk/include/linux/getcpu.h deleted file mode 100644 index 031ed3780e45..000000000000 --- a/trunk/include/linux/getcpu.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _LINUX_GETCPU_H -#define _LINUX_GETCPU_H 1 - -/* Cache for getcpu() to speed it up. Results might be upto a jiffie - out of date, but will be faster. - User programs should not refer to the contents of this structure. - It is only a cache for vgetcpu(). It might change in future kernels. - The user program must store this information per thread (__thread) - If you want 100% accurate information pass NULL instead. */ -struct getcpu_cache { - unsigned long t0; - unsigned long t1; - unsigned long res[4]; -}; - -#endif diff --git a/trunk/include/linux/jiffies.h b/trunk/include/linux/jiffies.h index c8d5f207c3d4..329ebcffa106 100644 --- a/trunk/include/linux/jiffies.h +++ b/trunk/include/linux/jiffies.h @@ -115,21 +115,6 @@ static inline u64 get_jiffies_64(void) ((long)(a) - (long)(b) >= 0)) #define time_before_eq(a,b) time_after_eq(b,a) -/* Same as above, but does so with platform independent 64bit types. - * These must be used when utilizing jiffies_64 (i.e. return value of - * get_jiffies_64() */ -#define time_after64(a,b) \ - (typecheck(__u64, a) && \ - typecheck(__u64, b) && \ - ((__s64)(b) - (__s64)(a) < 0)) -#define time_before64(a,b) time_after64(b,a) - -#define time_after_eq64(a,b) \ - (typecheck(__u64, a) && \ - typecheck(__u64, b) && \ - ((__s64)(a) - (__s64)(b) >= 0)) -#define time_before_eq64(a,b) time_after_eq64(b,a) - /* * Have the 32 bit jiffies value wrap 5 minutes after boot * so jiffies wrap bugs show up earlier. diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index 4fa373bb18ac..e44a37e2c71c 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -187,7 +187,6 @@ extern void bust_spinlocks(int yes); extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */ extern int panic_timeout; extern int panic_on_oops; -extern int panic_on_unrecovered_nmi; extern int tainted; extern const char *print_tainted(void); extern void add_taint(unsigned); diff --git a/trunk/include/linux/linkage.h b/trunk/include/linux/linkage.h index 6c9873f88287..932021f872d5 100644 --- a/trunk/include/linux/linkage.h +++ b/trunk/include/linux/linkage.h @@ -35,13 +35,9 @@ #endif #define KPROBE_ENTRY(name) \ - .pushsection .kprobes.text, "ax"; \ + .section .kprobes.text, "ax"; \ ENTRY(name) -#define KPROBE_END(name) \ - END(name); \ - .popsection - #ifndef END #define END(name) \ .size name, .-name diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 5c3a4176eb64..3ec72551ac31 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -356,8 +356,6 @@ struct pci_driver { struct pci_error_handlers *err_handler; struct device_driver driver; struct pci_dynids dynids; - - int multithread_probe; }; #define to_pci_driver(drv) container_of(drv,struct pci_driver, driver) @@ -433,7 +431,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn); struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); void pci_device_add(struct pci_dev *dev, struct pci_bus *bus); unsigned int pci_scan_child_bus(struct pci_bus *bus); -int __must_check pci_bus_add_device(struct pci_dev *dev); +void pci_bus_add_device(struct pci_dev *dev); void pci_read_bridge_bases(struct pci_bus *child); struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res); int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); @@ -441,7 +439,6 @@ extern struct pci_dev *pci_dev_get(struct pci_dev *dev); extern void pci_dev_put(struct pci_dev *dev); extern void pci_remove_bus(struct pci_bus *b); extern void pci_remove_bus_device(struct pci_dev *dev); -extern void pci_stop_bus_device(struct pci_dev *dev); void pci_setup_cardbus(struct pci_bus *bus); /* Generic PCI functions exported to card drivers */ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index ab032ceafa84..6a1e09834559 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -1411,7 +1411,6 @@ #define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017 #define PCI_DEVICE_ID_SERVERWORKS_EPB 0x0103 -#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 #define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 #define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203 @@ -1483,6 +1482,9 @@ #define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 #define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 #define PCI_DEVICE_ID_MARVELL_MV64460 0x6480 +#define PCI_DEVICE_ID_MARVELL_GT96100 0x9652 +#define PCI_DEVICE_ID_MARVELL_GT96100A 0x9653 + #define PCI_VENDOR_ID_V3 0x11b0 #define PCI_DEVICE_ID_V3_V960 0x0001 diff --git a/trunk/include/linux/pci_regs.h b/trunk/include/linux/pci_regs.h index 7d0e26cba420..96930cb5927c 100644 --- a/trunk/include/linux/pci_regs.h +++ b/trunk/include/linux/pci_regs.h @@ -196,7 +196,7 @@ #define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ #define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ #define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ -#define PCI_CAP_ID_HT 0x08 /* HyperTransport */ +#define PCI_CAP_ID_HT_IRQCONF 0x08 /* HyperTransport IRQ Configuration */ #define PCI_CAP_ID_VNDR 0x09 /* Vendor specific capability */ #define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ #define PCI_CAP_ID_EXP 0x10 /* PCI Express */ diff --git a/trunk/include/linux/pcieport_if.h b/trunk/include/linux/pcieport_if.h index 6cd91e3f9820..b44e01a70914 100644 --- a/trunk/include/linux/pcieport_if.h +++ b/trunk/include/linux/pcieport_if.h @@ -62,12 +62,6 @@ struct pcie_port_service_driver { int (*suspend) (struct pcie_device *dev, pm_message_t state); int (*resume) (struct pcie_device *dev); - /* Service Error Recovery Handler */ - struct pci_error_handlers *err_handler; - - /* Link Reset Capability - AER service driver specific */ - pci_ers_result_t (*reset_link) (struct pci_dev *dev); - const struct pcie_port_service_id *id_table; struct device_driver driver; }; diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 9d4aa7f95bc8..34ed0d99b1bd 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -819,11 +819,6 @@ struct task_struct { unsigned did_exec:1; pid_t pid; pid_t tgid; - -#ifdef CONFIG_CC_STACKPROTECTOR - /* Canary value for the -fstack-protector gcc feature */ - unsigned long stack_canary; -#endif /* * pointers to (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with @@ -870,15 +865,6 @@ struct task_struct { struct key *thread_keyring; /* keyring private to this thread */ unsigned char jit_keyring; /* default keyring to attach requested keys to */ #endif - /* - * fpu_counter contains the number of consecutive context switches - * that the FPU is used. If this is over a threshold, the lazy fpu - * saving becomes unlazy to save the trap. This is an unsigned char - * so that after 256 times the counter wraps and the behavior turns - * lazy again; this to deal with bursty apps that only use FPU for - * a short time - */ - unsigned char fpu_counter; int oomkilladj; /* OOM kill score adjustment (bit shift). */ char comm[TASK_COMM_LEN]; /* executable name excluding path - access with [gs]et_task_comm (which lock diff --git a/trunk/include/linux/stacktrace.h b/trunk/include/linux/stacktrace.h index 50e2b01e517c..9cc81e572224 100644 --- a/trunk/include/linux/stacktrace.h +++ b/trunk/include/linux/stacktrace.h @@ -5,16 +5,15 @@ struct stack_trace { unsigned int nr_entries, max_entries; unsigned long *entries; - int skip; /* input argument: How many entries to skip */ - int all_contexts; /* input argument: if true do than one stack */ }; extern void save_stack_trace(struct stack_trace *trace, - struct task_struct *task); + struct task_struct *task, int all_contexts, + unsigned int skip); extern void print_stack_trace(struct stack_trace *trace, int spaces); #else -# define save_stack_trace(trace, task) do { } while (0) +# define save_stack_trace(trace, task, all, skip) do { } while (0) # define print_stack_trace(trace) do { } while (0) #endif diff --git a/trunk/include/linux/syscalls.h b/trunk/include/linux/syscalls.h index 3f0f716225ec..008f04c56737 100644 --- a/trunk/include/linux/syscalls.h +++ b/trunk/include/linux/syscalls.h @@ -53,7 +53,6 @@ struct mq_attr; struct compat_stat; struct compat_timeval; struct robust_list_head; -struct getcpu_cache; #include #include @@ -597,6 +596,5 @@ asmlinkage long sys_get_robust_list(int pid, size_t __user *len_ptr); asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, size_t len); -asmlinkage long sys_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *cache); #endif diff --git a/trunk/include/linux/sysctl.h b/trunk/include/linux/sysctl.h index 1b24bd45e080..eca555781d05 100644 --- a/trunk/include/linux/sysctl.h +++ b/trunk/include/linux/sysctl.h @@ -150,8 +150,6 @@ enum KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */ KERN_COMPAT_LOG=73, /* int: print compat layer messages */ KERN_MAX_LOCK_DEPTH=74, - KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */ - KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */ }; diff --git a/trunk/include/linux/vermagic.h b/trunk/include/linux/vermagic.h index 4d0909e53595..46919f9f5eb3 100644 --- a/trunk/include/linux/vermagic.h +++ b/trunk/include/linux/vermagic.h @@ -24,5 +24,5 @@ #define VERMAGIC_STRING \ UTS_RELEASE " " \ MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ - MODULE_VERMAGIC_MODULE_UNLOAD MODULE_ARCH_VERMAGIC - + MODULE_VERMAGIC_MODULE_UNLOAD MODULE_ARCH_VERMAGIC \ + "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__) diff --git a/trunk/init/main.c b/trunk/init/main.c index 913e48d658ee..8651a720a092 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -162,19 +162,16 @@ extern struct obs_kernel_param __setup_start[], __setup_end[]; static int __init obsolete_checksetup(char *line) { struct obs_kernel_param *p; - int had_early_param = 0; p = __setup_start; do { int n = strlen(p->str); if (!strncmp(line, p->str, n)) { if (p->early) { - /* Already done in parse_early_param? - * (Needs exact match on param part). - * Keep iterating, as we can have early - * params and __setups of same names 8( */ + /* Already done in parse_early_param? (Needs + * exact match on param part) */ if (line[n] == '\0' || line[n] == '=') - had_early_param = 1; + return 1; } else if (!p->setup_func) { printk(KERN_WARNING "Parameter %s is obsolete," " ignored\n", p->str); @@ -184,8 +181,7 @@ static int __init obsolete_checksetup(char *line) } p++; } while (p < __setup_end); - - return had_early_param; + return 0; } /* @@ -468,7 +464,6 @@ asmlinkage void __init start_kernel(void) * Need to run as early as possible, to initialize the * lockdep hash: */ - unwind_init(); lockdep_init(); local_irq_disable(); @@ -507,6 +502,7 @@ asmlinkage void __init start_kernel(void) __stop___param - __start___param, &unknown_bootoption); sort_main_extable(); + unwind_init(); trap_init(); rcu_init(); init_IRQ(); diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index a0dad84567c9..f9b014e3e700 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include @@ -176,10 +175,6 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) tsk->thread_info = ti; setup_thread_stack(tsk, orig); -#ifdef CONFIG_CC_STACKPROTECTOR - tsk->stack_canary = get_random_int(); -#endif - /* One for us, one for whoever does the "release_task()" (usually parent) */ atomic_set(&tsk->usage,2); atomic_set(&tsk->fs_excl, 0); diff --git a/trunk/kernel/lockdep.c b/trunk/kernel/lockdep.c index c088e5542e84..9bad17884513 100644 --- a/trunk/kernel/lockdep.c +++ b/trunk/kernel/lockdep.c @@ -224,14 +224,7 @@ static int save_trace(struct stack_trace *trace) trace->max_entries = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries; trace->entries = stack_trace + nr_stack_trace_entries; - trace->skip = 3; - trace->all_contexts = 0; - - /* Make sure to not recurse in case the the unwinder needs to tak -e locks. */ - lockdep_off(); - save_stack_trace(trace, NULL); - lockdep_on(); + save_stack_trace(trace, NULL, 0, 3); trace->max_entries = trace->nr_entries; diff --git a/trunk/kernel/panic.c b/trunk/kernel/panic.c index 6ceb664fb52a..8010b9b17aca 100644 --- a/trunk/kernel/panic.c +++ b/trunk/kernel/panic.c @@ -21,7 +21,6 @@ #include int panic_on_oops; -int panic_on_unrecovered_nmi; int tainted; static int pause_on_oops; static int pause_on_oops_flag; @@ -271,15 +270,3 @@ void oops_exit(void) { do_oops_enter_exit(); } - -#ifdef CONFIG_CC_STACKPROTECTOR -/* - * Called when gcc's -fstack-protector feature is used, and - * gcc detects corruption of the on-stack canary value - */ -void __stack_chk_fail(void) -{ - panic("stack-protector: Kernel stack is corrupted"); -} -EXPORT_SYMBOL(__stack_chk_fail); -#endif diff --git a/trunk/kernel/resource.c b/trunk/kernel/resource.c index 9db38a1a7520..46286434af80 100644 --- a/trunk/kernel/resource.c +++ b/trunk/kernel/resource.c @@ -344,11 +344,12 @@ EXPORT_SYMBOL(allocate_resource); * * Returns 0 on success, -EBUSY if the resource can't be inserted. * - * This function is equivalent to request_resource when no conflict + * This function is equivalent of request_resource when no conflict * happens. If a conflict happens, and the conflicting resources * entirely fit within the range of the new resource, then the new - * resource is inserted and the conflicting resources become children of - * the new resource. + * resource is inserted and the conflicting resources become childs of + * the new resource. Otherwise the new resource becomes the child of + * the conflicting resource */ int insert_resource(struct resource *parent, struct resource *new) { @@ -356,21 +357,20 @@ int insert_resource(struct resource *parent, struct resource *new) struct resource *first, *next; write_lock(&resource_lock); + begin: + result = 0; + first = __request_resource(parent, new); + if (!first) + goto out; - for (;; parent = first) { - result = 0; - first = __request_resource(parent, new); - if (!first) - goto out; - - result = -EBUSY; - if (first == parent) - goto out; + result = -EBUSY; + if (first == parent) + goto out; - if ((first->start > new->start) || (first->end < new->end)) - break; - if ((first->start == new->start) && (first->end == new->end)) - break; + /* Resource fully contained by the clashing resource? Recurse into it */ + if (first->start <= new->start && first->end >= new->end) { + parent = first; + goto begin; } for (next = first; ; next = next->sibling) { diff --git a/trunk/kernel/spinlock.c b/trunk/kernel/spinlock.c index 9644a41e0bef..fb524b009eef 100644 --- a/trunk/kernel/spinlock.c +++ b/trunk/kernel/spinlock.c @@ -7,11 +7,6 @@ * * This file contains the spinlock/rwlock implementations for the * SMP and the DEBUG_SPINLOCK cases. (UP-nondebug inlines them) - * - * Note that some architectures have special knowledge about the - * stack frames of these functions in their profile_pc. If you - * change anything significant here that could change the stack - * frame contact the architecture maintainers. */ #include diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index 3f894775488d..e236f98f7ec5 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -2063,33 +2062,3 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, } return error; } - -asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep, - struct getcpu_cache __user *cache) -{ - int err = 0; - int cpu = raw_smp_processor_id(); - if (cpup) - err |= put_user(cpu, cpup); - if (nodep) - err |= put_user(cpu_to_node(cpu), nodep); - if (cache) { - /* - * The cache is not needed for this implementation, - * but make sure user programs pass something - * valid. vsyscall implementations can instead make - * good use of the cache. Only use t0 and t1 because - * these are available in both 32bit and 64bit ABI (no - * need for a compat_getcpu). 32bit has enough - * padding - */ - unsigned long t0, t1; - get_user(t0, &cache->t0); - get_user(t1, &cache->t1); - t0++; - t1++; - put_user(t0, &cache->t0); - put_user(t1, &cache->t1); - } - return err ? -EFAULT : 0; -} diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index bcb3a181dbb2..fd43c3e6786b 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -76,9 +76,8 @@ extern int compat_log; #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) int unknown_nmi_panic; -int nmi_watchdog_enabled; -extern int proc_nmi_enabled(struct ctl_table *, int , struct file *, - void __user *, size_t *, loff_t *); +extern int proc_unknown_nmi_panic(ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); #endif /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ @@ -629,26 +628,10 @@ static ctl_table kern_table[] = { .data = &unknown_nmi_panic, .maxlen = sizeof (int), .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .ctl_name = KERN_NMI_WATCHDOG, - .procname = "nmi_watchdog", - .data = &nmi_watchdog_enabled, - .maxlen = sizeof (int), - .mode = 0644, - .proc_handler = &proc_nmi_enabled, + .proc_handler = &proc_unknown_nmi_panic, }, #endif #if defined(CONFIG_X86) - { - .ctl_name = KERN_PANIC_ON_NMI, - .procname = "panic_on_unrecovered_nmi", - .data = &panic_on_unrecovered_nmi, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, { .ctl_name = KERN_BOOTLOADER_TYPE, .procname = "bootloader_type", diff --git a/trunk/kernel/unwind.c b/trunk/kernel/unwind.c index 3430475fcd88..f69c804c8e62 100644 --- a/trunk/kernel/unwind.c +++ b/trunk/kernel/unwind.c @@ -603,7 +603,6 @@ int unwind(struct unwind_frame_info *frame) #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs]) const u32 *fde = NULL, *cie = NULL; const u8 *ptr = NULL, *end = NULL; - unsigned long pc = UNW_PC(frame) - frame->call_frame; unsigned long startLoc = 0, endLoc = 0, cfa; unsigned i; signed ptrType = -1; @@ -613,7 +612,7 @@ int unwind(struct unwind_frame_info *frame) if (UNW_PC(frame) == 0) return -EINVAL; - if ((table = find_table(pc)) != NULL + if ((table = find_table(UNW_PC(frame))) != NULL && !(table->size & (sizeof(*fde) - 1))) { unsigned long tableSize = table->size; @@ -648,7 +647,7 @@ int unwind(struct unwind_frame_info *frame) ptrType & DW_EH_PE_indirect ? ptrType : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed)); - if (pc >= startLoc && pc < endLoc) + if (UNW_PC(frame) >= startLoc && UNW_PC(frame) < endLoc) break; cie = NULL; } @@ -658,28 +657,16 @@ int unwind(struct unwind_frame_info *frame) state.cieEnd = ptr; /* keep here temporarily */ ptr = (const u8 *)(cie + 2); end = (const u8 *)(cie + 1) + *cie; - frame->call_frame = 1; if ((state.version = *ptr) != 1) cie = NULL; /* unsupported version */ else if (*++ptr) { /* check if augmentation size is first (and thus present) */ if (*ptr == 'z') { - while (++ptr < end && *ptr) { - switch(*ptr) { - /* check for ignorable (or already handled) - * nul-terminated augmentation string */ - case 'L': - case 'P': - case 'R': - continue; - case 'S': - frame->call_frame = 0; - continue; - default: + /* check for ignorable (or already handled) + * nul-terminated augmentation string */ + while (++ptr < end && *ptr) + if (strchr("LPR", *ptr) == NULL) break; - } - break; - } } if (ptr >= end || *ptr) cie = NULL; @@ -768,7 +755,7 @@ int unwind(struct unwind_frame_info *frame) state.org = startLoc; memcpy(&state.cfa, &badCFA, sizeof(state.cfa)); /* process instructions */ - if (!processCFI(ptr, end, pc, ptrType, &state) + if (!processCFI(ptr, end, UNW_PC(frame), ptrType, &state) || state.loc > endLoc || state.regs[retAddrReg].where == Nowhere || state.cfa.reg >= ARRAY_SIZE(reg_info) @@ -776,11 +763,6 @@ int unwind(struct unwind_frame_info *frame) || state.cfa.offs % sizeof(unsigned long)) return -EIO; /* update frame */ -#ifndef CONFIG_AS_CFI_SIGNAL_FRAME - if(frame->call_frame - && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign)) - frame->call_frame = 0; -#endif cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs; startLoc = min((unsigned long)UNW_SP(frame), cfa); endLoc = max((unsigned long)UNW_SP(frame), cfa); @@ -884,7 +866,6 @@ int unwind_init_frame_info(struct unwind_frame_info *info, /*const*/ struct pt_regs *regs) { info->task = tsk; - info->call_frame = 0; arch_unw_init_frame_info(info, regs); return 0; @@ -898,7 +879,6 @@ int unwind_init_blocked(struct unwind_frame_info *info, struct task_struct *tsk) { info->task = tsk; - info->call_frame = 0; arch_unw_init_blocked(info); return 0; @@ -914,7 +894,6 @@ int unwind_init_running(struct unwind_frame_info *info, void *arg) { info->task = current; - info->call_frame = 0; return arch_unwind_init_running(info, callback, arg); } diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index f1ac3184dc08..2869307ca3e4 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -225,7 +225,7 @@ config LOCKDEP bool depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT select STACKTRACE - select FRAME_POINTER if !X86 + select FRAME_POINTER select KALLSYMS select KALLSYMS_ALL diff --git a/trunk/lib/hweight.c b/trunk/lib/hweight.c index 360556a7803d..438257671708 100644 --- a/trunk/lib/hweight.c +++ b/trunk/lib/hweight.c @@ -1,6 +1,5 @@ #include #include -#include /** * hweightN - returns the hamming weight of a N-bit word @@ -41,19 +40,14 @@ unsigned long hweight64(__u64 w) #if BITS_PER_LONG == 32 return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); #elif BITS_PER_LONG == 64 -#ifdef ARCH_HAS_FAST_MULTIPLIER - w -= (w >> 1) & 0x5555555555555555ul; - w = (w & 0x3333333333333333ul) + ((w >> 2) & 0x3333333333333333ul); - w = (w + (w >> 4)) & 0x0f0f0f0f0f0f0f0ful; - return (w * 0x0101010101010101ul) >> 56; -#else __u64 res = w - ((w >> 1) & 0x5555555555555555ul); res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful; res = res + (res >> 8); res = res + (res >> 16); return (res + (res >> 32)) & 0x00000000000000FFul; -#endif +#else +#error BITS_PER_LONG not defined #endif } EXPORT_SYMBOL(hweight64); diff --git a/trunk/scripts/Kbuild.include b/trunk/scripts/Kbuild.include index 4f5ff19b992b..3d523899fdc0 100644 --- a/trunk/scripts/Kbuild.include +++ b/trunk/scripts/Kbuild.include @@ -63,13 +63,6 @@ as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \ -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \ else echo "$(2)"; fi ;) -# as-instr -# Usage: cflags-y += $(call as-instr, instr, option1, option2) - -as-instr = $(shell if echo -e "$(1)" | $(AS) >/dev/null 2>&1 -W -Z -o astest$$$$.out ; \ - then echo "$(2)"; else echo "$(3)"; fi; \ - rm -f astest$$$$.out) - # cc-option # Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586) diff --git a/trunk/scripts/gcc-x86_64-has-stack-protector.sh b/trunk/scripts/gcc-x86_64-has-stack-protector.sh deleted file mode 100644 index 325c0a1b03b6..000000000000 --- a/trunk/scripts/gcc-x86_64-has-stack-protector.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -echo "int foo(void) { char X[200]; return 3; }" | $1 -S -xc -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs" -if [ "$?" -eq "0" ] ; then - echo $2 -fi