Commit 88e4bc32 authored by Andi Kleen's avatar Andi Kleen Committed by Russell King

[PATCH] x86-64 architecture specific sync for 2.5.8

This patch brings 2.5.8 in sync with the x86-64 2.4 development tree again
(excluding device drivers)

It has lots of bug fixes and enhancements. It only touches architecture
specific files.

- Sync with 2.5.8
- SMP/APIC supported now.
- Module loading works now.
- Time keeping bugs fixed.
- entry.S streamlined and some bugs fixed.
- modify_ldt works now
- mostly rewritten FPU support (including FXRSTOR for initial FPU
  initialization based on the initial state)
- 32bit emulation enhanced and bugs fixed.
- rewrote mm initialization and lots of cleanups in the page table handling
  __PAGE_OFFSET is now moved to 0x10000000000 and some vmalloc/ioremap
  problems have been fixed. They have an own PML4 slot now.
- WCHAN reporting support for RIP (but not RSP)
- Lots of various other bug fixes and cleanups.

Currently broken:
- ACPI
- MTRR

It needs some other bugfixes outside architecture specific code. I sent
them all in separate mail.
parent 61aacaa2
......@@ -396,33 +396,31 @@ CONFIG_PM
sending the processor to sleep and saving power.
CONFIG_ACPI
ACPI/OSPM support for Linux is currently under development. As such,
this support is preliminary and EXPERIMENTAL. Configuring ACPI
support enables kernel interfaces that allow higher level software
(OSPM) to manipulate ACPI defined hardware and software interfaces,
including the evaluation of ACPI control methods. If unsure, choose
N here. Note, this option will enlarge your kernel by about 120K.
This support requires an ACPI compliant platform (hardware/firmware).
If both ACPI and Advanced Power Management (APM) support are
configured, whichever is loaded first shall be used.
This code DOES NOT currently provide a complete OSPM implementation
-- it has not yet reached APM's level of functionality. When fully
implemented, Linux ACPI/OSPM will provide a more robust functional
replacement for legacy configuration and power management
interfaces, including the Plug-and-Play BIOS specification (PnP
BIOS), the Multi-Processor Specification (MPS), and the Advanced
Power Management specification (APM).
Linux support for ACPI/OSPM is based on Intel Corporation's ACPI
Component Architecture (ACPI CA). The latest ACPI CA source code,
documentation, debug builds, and implementation status information
can be downloaded from:
<http://developer.intel.com/technology/iapc/acpi/downloads.htm>.
The ACPI Sourceforge project may also be of interest:
<http://sf.net/projects/acpi/>
Advanced Configuration and Power Interface (ACPI) support for
Linux requires an ACPI compliant platform (hardware/firmware),
and assumes the presence of OS-directed configuration and power
management (OSPM) software.
Linux ACPI provides a robust functional replacement for several
legacy configuration and power management intefaces, including
the Plug-and-Play BIOS specification (PnP BIOS), the
MultiProcessor Specification (MPS), and the Advanced Power
Management (APM) specification. If both ACPI and APM support
are configured, whichever is loaded first shall be used.
The ACPI SourceForge project contains the latest source code,
documentation, tools, mailing list subscription, and other
information. This project is available at:
<http://sourceforge.net/projects/acpi>
Linux support for ACPI is based on Intel Corporation's ACPI
Component Architecture (ACPI CA). For more information see:
<http://developer.intel.com/technology/iapc/acpi>
ACPI is an open industry specification co-developed by Compaq,
Intel, Microsoft, Phoenix, and Toshiba. The specification is
available at:
<http://www.acpi.info>
CONFIG_X86_MSR
This device gives privileged processes access to the x86
......@@ -437,34 +435,6 @@ CONFIG_X86_CPUID
with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
/dev/cpu/31/cpuid.
CONFIG_SOUND
If you have a sound card in your computer, i.e. if it can say more
than an occasional beep, say Y. Be sure to have all the information
about your sound card and its configuration down (I/O port,
interrupt and DMA channel), because you will be asked for it.
You want to read the Sound-HOWTO, available from
<http://www.linuxdoc.org/docs.html#howto>. General information about
the modular sound system is contained in the files
<file:Documentation/sound/Introduction>. The file
<file:Documentation/sound/README.OSS> contains some slightly
outdated but still useful information as well.
If you have a PnP sound card and you want to configure it at boot
time using the ISA PnP tools (read
<http://www.roestock.demon.co.uk/isapnptools/>), then you need to
compile the sound card support as a module ( = code which can be
inserted in and removed from the running kernel whenever you want)
and load that module after the PnP configuration is finished. To do
this, say M here and read <file:Documentation/modules.txt> as well
as <file:Documentation/sound/README.modules>; the module will be
called soundcore.o.
I'm told that even without a sound card, you can make your computer
say more than an occasional beep, by programming the PC speaker.
Kernel patches and supporting utilities to do that are in the pcsp
package, available at <ftp://ftp.infradead.org/pub/pcsp/>.
CONFIG_PREEMPT
This option reduces the latency of the kernel when reacting to
real-time or interactive events by allowing a low priority process to
......@@ -529,3 +499,13 @@ CONFIG_EARLY_PRINTK
klogd/syslogd or the X server.You should normally N here, unless
you want to debug such a crash.
CONFIG_X86_MCE_NONFATAL
Enabling this feature starts a timer that triggers every 5 seconds which
will look at the machine check registers to see if anything happened.
Non-fatal problems automatically get corrected (but still logged).
Disable this if you don't want to see these messages.
Seeing the messages this option prints out may be indicative of dying hardware,
or out-of-spec (ie, overclocked) hardware.
This option only does something on hardware with Intel P6 style MCE.
(Pentium Pro and above, AMD Athlon/Duron)
......@@ -17,20 +17,19 @@
# 20000913 Pavel Machek <pavel@suse.cz>
# Converted for x86_64 architecture
# 20010105 Andi Kleen, add IA32 compiler.
# ....and later removed it again....
#
# $Id: Makefile,v 1.28 2001/06/29 17:47:43 aj Exp $
# $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $
#
# boot system currently needs IA32 tools to link (to be fixed)
# early bootup linking needs 32bit. You can either use real 32bit tools
# here or 64bit tools switch to 32bit mode.
#
# Change this to your i386 compiler/binutils
IA32_PREFIX := /usr/bin/
IA32_CC := $(IA32_PREFIX)gcc -O2 -fomit-frame-pointer -nostdinc -I $(HPATH)
IA32_LD := $(IA32_PREFIX)ld
IA32_AS := $(IA32_PREFIX)gcc -D__ASSEMBLY__ -traditional -c -nostdinc -I $(HPATH)
IA32_OBJCOPY := $(IA32_PREFIX)objcopy
IA32_CPP := $(IA32_PREFIX)gcc -E
IA32_CC := $(CROSS_COMPILE)gcc -m32 -O2 -fomit-frame-pointer -nostdinc -I $(HPATH)
IA32_LD := $(CROSS_COMPILE)ld -m elf_i386
IA32_AS := $(CROSS_COMPILE)gcc -m32 -Wa,--32 -D__ASSEMBLY__ -traditional -c -nostdinc -I $(HPATH)
IA32_OBJCOPY := $(CROSS_COMPILE)objcopy
IA32_CPP := $(CROSS_COMPILE)gcc -m32 -E
export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP
......@@ -39,16 +38,14 @@ OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
LDFLAGS=-e stext
LINKFLAGS =-T $(TOPDIR)/arch/x86_64/vmlinux.lds $(LDFLAGS)
CFLAGS += $(shell if $(CC) -mno-red-zone -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mno-red-zone"; fi )
CFLAGS += -mno-red-zone
CFLAGS += -mcmodel=kernel
CFLAGS += -pipe
# generates worse code, but makes the assembly much more readable:
CFLAGS += -fno-reorder-blocks
# work around early gcc 3.1 bugs. Later snapshots should this already fixed.
# needed for later gcc 3.1
CFLAGS += -finline-limit=2000
# needed for earlier gcc 3.1
CFLAGS += -fno-strength-reduce
# make sure all inline functions are inlined
CFLAGS += -finline-limit=3000
#CFLAGS += -g
# prevent gcc from keeping the stack 16 byte aligned (FIXME)
......@@ -61,8 +58,6 @@ CORE_FILES := arch/x86_64/kernel/kernel.o $(CORE_FILES)
CORE_FILES += arch/x86_64/mm/mm.o
LIBS := $(TOPDIR)/arch/x86_64/lib/lib.a $(LIBS)
CLEAN_FILES += include/asm-x86_64/offset.h
ifdef CONFIG_IA32_EMULATION
SUBDIRS += arch/x86_64/ia32
CORE_FILES += arch/x86_64/ia32/ia32.o
......@@ -88,14 +83,14 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
vmlinux: arch/x86_64/vmlinux.lds
checkoffset: FORCE
make -C arch/$(ARCH)/tools $(TOPDIR)/include/asm-x86_64/offset.h
FORCE: ;
.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
clean archclean archmrproper archdep checkoffset
checkoffset: FORCE
make -C arch/$(ARCH)/tools $(TOPDIR)/include/asm-x86_64/offset.h
bzImage: checkoffset vmlinux
@$(MAKEBOOT) bzImage
......@@ -104,12 +99,10 @@ bzImage-padded: checkoffset vmlinux
tmp:
@$(MAKEBOOT) BOOTIMAGE=bzImage zlilo
bzlilo: checkoffset vmlinux
@$(MAKEBOOT) BOOTIMAGE=bzImage zlilo
zdisk: checkoffset vmlinux
@$(MAKEBOOT) BOOTIMAGE=zImage zdisk
bzdisk: checkoffset vmlinux
@$(MAKEBOOT) BOOTIMAGE=bzImage zdisk
......@@ -118,7 +111,7 @@ install: checkoffset vmlinux
archclean:
@$(MAKEBOOT) clean
$(MAKE) -C $(TOPDIR)/arch/x86_64/tools clean
@$(MAKE) -C $(TOPDIR)/arch/x86_64/tools clean
archmrproper:
rm -f $(TOPDIR)/arch/x86_64/tools/offset.h
......
......@@ -435,36 +435,7 @@ no_disk1:
rep
stosb
is_disk1:
# check for Micro Channel (MCA) bus
movw %cs, %ax # aka SETUPSEG
subw $DELTA_INITSEG, %ax # aka INITSEG
movw %ax, %ds
xorw %ax, %ax
movw %ax, (0xa0) # set table length to 0
movb $0xc0, %ah
stc
int $0x15 # moves feature table to es:bx
jc no_mca
pushw %ds
movw %es, %ax
movw %ax, %ds
movw %cs, %ax # aka SETUPSEG
subw $DELTA_INITSEG, %ax # aka INITSEG
movw %ax, %es
movw %bx, %si
movw $0xa0, %di
movw (%si), %cx
addw $2, %cx # table length is a short
cmpw $0x10, %cx
jc sysdesc_ok
movw $0x10, %cx # we keep only first 16 bytes
sysdesc_ok:
rep
movsb
popw %ds
no_mca:
# Check for PS/2 pointing device
movw %cs, %ax # aka SETUPSEG
subw $DELTA_INITSEG, %ax # aka INITSEG
......@@ -477,71 +448,11 @@ no_mca:
movw $0xAA, (0x1ff) # device present
no_psmouse:
#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
# Then check for an APM BIOS...
# %ds points to the bootsector
movw $0, 0x40 # version = 0 means no APM BIOS
movw $0x05300, %ax # APM BIOS installation check
xorw %bx, %bx
int $0x15
jc done_apm_bios # Nope, no APM BIOS
cmpw $0x0504d, %bx # Check for "PM" signature
jne done_apm_bios # No signature, no APM BIOS
andw $0x02, %cx # Is 32 bit supported?
je done_apm_bios # No 32-bit, no (good) APM BIOS
movw $0x05304, %ax # Disconnect first just in case
xorw %bx, %bx
int $0x15 # ignore return code
movw $0x05303, %ax # 32 bit connect
xorl %ebx, %ebx
xorw %cx, %cx # paranoia :-)
xorw %dx, %dx # ...
xorl %esi, %esi # ...
xorw %di, %di # ...
int $0x15
jc no_32_apm_bios # Ack, error.
movw %ax, (66) # BIOS code segment
movl %ebx, (68) # BIOS entry point offset
movw %cx, (72) # BIOS 16 bit code segment
movw %dx, (74) # BIOS data segment
movl %esi, (78) # BIOS code segment lengths
movw %di, (82) # BIOS data segment length
# Redo the installation check as the 32 bit connect
# modifies the flags returned on some BIOSs
movw $0x05300, %ax # APM BIOS installation check
xorw %bx, %bx
xorw %cx, %cx # paranoia
int $0x15
jc apm_disconnect # error -> shouldn't happen
cmpw $0x0504d, %bx # check for "PM" signature
jne apm_disconnect # no sig -> shouldn't happen
movw %ax, (64) # record the APM BIOS version
movw %cx, (76) # and flags
jmp done_apm_bios
apm_disconnect: # Tidy up
movw $0x05304, %ax # Disconnect
xorw %bx, %bx
int $0x15 # ignore return code
jmp done_apm_bios
no_32_apm_bios:
andw $0xfffd, (76) # remove 32 bit support bit
done_apm_bios:
#endif
# Now we want to move to protected mode ...
cmpw $0, %cs:realmode_swtch
jz rmodeswtch_normal
lcall *%cs:realmode_swtch
lcall %cs:realmode_swtch
jmp rmodeswtch_end
......
......@@ -66,7 +66,6 @@
#define VIDEO_80x30 0x0f05
#define VIDEO_80x34 0x0f06
#define VIDEO_80x60 0x0f07
#define VIDEO_GFX_HACK 0x0f08
#define VIDEO_LAST_SPECIAL 0x0f09
/* Video modes given by resolution */
......@@ -741,15 +740,7 @@ set_80x60:
movw $0x503c, force_size
jmp setvde
# Special hack for ThinkPad graphics
set_gfx:
#ifdef CONFIG_VIDEO_GFX_HACK
movw $VIDEO_GFX_BIOS_AX, %ax
movw $VIDEO_GFX_BIOS_BX, %bx
int $0x10
movw $VIDEO_GFX_DUMMY_RESOLUTION, force_size
stc
#endif
ret
#ifdef CONFIG_VIDEO_RETAIN
......@@ -974,10 +965,6 @@ vga_modes:
.word 0x5022 # 80x34
.word VIDEO_80x60
.word 0x503c # 80x60
#ifdef CONFIG_VIDEO_GFX_HACK
.word VIDEO_GFX_HACK
.word VIDEO_GFX_DUMMY_RESOLUTION
#endif
vga_modes_end:
# Detect VESA modes.
......
......@@ -11,16 +11,16 @@ define_bool CONFIG_ISA y
define_bool CONFIG_SBUS n
define_bool CONFIG_UID16 y
define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
define_bool CONFIG_X86_CMPXCHG y
source init/Config.in
mainmenu_option next_comment
comment 'Processor type and features'
choice 'Processor family' \
"Clawhammer CONFIG_MK8" Clawhammer
"AMD-Hammer CONFIG_MK8" CONFIG_MK8
#
# Define implied options from the CPU selection here
......@@ -29,7 +29,6 @@ define_int CONFIG_X86_L1_CACHE_BYTES 64
define_int CONFIG_X86_L1_CACHE_SHIFT 6
define_bool CONFIG_X86_TSC y
define_bool CONFIG_X86_GOOD_APIC y
define_bool CONFIG_X86_CMPXCHG y
tristate '/dev/cpu/*/msr - Model-specific register support' CONFIG_X86_MSR
tristate '/dev/cpu/*/cpuid - CPU information support' CONFIG_X86_CPUID
......@@ -37,32 +36,31 @@ tristate '/dev/cpu/*/cpuid - CPU information support' CONFIG_X86_CPUID
define_bool CONFIG_MATH_EMULATION n
define_bool CONFIG_MCA n
define_bool CONFIG_EISA n
define_bool CONFIG_X86_IO_APIC y
define_bool CONFIG_X86_LOCAL_APIC y
bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
#currently broken:
#bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
bool 'Symmetric multi-processing support' CONFIG_SMP
bool 'Preemptible Kernel' CONFIG_PREEMPT
# currently doesn't boot without hacks. probably simulator bug.
#if [ "$CONFIG_SMP" != "y" ]; then
# bool 'APIC and IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC
# if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then
# define_bool CONFIG_X86_IO_APIC y
# define_bool CONFIG_X86_LOCAL_APIC y
# fi
#fi
if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
define_bool CONFIG_HAVE_DEC_LOCK y
fi
define_bool CONFIG_X86_MCE y
bool 'Check for non-fatal machine check errors' CONFIG_X86_MCE_NONFATAL $CONFIG_X86_MCE
endmenu
mainmenu_option next_comment
comment 'General options'
if [ "$CONFIG_SMP" = "y" ]; then
define_bool CONFIG_X86_IO_APIC y
define_bool CONFIG_X86_LOCAL_APIC y
fi
source drivers/acpi/Config.in
bool 'PCI support' CONFIG_PCI
if [ "$CONFIG_PCI" = "y" ]; then
# x86-64 doesn't support PCI BIOS access from long mode so always go direct.
define_bool CONFIG_PCI_DIRECT y
fi
......@@ -80,22 +78,14 @@ fi
if [ "$CONFIG_PROC_FS" = "y" ]; then
define_bool CONFIG_KCORE_ELF y
fi
# We probably are not going to support a.out, are we? Or should we support a.out in i386 compatibility mode?
#tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
#tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
bool 'Power Management support' CONFIG_PM
bool 'IA32 Emulation' CONFIG_IA32_EMULATION
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_bool ' ACPI support' CONFIG_ACPI $CONFIG_PM
if [ "$CONFIG_ACPI" != "n" ]; then
source drivers/acpi/Config.in
fi
fi
endmenu
source drivers/mtd/Config.in
......@@ -186,10 +176,6 @@ endmenu
source drivers/input/Config.in
source drivers/char/Config.in
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
source net/bluetooth/Config.in
fi
source drivers/misc/Config.in
source drivers/media/Config.in
......@@ -219,6 +205,10 @@ endmenu
source drivers/usb/Config.in
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
source net/bluetooth/Config.in
fi
mainmenu_option next_comment
comment 'Kernel hacking'
......@@ -228,13 +218,13 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
# bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
# bool ' Early printk' CONFIG_EARLY_PRINTK
bool ' Early printk' CONFIG_EARLY_PRINTK
bool ' Additional run-time checks' CONFIG_CHECKING
fi
bool 'Simnow environment (disables time-consuming things)' CONFIG_SIMNOW
bool ' Debug __init statements' CONFIG_INIT_DEBUG
#if [ "$CONFIG_SERIAL_CONSOLE" = "y" ]; then
# bool 'Early serial console (ttyS0)' CONFIG_EARLY_SERIAL_CONSOLE
#fi
fi
endmenu
source lib/Config.in
......@@ -6,8 +6,9 @@ CONFIG_X86=y
CONFIG_ISA=y
# CONFIG_SBUS is not set
CONFIG_UID16=y
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_X86_CMPXCHG=y
#
# Code maturity level options
......@@ -37,19 +38,27 @@ CONFIG_X86_L1_CACHE_BYTES=64
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_TSC=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_CMPXCHG=y
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
# CONFIG_MATH_EMULATION is not set
# CONFIG_MCA is not set
# CONFIG_EISA is not set
CONFIG_MTRR=y
# CONFIG_SMP is not set
CONFIG_X86_IO_APIC=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_SMP=y
# CONFIG_PREEMPT is not set
CONFIG_HAVE_DEC_LOCK=y
CONFIG_X86_MCE=y
# CONFIG_X86_MCE_NONFATAL is not set
#
# General options
#
#
# ACPI Support
#
# CONFIG_ACPI is not set
CONFIG_PCI=y
CONFIG_PCI_DIRECT=y
# CONFIG_PCI_NAMES is not set
......@@ -60,7 +69,6 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_PM=y
CONFIG_IA32_EMULATION=y
# CONFIG_ACPI is not set
#
# Memory Technology Devices (MTD)
......@@ -162,7 +170,7 @@ CONFIG_INET=y
CONFIG_IDE=y
#
# IDE, ATA and ATAPI Block devices
# ATA and ATAPI Block devices
#
CONFIG_BLK_DEV_IDE=y
......@@ -172,7 +180,7 @@ CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_IDEDISK_STROKE is not set
# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
......@@ -184,23 +192,55 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_COMMERIAL is not set
# CONFIG_BLK_DEV_TIVO is not set
# CONFIG_BLK_DEV_IDECS is not set
# CONFIG_BLK_DEV_IDECD is not set
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
#
# IDE chipset support/bugfixes
# IDE chipset support
#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_IDEPCI is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_BLK_DEV_IDE_TCQ is not set
# CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_AEC62XX_TUNING is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_HPT34X_AUTODMA is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC_ADMA is not set
# CONFIG_BLK_DEV_PDC202XX is not set
# CONFIG_PDC202XX_BURST is not set
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_IDEDMA_IVB is not set
CONFIG_IDEDMA_AUTO=y
# CONFIG_DMA_NONPCI is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_ATARAID is not set
# CONFIG_BLK_DEV_ATARAID_PDC is not set
# CONFIG_BLK_DEV_ATARAID_HPT is not set
......@@ -315,11 +355,6 @@ CONFIG_PSMOUSE=y
# CONFIG_DRM is not set
# CONFIG_MWAVE is not set
#
# Bluetooth support
#
# CONFIG_BLUEZ is not set
#
# Misc devices
#
......@@ -359,6 +394,9 @@ CONFIG_RAMFS=y
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_ZISOFS is not set
# CONFIG_JFS_FS is not set
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_NTFS_FS is not set
......@@ -389,6 +427,7 @@ CONFIG_EXT2_FS=y
# CONFIG_ROOT_NFS is not set
# CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_TCP is not set
# CONFIG_SUNRPC is not set
# CONFIG_LOCKD is not set
# CONFIG_SMB_FS is not set
......@@ -434,110 +473,9 @@ CONFIG_VGA_CONSOLE=y
# CONFIG_USB is not set
#
# USB Host Controller Drivers
#
# CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI is not set
# CONFIG_USB_UHCI_ALT is not set
# CONFIG_USB_OHCI is not set
#
# USB Device Class drivers
#
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_BLUETOOTH is not set
#
# SCSI support is needed for USB Storage
#
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_HP8200e is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
#
# USB Human Interface Devices (HID)
#
#
# Input core support is needed for USB HID
#
#
# USB Imaging devices
#
# CONFIG_USB_DC2XX is not set
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_SCANNER is not set
# CONFIG_USB_MICROTEK is not set
# CONFIG_USB_HPUSBSCSI is not set
#
# USB Multimedia devices
#
#
# Video4Linux support is needed for USB Multimedia device support
#
#
# USB Network adaptors
#
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_CATC is not set
# CONFIG_USB_CDCETHER is not set
# CONFIG_USB_USBNET is not set
#
# USB port drivers
#
# CONFIG_USB_USS720 is not set
#
# USB Serial Converter support
#
# CONFIG_USB_SERIAL is not set
# CONFIG_USB_SERIAL_GENERIC is not set
# CONFIG_USB_SERIAL_BELKIN is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
# CONFIG_USB_SERIAL_EMPEG is not set
# CONFIG_USB_SERIAL_FTDI_SIO is not set
# CONFIG_USB_SERIAL_VISOR is not set
# CONFIG_USB_SERIAL_IPAQ is not set
# CONFIG_USB_SERIAL_IR is not set
# CONFIG_USB_SERIAL_EDGEPORT is not set
# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
# CONFIG_USB_SERIAL_KEYSPAN is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
# CONFIG_USB_SERIAL_MCT_U232 is not set
# CONFIG_USB_SERIAL_KLSI is not set
# CONFIG_USB_SERIAL_PL2303 is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_SERIAL_OMNINET is not set
#
# USB Miscellaneous drivers
# Bluetooth support
#
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_BLUEZ is not set
#
# Kernel hacking
......@@ -546,8 +484,9 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SLAB is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_EARLY_PRINTK is not set
# CONFIG_CHECKING is not set
CONFIG_SIMNOW=y
# CONFIG_INIT_DEBUG is not set
#
# Library routines
......
......@@ -7,11 +7,13 @@
.S.o:
$(CC) $(AFLAGS) -c -o $*.o $<
export-objs := ia32_ioctl.o
all: ia32.o
O_TARGET := ia32.o
obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o ia32_signal.o ia32_binfmt.o \
socket32.o ptrace32.o
obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o ia32_signal.o \
ia32_binfmt.o fpu32.o socket32.o ptrace32.o
clean::
......
/*
* Copyright 2002 Andi Kleen, SuSE Labs.
* FXSAVE<->i387 conversion support. Based on code by Gareth Hughes.
* This is used for ptrace, signals and coredumps in 32bit emulation.
* $Id: fpu32.c,v 1.1 2002/03/21 14:16:32 ak Exp $
*/
#include <linux/sched.h>
#include <asm/sigcontext32.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/i387.h>
static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
{
unsigned int tmp; /* to avoid 16 bit prefixes in the code */
/* Transform each pair of bits into 01 (valid) or 00 (empty) */
tmp = ~twd;
tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
/* and move the valid bits to the lower byte. */
tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
return tmp;
}
static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
{
struct _fpxreg *st = NULL;
unsigned long twd = (unsigned long) fxsave->twd;
unsigned long tag;
unsigned long ret = 0xffff0000;
int i;
#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
for (i = 0 ; i < 8 ; i++) {
if (twd & 0x1) {
st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
switch (st->exponent & 0x7fff) {
case 0x7fff:
tag = 2; /* Special */
break;
case 0x0000:
if ( !st->significand[0] &&
!st->significand[1] &&
!st->significand[2] &&
!st->significand[3] ) {
tag = 1; /* Zero */
} else {
tag = 2; /* Special */
}
break;
default:
if (st->significand[3] & 0x8000) {
tag = 0; /* Valid */
} else {
tag = 2; /* Special */
}
break;
}
} else {
tag = 3; /* Empty */
}
ret |= (tag << (2 * i));
twd = twd >> 1;
}
return ret;
}
static inline int convert_fxsr_from_user(struct i387_fxsave_struct *fxsave,
struct _fpstate_ia32 *buf)
{
struct _fpxreg *to;
struct _fpreg *from;
int i;
int err;
__u32 v;
err = __get_user(fxsave->cwd, (u16 *)&buf->cw);
err |= __get_user(fxsave->swd, (u16 *)&buf->sw);
err |= __get_user(fxsave->twd, (u16 *)&buf->tag);
fxsave->twd = twd_i387_to_fxsr(fxsave->twd);
err |= __get_user(fxsave->rip, &buf->ipoff);
err |= __get_user(fxsave->rdp, &buf->dataoff);
err |= __get_user(v, &buf->cssel);
fxsave->fop = v >> 16;
if (err)
return -1;
to = (struct _fpxreg *)&fxsave->st_space[0];
from = &buf->_st[0];
for (i = 0 ; i < 8 ; i++, to++, from++) {
if (__copy_from_user(to, from, sizeof(*from)))
return -1;
}
return 0;
}
static inline int convert_fxsr_to_user(struct _fpstate_ia32 *buf,
struct i387_fxsave_struct *fxsave,
struct pt_regs *regs,
struct task_struct *tsk)
{
struct _fpreg *to;
struct _fpxreg *from;
int i;
u32 ds;
int err;
err = __put_user((unsigned long)fxsave->cwd | 0xffff0000, &buf->cw);
err |= __put_user((unsigned long)fxsave->swd | 0xffff0000, &buf->sw);
err |= __put_user((u32)fxsave->rip, &buf->ipoff);
err |= __put_user((u32)(regs->cs | ((u32)fxsave->fop << 16)),
&buf->cssel);
err |= __put_user((u32)twd_fxsr_to_i387(fxsave), &buf->tag);
err |= __put_user((u32)fxsave->rdp, &buf->dataoff);
if (tsk == current)
asm("movl %%ds,%0 " : "=r" (ds));
else /* ptrace. task has stopped. */
ds = tsk->thread.ds;
err |= __put_user(ds, &buf->datasel);
if (err)
return -1;
to = &buf->_st[0];
from = (struct _fpxreg *) &fxsave->st_space[0];
for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
if (__copy_to_user(to, from, sizeof(*to)))
return -1;
}
return 0;
}
int restore_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 *buf, int fsave)
{
clear_fpu(tsk);
if (!fsave) {
if (__copy_from_user(&tsk->thread.i387.fxsave,
&buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct)))
return -1;
}
tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf);
}
int save_i387_ia32(struct task_struct *tsk,
struct _fpstate_ia32 *buf,
struct pt_regs *regs,
int fsave)
{
int err = 0;
if (!tsk->used_math)
return 0;
tsk->used_math = 0;
unlazy_fpu(tsk);
if (convert_fxsr_to_user(buf, &tsk->thread.i387.fxsave, regs, tsk))
return -1;
err |= __put_user(tsk->thread.i387.fxsave.swd, &buf->status);
if (fsave)
return err ? -1 : 1;
err |= __put_user(X86_FXSR_MAGIC, &buf->magic);
err |= __copy_to_user(&buf->_fxsr_env[0], &tsk->thread.i387.fxsave,
sizeof(struct i387_fxsave_struct));
return err ? -1 : 1;
}
/*
* Written 2000 by Andi Kleen.
* Written 2000,2002 by Andi Kleen.
*
* Losely based on the sparc64 and IA64 32bit emulation loaders.
* This tricks binfmt_elf.c into loading 32bit binaries using lots
* of ugly preprocessor tricks. Talk about very very poor man's inheritance.
*/
#include <linux/types.h>
#include <linux/config.h>
#include <linux/stddef.h>
#include <linux/module.h>
#include <linux/rwsem.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <asm/segment.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
#include <asm/user32.h>
#include <asm/sigcontext32.h>
#include <asm/fpu32.h>
#include <asm/i387.h>
struct file;
struct elf_phdr;
......@@ -28,19 +36,99 @@ struct elf_phdr;
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
//#define USE_ELF_CORE_DUMP
#define USE_ELF_CORE_DUMP 1
/* Overwrite elfcore.h */
#define _LINUX_ELFCORE_H 1
typedef unsigned int elf_greg_t;
#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
struct elf_siginfo
{
int si_signo; /* signal number */
int si_code; /* extra code */
int si_errno; /* errno */
};
struct timeval32
{
int tv_sec, tv_usec;
};
struct elf_prstatus
{
struct elf_siginfo pr_info; /* Info associated with signal */
short pr_cursig; /* Current signal */
unsigned int pr_sigpend; /* Set of pending signals */
unsigned int pr_sighold; /* Set of held signals */
pid_t pr_pid;
pid_t pr_ppid;
pid_t pr_pgrp;
pid_t pr_sid;
struct timeval32 pr_utime; /* User time */
struct timeval32 pr_stime; /* System time */
struct timeval32 pr_cutime; /* Cumulative user time */
struct timeval32 pr_cstime; /* Cumulative system time */
elf_gregset_t pr_reg; /* GP registers */
int pr_fpvalid; /* True if math co-processor being used. */
};
#define ELF_PRARGSZ (80) /* Number of chars for args */
struct elf_prpsinfo
{
char pr_state; /* numeric process state */
char pr_sname; /* char for pr_state */
char pr_zomb; /* zombie */
char pr_nice; /* nice val */
unsigned int pr_flag; /* flags */
__u16 pr_uid;
__u16 pr_gid;
pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
/* Lots missing */
char pr_fname[16]; /* filename of executable */
char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
};
#define __STR(x) #x
#define STR(x) __STR(x)
#define _GET_SEG(x) \
({ __u32 seg; asm("movl %%" STR(x) ",%0" : "=r"(seg)); seg; })
/* Assumes current==process to be dumped */
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
pr_reg[0] = regs->rbx; \
pr_reg[1] = regs->rcx; \
pr_reg[2] = regs->rdx; \
pr_reg[3] = regs->rsi; \
pr_reg[4] = regs->rdi; \
pr_reg[5] = regs->rbp; \
pr_reg[6] = regs->rax; \
pr_reg[7] = _GET_SEG(ds); \
pr_reg[8] = _GET_SEG(es); \
pr_reg[9] = _GET_SEG(fs); \
pr_reg[10] = _GET_SEG(gs); \
pr_reg[11] = regs->orig_rax; \
pr_reg[12] = regs->rip; \
pr_reg[13] = regs->cs; \
pr_reg[14] = regs->eflags; \
pr_reg[15] = regs->rsp; \
pr_reg[16] = regs->ss;
#define user user32
#define dump_fpu dump_fpu_ia32
#define __ASM_X86_64_ELF_H 1
#include <asm/ia32.h>
#include <linux/elf.h>
typedef __u32 elf_greg_t;
typedef elf_greg_t elf_gregset_t[8];
/* FIXME -- wrong */
typedef struct user_i387_ia32_struct elf_fpregset_t;
typedef struct user_i387_struct elf_fpxregset_t;
typedef struct user32_fxsr_struct elf_fpxregset_t;
#undef elf_check_arch
#define elf_check_arch(x) \
......@@ -177,11 +265,35 @@ elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int p
unsigned long map_addr;
struct task_struct *me = current;
if (prot & PROT_READ)
prot |= PROT_EXEC;
down_write(&me->mm->mmap_sem);
map_addr = do_mmap(filep, ELF_PAGESTART(addr),
eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type|MAP_32BIT,
eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot,
type|MAP_32BIT,
eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
up_write(&me->mm->mmap_sem);
return(map_addr);
}
int dump_fpu_ia32(struct pt_regs *regs, elf_fpregset_t *fp)
{
struct _fpstate_ia32 *fpu = (void*)fp;
struct task_struct *tsk = current;
mm_segment_t oldfs = get_fs();
int ret;
if (!tsk->used_math)
return 0;
if (!(test_thread_flag(TIF_IA32)))
BUG();
unlazy_fpu(tsk);
set_fs(KERNEL_DS);
ret = save_i387_ia32(current, fpu, regs, 1);
/* Correct for i386 bug. It puts the fop into the upper 16bits of
the tag word (like FXSAVE), not into the fcs*/
fpu->cssel |= fpu->tag & 0xffff0000;
set_fs(oldfs);
return ret;
}
/* $Id: ia32_ioctl.c,v 1.2 2001/07/05 06:28:42 ak Exp $
/* $Id: ia32_ioctl.c,v 1.11 2002/04/18 14:36:37 ak Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 2001 Andi Kleen, SuSE Labs
* Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
*
* These routines maintain argument size conversion between 32bit and 64bit
* ioctls.
......@@ -51,6 +51,10 @@
#include <linux/elevator.h>
#include <linux/rtc.h>
#include <linux/pci.h>
#include <linux/rtc.h>
#include <linux/module.h>
#include <linux/serial.h>
#include <linux/reiserfs_fs.h>
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
/* Ugh. This header really is not clean */
#define min min
......@@ -2972,12 +2976,139 @@ static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg)
return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
}
/* SuSE extension */
#ifndef TIOCGDEV
#define TIOCGDEV _IOR('T',0x32, unsigned int)
#endif
static int tiocgdev(unsigned fd, unsigned cmd, unsigned int *ptr)
{
struct file *file = fget(fd);
struct tty_struct *real_tty;
if (!fd)
return -EBADF;
if (file->f_op->ioctl != tty_ioctl)
return -EINVAL;
real_tty = (struct tty_struct *)file->private_data;
if (!real_tty)
return -EINVAL;
return put_user(kdev_t_to_nr(real_tty->device), ptr);
}
struct raw32_config_request
{
int raw_minor;
__u64 block_major;
__u64 block_minor;
} __attribute__((packed));
static int raw_ioctl(unsigned fd, unsigned cmd, void *ptr)
{
int ret;
switch (cmd) {
case RAW_SETBIND:
case RAW_GETBIND: {
struct raw_config_request req;
struct raw32_config_request *user_req = ptr;
mm_segment_t oldfs = get_fs();
if (get_user(req.raw_minor, &user_req->raw_minor) ||
get_user(req.block_major, &user_req->block_major) ||
get_user(req.block_minor, &user_req->block_minor))
return -EFAULT;
set_fs(KERNEL_DS);
ret = sys_ioctl(fd,cmd,(unsigned long)&req);
set_fs(oldfs);
break;
}
default:
ret = sys_ioctl(fd,cmd,(unsigned long)ptr);
break;
}
return ret;
}
struct serial_struct32 {
int type;
int line;
unsigned int port;
int irq;
int flags;
int xmit_fifo_size;
int custom_divisor;
int baud_base;
unsigned short close_delay;
char io_type;
char reserved_char[1];
int hub6;
unsigned short closing_wait; /* time to wait before closing */
unsigned short closing_wait2; /* no longer used... */
__u32 iomem_base;
unsigned short iomem_reg_shift;
unsigned int port_high;
int reserved[1];
};
static int serial_struct_ioctl(unsigned fd, unsigned cmd, void *ptr)
{
typedef struct serial_struct SS;
struct serial_struct32 *ss32 = ptr;
int err = 0;
struct serial_struct ss;
mm_segment_t oldseg = get_fs();
set_fs(KERNEL_DS);
if (cmd == TIOCSSERIAL) {
err = -EFAULT;
if (copy_from_user(&ss, ss32, sizeof(struct serial_struct32)))
goto out;
memmove(&ss.iomem_reg_shift, ((char*)&ss.iomem_base)+4,
sizeof(SS)-offsetof(SS,iomem_reg_shift));
ss.iomem_base = (void *)((unsigned long)ss.iomem_base & 0xffffffff);
}
if (!err)
err = sys_ioctl(fd,cmd,(unsigned long)(&ss));
if (cmd == TIOCGSERIAL && err >= 0) {
__u32 base;
if (__copy_to_user(ss32,&ss,offsetof(SS,iomem_base)) ||
__copy_to_user(&ss32->iomem_reg_shift,
&ss.iomem_reg_shift,
sizeof(SS) - offsetof(SS, iomem_reg_shift)))
err = -EFAULT;
if (ss.iomem_base > (unsigned char *)0xffffffff)
base = -1;
else
base = (unsigned long)ss.iomem_base;
err |= __put_user(base, &ss32->iomem_base);
}
out:
set_fs(oldseg);
return err;
}
struct ioctl_trans {
unsigned long cmd;
unsigned long handler;
int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
struct ioctl_trans *next;
};
/* generic function to change a single long put_user to arg to 32bit */
static int arg2long(unsigned int fd, unsigned int cmd, unsigned long arg)
{
int ret;
unsigned long val = 0;
mm_segment_t oldseg = get_fs();
set_fs(KERNEL_DS);
ret = sys_ioctl(fd, cmd, (unsigned long)&val);
set_fs(oldseg);
if (!ret || val) {
if (put_user((int)val, (unsigned int *)arg))
return -EFAULT;
}
return ret;
}
#define REF_SYMBOL(handler) if (0) (void)handler;
#define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler); asm volatile(".quad %c0, " #handler ",0"::"i" (cmd));
#define HANDLE_IOCTL(cmd,handler) HANDLE_IOCTL2(cmd,handler)
......@@ -2986,7 +3117,7 @@ struct ioctl_trans {
#define IOCTL_TABLE_END asm volatile("\nioctl_end:"); }
IOCTL_TABLE_START
/* List here exlicitly which ioctl's are known to have
/* List here explicitly which ioctl's are known to have
* compatable types passed or none at all...
*/
/* Big T */
......@@ -3002,6 +3133,7 @@ COMPATIBLE_IOCTL(TCSETS)
COMPATIBLE_IOCTL(TCSETSW)
COMPATIBLE_IOCTL(TCSETSF)
COMPATIBLE_IOCTL(TIOCLINUX)
HANDLE_IOCTL(TIOCGDEV, tiocgdev)
/* Little t */
COMPATIBLE_IOCTL(TIOCGETD)
COMPATIBLE_IOCTL(TIOCSETD)
......@@ -3025,8 +3157,6 @@ COMPATIBLE_IOCTL(TIOCGPGRP)
COMPATIBLE_IOCTL(TIOCSCTTY)
COMPATIBLE_IOCTL(TIOCGPTN)
COMPATIBLE_IOCTL(TIOCSPTLCK)
COMPATIBLE_IOCTL(TIOCGSERIAL)
COMPATIBLE_IOCTL(TIOCSSERIAL)
COMPATIBLE_IOCTL(TIOCSERGETLSR)
COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
......@@ -3082,6 +3212,8 @@ COMPATIBLE_IOCTL(BLKROSET)
COMPATIBLE_IOCTL(BLKROGET)
COMPATIBLE_IOCTL(BLKRRPART)
COMPATIBLE_IOCTL(BLKFLSBUF)
COMPATIBLE_IOCTL(BLKRASET)
COMPATIBLE_IOCTL(BLKFRASET)
COMPATIBLE_IOCTL(BLKSECTSET)
COMPATIBLE_IOCTL(BLKSSZGET)
......@@ -3203,7 +3335,7 @@ COMPATIBLE_IOCTL(RTC_RD_TIME)
COMPATIBLE_IOCTL(RTC_SET_TIME)
COMPATIBLE_IOCTL(RTC_WKALM_SET)
COMPATIBLE_IOCTL(RTC_WKALM_RD)
COMPATIBLE_IOCTL(RTC_IRQP_READ)
HANDLE_IOCTL(RTC_IRQP_READ,arg2long)
COMPATIBLE_IOCTL(RTC_IRQP_SET)
COMPATIBLE_IOCTL(RTC_EPOCH_READ)
COMPATIBLE_IOCTL(RTC_EPOCH_SET)
......@@ -3479,9 +3611,6 @@ COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE)
COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK)
/* Raw devices */
COMPATIBLE_IOCTL(RAW_SETBIND)
COMPATIBLE_IOCTL(RAW_GETBIND)
/* SMB ioctls which do not need any translations */
COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
/* Little a */
......@@ -3543,6 +3672,18 @@ COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)
COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
#endif /* DRM */
#ifdef CONFIG_AUTOFS_FS
COMPATIBLE_IOCTL(AUTOFS_IOC_READY);
COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL);
COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC);
COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER);
COMPATIBLE_IOCTL(AUTOFS_IOC_SETTIMEOUT);
COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE);
#endif
COMPATIBLE_IOCTL(REISERFS_IOC_UNPACK);
/* serial driver */
HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl);
HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl);
/* elevator */
COMPATIBLE_IOCTL(BLKELVGET)
COMPATIBLE_IOCTL(BLKELVSET)
......@@ -3589,6 +3730,8 @@ HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc)
HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl)
HANDLE_IOCTL(SIOCADDRT, routing_ioctl)
HANDLE_IOCTL(SIOCDELRT, routing_ioctl)
/* Raw devices */
HANDLE_IOCTL(RAW_SETBIND, raw_ioctl)
/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
HANDLE_IOCTL(SIOCRTMSG, ret_einval)
HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp)
......@@ -3751,14 +3894,14 @@ static struct ioctl_trans *additional_ioctls;
/* Always call these with kernel lock held! */
int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *))
{
int i;
if (!additional_ioctls) {
additional_ioctls = module_map(PAGE_SIZE);
additional_ioctls = (struct ioctl_trans *)get_zeroed_page(GFP_KERNEL);
if (!additional_ioctls)
return -ENOMEM;
memset(additional_ioctls, 0, PAGE_SIZE);
}
for (i = 0; i < PAGE_SIZE/sizeof(struct ioctl_trans); i++)
if (!additional_ioctls[i].cmd)
......@@ -3767,13 +3910,15 @@ int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, u
return -ENOMEM;
additional_ioctls[i].cmd = cmd;
if (!handler)
additional_ioctls[i].handler = (u32)(long)sys_ioctl;
additional_ioctls[i].handler =
(int (*)(unsigned,unsigned,unsigned long, struct file *))sys_ioctl;
else
additional_ioctls[i].handler = (u32)(long)handler;
additional_ioctls[i].handler = handler;
ioctl32_insert_translation(&additional_ioctls[i]);
return 0;
}
int unregister_ioctl32_conversion(unsigned int cmd)
{
unsigned long hash = ioctl32_hash(cmd);
......@@ -3799,6 +3944,9 @@ int unregister_ioctl32_conversion(unsigned int cmd)
return -EINVAL;
}
EXPORT_SYMBOL(register_ioctl32_conversion);
EXPORT_SYMBOL(unregister_ioctl32_conversion);
asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct file * filp;
......@@ -3820,7 +3968,7 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
while (t && t->cmd != cmd)
t = (struct ioctl_trans *)(long)t->next;
if (t) {
handler = (void *)(long)t->handler;
handler = t->handler;
error = handler(fd, cmd, arg, filp);
} else {
static int count = 0;
......
......@@ -7,7 +7,7 @@
* 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
* 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
*
* $Id: ia32_signal.c,v 1.15 2001/10/16 23:41:42 ak Exp $
* $Id: ia32_signal.c,v 1.17 2002/03/21 14:16:32 ak Exp $
*/
#include <linux/sched.h>
......@@ -29,6 +29,8 @@
#include <asm/ptrace.h>
#include <asm/ia32_unistd.h>
#include <asm/user32.h>
#include <asm/sigcontext32.h>
#include <asm/fpu32.h>
#define ptr_to_u32(x) ((u32)(u64)(x)) /* avoid gcc warning */
......@@ -147,7 +149,7 @@ struct rt_sigframe
};
static int
restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned int *peax)
ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned int *peax)
{
unsigned int err = 0;
......@@ -171,7 +173,13 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned in
/* Reload fs and gs if they have changed in the signal handler.
This does not handle long fs/gs base changes in the handler, but does not clobber
them at least in the normal case. */
RELOAD_SEG(gs);
{
unsigned short gs;
err |= __get_user(gs, &sc->gs);
load_gs_index(gs);
}
RELOAD_SEG(fs);
COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
......@@ -187,13 +195,13 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned in
{
u32 tmp;
struct _fpstate * buf;
struct _fpstate_ia32 * buf;
err |= __get_user(tmp, &sc->fpstate);
buf = (struct _fpstate *) (u64)tmp;
buf = (struct _fpstate_ia32 *) (u64)tmp;
if (buf) {
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387(buf);
err |= restore_i387_ia32(current, buf, 0);
}
}
......@@ -228,7 +236,7 @@ asmlinkage int sys32_sigreturn(struct pt_regs regs)
recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock);
if (restore_sigcontext(&regs, &frame->sc, &eax))
if (ia32_restore_sigcontext(&regs, &frame->sc, &eax))
goto badframe;
return eax;
......@@ -255,7 +263,7 @@ asmlinkage int sys32_rt_sigreturn(struct pt_regs regs)
recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock);
if (restore_sigcontext(&regs, &frame->uc.uc_mcontext, &eax))
if (ia32_restore_sigcontext(&regs, &frame->uc.uc_mcontext, &eax))
goto badframe;
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
......@@ -281,7 +289,7 @@ asmlinkage int sys32_rt_sigreturn(struct pt_regs regs)
*/
static int
setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
ia32_setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
struct pt_regs *regs, unsigned int mask)
{
int tmp, err = 0;
......@@ -306,7 +314,7 @@ setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
err |= __put_user((u32)regs->eflags, &sc->eflags);
err |= __put_user((u32)regs->rsp, &sc->esp_at_signal);
tmp = save_i387(fpstate);
tmp = save_i387_ia32(current, fpstate, regs, 0);
if (tmp < 0)
err = -EFAULT;
else
......@@ -351,23 +359,24 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
{
struct sigframe *frame;
int err = 0;
struct exec_domain *exec_domain = current_thread_info()->exec_domain;
frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
err |= __put_user((exec_domain
&& exec_domain->signal_invmap
&& sig < 32
? exec_domain->signal_invmap[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;
err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
if (err)
goto give_sigsegv;
......@@ -419,19 +428,19 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
{
struct rt_sigframe *frame;
int err = 0;
struct exec_domain *exec_domain = current_thread_info()->exec_domain;
frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
err |= __put_user((exec_domain
&& exec_domain->signal_invmap
&& sig < 32
? exec_domain->signal_invmap[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);
}
err |= __put_user((u32)(u64)&frame->info, &frame->pinfo);
err |= __put_user((u32)(u64)&frame->uc, &frame->puc);
err |= ia32_copy_siginfo_to_user(&frame->info, info);
......@@ -445,7 +454,7 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
err |= __put_user(sas_ss_flags(regs->rsp),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
......
/*
* Compatibility mode system call entry point for x86-64.
*
* Copyright 2000,2001,2002 Andi Kleen, SuSE Labs.
* Copyright 2000,2001 Andi Kleen, SuSE Labs.
*
* $Id: ia32entry.S,v 1.24 2001/11/11 17:47:47 ak Exp $
* $Id: ia32entry.S,v 1.31 2002/03/24 13:01:45 ak Exp $
*/
#include <asm/calling.h>
#include <asm/offset.h>
#include <asm/thread_info.h>
#include <asm/current.h>
#include <linux/linkage.h>
#include <asm/errno.h>
#include <asm/ia32_unistd.h>
#include <asm/thread_info.h>
.macro IA32_ARG_FIXUP
movl %edi,%r8d
......@@ -29,7 +30,7 @@
*/
ENTRY(ia32_cstar_target)
movq $-ENOSYS,%rax
SYSRET32
sysret
/*
* Emulated IA32 system calls via int 0x80.
......@@ -65,7 +66,6 @@ ia32_do_syscall:
cmpl $(IA32_NR_syscalls),%eax
jae ia32_badsys
IA32_ARG_FIXUP
movl $1,%r10d
call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
movq %rax,RAX-ARGOFFSET(%rsp)
jmp int_ret_from_sys_call
......@@ -106,7 +106,7 @@ ni_syscall:
PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend
ENTRY(ia32_ptregs_common)
popq %r11 /* save return address outside the stack frame. */
popq %r11
SAVE_REST
movq %r11, %r15
call *%rax
......@@ -241,14 +241,14 @@ ia32_sys_call_table:
.quad stub32_clone /* 120 */
.quad sys_setdomainname
.quad sys_newuname
.quad ni_syscall /* modify_ldt */
.quad sys_modify_ldt
.quad sys32_adjtimex
.quad sys_mprotect /* 125 */
.quad sys32_mprotect /* 125 */
.quad sys32_sigprocmask
.quad ni_syscall /* query_module */
.quad ni_syscall /* init_module */
.quad ni_syscall /* delete module */
.quad ni_syscall /* 130 get_kernel_syms */
.quad sys32_module_warning /* create_module */
.quad sys32_module_warning /* init_module */
.quad sys32_module_warning /* delete module */
.quad sys32_module_warning /* 130 get_kernel_syms */
.quad ni_syscall /* quotactl */
.quad sys_getpgid
.quad sys_fchdir
......@@ -287,7 +287,7 @@ ia32_sys_call_table:
.quad ni_syscall /* vm86 */
.quad ni_syscall /* query_module */
.quad sys_poll
.quad ni_syscall /* nfsserverctl */
.quad sys32_nfsservctl
.quad sys_setresgid16 /* 170 */
.quad sys_getresgid16
.quad sys_prctl
......@@ -302,8 +302,8 @@ ia32_sys_call_table:
.quad sys32_pwrite
.quad sys_chown16
.quad sys_getcwd
.quad ni_syscall /* capget */
.quad ni_syscall /* capset */
.quad sys_capget
.quad sys_capset
.quad stub32_sigaltstack
.quad sys32_sendfile
.quad ni_syscall /* streams1 */
......@@ -338,7 +338,7 @@ ia32_sys_call_table:
.quad sys_pivot_root
.quad sys_mincore
.quad sys_madvise
.quad sys_getdents64 /* 220 */
.quad sys_getdents64 /* 220 getdents64 */
.quad sys32_fcntl64
.quad sys_ni_syscall /* tux */
.quad sys_ni_syscall /* security */
......@@ -357,6 +357,10 @@ ia32_sys_call_table:
.quad sys_lremovexattr
.quad sys_fremovexattr
.quad sys_tkill /* 238 */
.quad sys_sendfile64
.quad sys_futex
.quad sys32_sched_setaffinity
.quad sys32_sched_getaffinity
ia32_syscall_end:
.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
.quad ni_syscall
......
/*
* 32bit ptrace for x86-64.
*
* Copyright 2001 Andi Kleen, SuSE Labs.
* Some parts copied from arch/i386/kernel/ptrace.c. See that file for
* earlier copyright.
* Copyright 2001,2002 Andi Kleen, SuSE Labs.
* Some parts copied from arch/i386/kernel/ptrace.c. See that file for earlier
* copyright.
*
* This allows to access 64bit processes too but there is no way to see
* the extended register contents.
* This allows to access 64bit processes too; but there is no way to see the extended
* register contents.
*
* $Id: ptrace32.c,v 1.2 2001/08/15 06:41:13 ak Exp $
* $Id: ptrace32.c,v 1.12 2002/03/24 13:02:02 ak Exp $
*/
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/ptrace.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>
#include <asm/user32.h>
#include <asm/user.h>
#include <asm/errno.h>
#include <asm/debugreg.h>
#include <asm/i387.h>
#include <asm/fpu32.h>
#include <linux/mm.h>
#define R32(l,q) \
case offsetof(struct user32, regs.l): stack[offsetof(struct pt_regs, q)/8] = val; break
......@@ -139,7 +141,6 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
#undef R32
static struct task_struct *find_target(int request, int pid, int *err)
{
struct task_struct *child;
......@@ -154,23 +155,11 @@ static struct task_struct *find_target(int request, int pid, int *err)
if (child)
get_task_struct(child);
read_unlock(&tasklist_lock);
if (child) {
*err = -ESRCH;
if (!(child->ptrace & PT_PTRACED))
goto out;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
goto out;
}
if (child->p_pptr != current)
goto out;
*err = ptrace_check_attach(child,0);
if (*err == 0)
return child;
}
out:
put_task_struct(child);
return NULL;
}
extern asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, unsigned long data);
......@@ -178,6 +167,7 @@ extern asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, un
asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
{
struct task_struct *child;
struct pt_regs *childregs;
int ret;
__u32 val;
......@@ -203,6 +193,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_SETREGS:
case PTRACE_SETFPREGS:
case PTRACE_GETFPREGS:
case PTRACE_SETFPXREGS:
case PTRACE_GETFPXREGS:
break;
default:
......@@ -213,11 +205,13 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
if (!child)
return ret;
childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs));
switch (request) {
case PTRACE_PEEKDATA:
case PTRACE_PEEKTEXT:
ret = 0;
if (access_process_vm(child, addr, &val, sizeof(u32), 0) != sizeof(u32))
if (access_process_vm(child, addr, &val, sizeof(u32), 0)!=sizeof(u32))
ret = -EIO;
else
ret = put_user(val, (unsigned int *)(u64)data);
......@@ -226,13 +220,13 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_POKEDATA:
case PTRACE_POKETEXT:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(u32), 1) != sizeof(u32))
if (access_process_vm(child, addr, &data, sizeof(u32), 1)!=sizeof(u32))
ret = -EIO;
break;
case PTRACE_PEEKUSR:
ret = getreg32(child, addr, &val);
if (ret >= 0)
if (ret == 0)
ret = put_user(val, (__u32 *)(unsigned long) data);
break;
......@@ -242,7 +236,7 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
int i;
if (!access_ok(VERIFY_WRITE, (unsigned *)(unsigned long)data, FRAME_SIZE)) {
if (!access_ok(VERIFY_WRITE, (unsigned *)(unsigned long)data, 16*4)) {
ret = -EIO;
break;
}
......@@ -258,10 +252,11 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
case PTRACE_SETREGS: { /* Set all gp regs in the child. */
unsigned long tmp;
int i;
if (!access_ok(VERIFY_READ, (unsigned *)(unsigned long)data, FRAME_SIZE)) {
if (!access_ok(VERIFY_READ, (unsigned *)(unsigned long)data, 16*4)) {
ret = -EIO;
break;
}
empty_fpu(child);
ret = 0;
for ( i = 0; i <= 16*4; i += sizeof(u32) ) {
ret |= __get_user(tmp, (u32 *) (unsigned long) data);
......@@ -271,35 +266,37 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
break;
}
#if 0 /* to be done. */
case PTRACE_GETFPREGS: { /* Get the child extended FPU state. */
if (!access_ok(VERIFY_WRITE, (unsigned *)data,
sizeof(struct user_i387_struct))) {
ret = -EIO;
case PTRACE_SETFPREGS:
empty_fpu(child);
save_i387_ia32(child, (void *)(u64)data, childregs, 1);
ret = 0;
break;
}
if ( !child->used_math ) {
/* Simulate an empty FPU. */
set_fpu_cwd(child, 0x037f);
set_fpu_swd(child, 0x0000);
set_fpu_twd(child, 0xffff);
set_fpu_mxcsr(child, 0x1f80);
}
ret = get_fpregs((struct user_i387_struct *)data, child);
case PTRACE_GETFPREGS:
empty_fpu(child);
restore_i387_ia32(child, (void *)(u64)data, 1);
ret = 0;
break;
}
case PTRACE_SETFPREGS: { /* Set the child extended FPU state. */
if (!access_ok(VERIFY_READ, (unsigned *)data,
sizeof(struct user_i387_struct))) {
ret = -EIO;
case PTRACE_GETFPXREGS: {
struct user32_fxsr_struct *u = (void *)(u64)data;
empty_fpu(child);
ret = copy_to_user(u, &child->thread.i387.fxsave, sizeof(*u));
ret |= __put_user(childregs->cs, &u->fcs);
ret |= __put_user(child->thread.ds, &u->fos);
if (ret)
ret = -EFAULT;
break;
}
case PTRACE_SETFPXREGS: {
struct user32_fxsr_struct *u = (void *)(u64)data;
empty_fpu(child);
/* no error checking to be bug to bug compatible with i386 */
copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u));
child->thread.i387.fxsave.mxcsr &= 0xffbf;
ret = 0;
break;
}
child->used_math = 1;
ret = set_fpregs(child, (struct user_i387_struct *)data);
break;
#endif
default:
ret = -EINVAL;
......
This diff is collapsed.
......@@ -19,8 +19,8 @@ export-objs := mtrr.o msr.o cpuid.o x8664_ksyms.o
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
pci-dma.o x8664_ksyms.o i387.o syscall.o early_printk.o vsyscall.o \
setup64.o bluesmoke.o
pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
setup64.o bluesmoke.o bootflag.o
ifdef CONFIG_PCI
obj-y += pci-x86_64.o
......@@ -33,6 +33,9 @@ obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o
#obj-$(CONFIG_ACPI) += acpi.o
#obj-$(CONFIG_ACPI_SLEEP) += acpi_wakeup.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
include $(TOPDIR)/Rules.make
......@@ -33,6 +33,8 @@
/* Using APIC to generate smp_local_timer_interrupt? */
int using_apic_timer = 0;
int dont_enable_local_apic __initdata = 0;
int prof_multiplier[NR_CPUS] = { 1, };
int prof_old_multiplier[NR_CPUS] = { 1, };
int prof_counter[NR_CPUS] = { 1, };
......@@ -51,7 +53,7 @@ int get_maxlvt(void)
void clear_local_APIC(void)
{
int maxlvt;
unsigned long v;
unsigned int v;
maxlvt = get_maxlvt();
......@@ -90,7 +92,7 @@ void clear_local_APIC(void)
apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
v = GET_APIC_VERSION(apic_read(APIC_LVR));
if (APIC_INTEGRATED(v)) { /* !82489DX */
if (maxlvt > 3)
if (maxlvt > 3) /* Due to Pentium errata 3AP and 11AP. */
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
}
......@@ -130,7 +132,7 @@ void disconnect_bsp_APIC(void)
void disable_local_APIC(void)
{
unsigned long value;
unsigned int value;
clear_local_APIC();
......@@ -223,7 +225,7 @@ extern void __error_in_apic_c (void);
*/
void __init init_bsp_APIC(void)
{
unsigned long value, ver;
unsigned int value, ver;
/*
* Don't do the setup now if we have a SMP BIOS as the
......@@ -262,7 +264,7 @@ void __init init_bsp_APIC(void)
void __init setup_local_APIC (void)
{
unsigned long value, ver, maxlvt;
unsigned int value, ver, maxlvt;
/* Pound the ESR really hard over the head with a big hammer - mbligh */
if (esr_disable) {
......@@ -395,7 +397,7 @@ void __init setup_local_APIC (void)
if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
apic_write(APIC_ESR, 0);
value = apic_read(APIC_ESR);
printk("ESR value before enabling vector: %08lx\n", value);
printk("ESR value before enabling vector: %08x\n", value);
value = ERROR_APIC_VECTOR; // enables sending errors
apic_write_around(APIC_LVTERR, value);
......@@ -405,7 +407,7 @@ void __init setup_local_APIC (void)
if (maxlvt > 3)
apic_write(APIC_ESR, 0);
value = apic_read(APIC_ESR);
printk("ESR value after enabling vector: %08lx\n", value);
printk("ESR value after enabling vector: %08x\n", value);
} else {
if (esr_disable)
/*
......@@ -449,6 +451,7 @@ static struct {
unsigned int apic_lvterr;
unsigned int apic_tmict;
unsigned int apic_tdcr;
unsigned int apic_thmr;
} apic_pm_state;
static void apic_pm_suspend(void *data)
......@@ -470,6 +473,7 @@ static void apic_pm_suspend(void *data)
apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
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);
__save_flags(flags);
__cli();
disable_local_APIC();
......@@ -498,6 +502,7 @@ static void apic_pm_resume(void *data)
apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
......@@ -586,7 +591,6 @@ static inline void apic_pm_init2(void) { }
static int __init detect_init_APIC (void)
{
u32 h, l, features;
int needs_pm = 0;
extern void get_cpu_vendor(struct cpuinfo_x86*);
/* Workaround for us being called before identify_cpu(). */
......@@ -619,7 +623,6 @@ static int __init detect_init_APIC (void)
l &= ~MSR_IA32_APICBASE_BASE;
l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
wrmsr(MSR_IA32_APICBASE, l, h);
needs_pm = 1;
}
}
/*
......@@ -631,17 +634,13 @@ static int __init detect_init_APIC (void)
printk("Could not enable APIC!\n");
return -1;
}
set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability);
set_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
boot_cpu_id = 0;
if (nmi_watchdog != NMI_NONE)
nmi_watchdog = NMI_LOCAL_APIC;
printk("Found and enabled local APIC!\n");
if (needs_pm)
apic_pm_init1();
return 0;
no_apic:
......@@ -782,7 +781,7 @@ void __setup_APIC_LVTT(unsigned int clocks)
void setup_APIC_timer(void * data)
{
unsigned long clocks = (unsigned long) data, slice, t0, t1;
unsigned int clocks = (unsigned long) data, slice, t0, t1;
unsigned long flags;
int delta;
......@@ -799,7 +798,8 @@ void setup_APIC_timer(void * data)
*/
slice = clocks / (smp_num_cpus+1);
printk("cpu: %d, clocks: %lu, slice: %lu\n", smp_processor_id(), clocks, slice);
printk("cpu: %d, clocks: %d, slice: %d\n",
smp_processor_id(), clocks, slice);
/*
* Wait for IRQ0's slice:
......@@ -822,7 +822,8 @@ void setup_APIC_timer(void * data)
__setup_APIC_LVTT(clocks);
printk("CPU%d<T0:%lu,T1:%lu,D:%d,S:%lu,C:%lu>\n", smp_processor_id(), t0, t1, delta, slice, clocks);
printk("CPU%d<T0:%u,T1:%u,D:%d,S:%u,C:%u>\n",
smp_processor_id(), t0, t1, delta, slice, clocks);
__restore_flags(flags);
}
......@@ -842,9 +843,9 @@ void setup_APIC_timer(void * data)
int __init calibrate_APIC_clock(void)
{
unsigned long long t1 = 0, t2 = 0;
long tt1, tt2;
long result;
unsigned long t1 = 0, t2 = 0;
int tt1, tt2;
int result;
int i;
const int LOOPS = HZ/10;
......@@ -892,19 +893,23 @@ int __init calibrate_APIC_clock(void)
result = (tt1-tt2)*APIC_DIVISOR/LOOPS;
printk("t1 = %ld t2 = %ld tt1 = %d tt2 = %d\n", t1, t2, tt1, tt2);
if (cpu_has_tsc)
printk("..... CPU clock speed is %ld.%04ld MHz.\n",
((long)(t2-t1)/LOOPS)/(1000000/HZ),
((long)(t2-t1)/LOOPS)%(1000000/HZ));
printk("..... CPU clock speed is %d.%04d MHz.\n",
((int)(t2-t1)/LOOPS)/(1000000/HZ),
((int)(t2-t1)/LOOPS)%(1000000/HZ));
printk("..... host bus clock speed is %ld.%04ld MHz.\n",
printk("..... host bus clock speed is %d.%04d MHz.\n",
result/(1000000/HZ),
result%(1000000/HZ));
return result;
}
static unsigned long calibration_result;
static unsigned int calibration_result;
void __init setup_APIC_clocks (void)
{
......@@ -917,12 +922,12 @@ void __init setup_APIC_clocks (void)
/*
* Now set up the timer for real.
*/
setup_APIC_timer((void *)calibration_result);
setup_APIC_timer((void *)(u64)calibration_result);
__sti();
/* and update all other cpus */
smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1);
smp_call_function(setup_APIC_timer, (void *)(u64)calibration_result, 1, 1);
}
void __init disable_APIC_timer(void)
......@@ -985,7 +990,7 @@ int setup_profiling_timer(unsigned int multiplier)
* value into /proc/profile.
*/
inline void smp_local_timer_interrupt(struct pt_regs * regs)
inline void smp_local_timer_interrupt(struct pt_regs *regs)
{
int user = user_mode(regs);
int cpu = smp_processor_id();
......@@ -1041,7 +1046,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs)
*/
unsigned int apic_timer_irqs [NR_CPUS];
void smp_apic_timer_interrupt(struct pt_regs regs)
void smp_apic_timer_interrupt(struct pt_regs *regs)
{
int cpu = smp_processor_id();
......@@ -1061,7 +1066,7 @@ void smp_apic_timer_interrupt(struct pt_regs regs)
* interrupt lock, which is the WrongThing (tm) to do.
*/
irq_enter(cpu, 0);
smp_local_timer_interrupt(&regs);
smp_local_timer_interrupt(regs);
irq_exit(cpu, 0);
if (softirq_pending(cpu))
......@@ -1073,7 +1078,9 @@ void smp_apic_timer_interrupt(struct pt_regs regs)
*/
asmlinkage void smp_spurious_interrupt(void)
{
unsigned long v;
unsigned int v;
static unsigned long last_warning;
static unsigned long skipped;
/*
* Check if this really is a spurious interrupt and ACK it
......@@ -1085,8 +1092,13 @@ asmlinkage void smp_spurious_interrupt(void)
ack_APIC_irq();
/* see sw-dev-man vol 3, chapter 7.4.13.5 */
printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n",
smp_processor_id());
if (last_warning+30*HZ < jiffies) {
printk(KERN_INFO "spurious APIC interrupt on CPU#%d, %ld skipped.\n",
smp_processor_id(), skipped);
last_warning = jiffies;
} else {
skipped++;
}
}
/*
......@@ -1095,7 +1107,7 @@ asmlinkage void smp_spurious_interrupt(void)
asmlinkage void smp_error_interrupt(void)
{
unsigned long v, v1;
unsigned int v, v1;
/* First tickle the hardware, only then report what went on. -- REW */
v = apic_read(APIC_ESR);
......@@ -1114,7 +1126,7 @@ asmlinkage void smp_error_interrupt(void)
6: Received illegal vector
7: Illegal register address
*/
printk (KERN_ERR "APIC error on CPU%d: %02lx(%02lx)\n",
printk (KERN_ERR "APIC error on CPU%d: %02x(%02x)\n",
smp_processor_id(), v , v1);
}
......
......@@ -3,16 +3,127 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/config.h>
#include <linux/irq.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/msr.h>
#include <asm/apic.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
static int mce_disabled __initdata = 0;
static int banks;
/*
* Machine Check Handler For PII/PIII/K7
* If we get an MCE, we don't know what state the caches/TLB's are
* going to be in, so we throw them all away.
*/
static void inline flush_all (void)
{
__asm__ __volatile__ ("invd": : );
__flush_tlb();
}
static int banks;
/*
* P4/Xeon Thermal transition interrupt handler
*/
static void intel_thermal_interrupt(struct pt_regs *regs)
{
#ifdef CONFIG_X86_LOCAL_APIC
u32 l, h;
unsigned int cpu = smp_processor_id();
ack_APIC_irq();
rdmsr(MSR_IA32_THERM_STATUS, l, h);
if (l & 1) {
printk(KERN_EMERG "CPU#%d: Temperature above threshold\n", cpu);
printk(KERN_EMERG "CPU#%d: Running in modulated clock mode\n", cpu);
} else {
printk(KERN_INFO "CPU#%d: Temperature/speed normal\n", cpu);
}
#endif
}
static void unexpected_thermal_interrupt(struct pt_regs *regs)
{
printk(KERN_ERR "CPU#%d: Unexpected LVT TMR interrupt!\n", smp_processor_id());
}
/*
* Thermal interrupt handler for this CPU setup
*/
static void (*vendor_thermal_interrupt)(struct pt_regs *regs) = unexpected_thermal_interrupt;
asmlinkage void smp_thermal_interrupt(struct pt_regs regs)
{
vendor_thermal_interrupt(&regs);
}
/* P4/Xeon Thermal regulation detect and init */
static void __init intel_init_thermal(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_X86_LOCAL_APIC
u32 l, h;
unsigned int cpu = smp_processor_id();
/* Thermal monitoring */
if (!test_bit(X86_FEATURE_ACPI, &c->x86_capability))
return; /* -ENODEV */
/* Clock modulation */
if (!test_bit(X86_FEATURE_ACC, &c->x86_capability))
return; /* -ENODEV */
rdmsr(MSR_IA32_MISC_ENABLE, l, h);
/* first check if its enabled already, in which case there might
* be some SMM goo which handles it, so we can't even put a handler
* since it might be delivered via SMI already -zwanem.
*/
if (l & (1<<3)) {
printk(KERN_DEBUG "CPU#%d: Thermal monitoring already enabled\n", cpu);
} else {
wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h);
printk(KERN_INFO "CPU#%d: Thermal monitoring enabled\n", cpu);
}
/* check wether a vector already exists */
l = apic_read(APIC_LVTTHMR);
if (l & 0xff) {
printk(KERN_DEBUG "CPU#%d: Thermal LVT already handled\n", cpu);
return; /* -EBUSY */
}
wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h);
printk(KERN_INFO "CPU#%d: Thermal monitoring enabled\n", cpu);
/* The temperature transition interrupt handler setup */
l = THERMAL_APIC_VECTOR; /* our delivery vector */
l |= (APIC_DM_FIXED | APIC_LVT_MASKED); /* we'll mask till we're ready */
apic_write_around(APIC_LVTTHMR, l);
rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x3 , h);
/* ok we're good to go... */
vendor_thermal_interrupt = intel_thermal_interrupt;
l = apic_read(APIC_LVTTHMR);
apic_write_around(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
return;
#endif
}
/*
* Machine Check Handler For PII/PIII
*/
static void intel_machine_check(struct pt_regs * regs, long error_code)
{
......@@ -21,6 +132,8 @@ static void intel_machine_check(struct pt_regs * regs, long error_code)
u32 mcgstl, mcgsth;
int i;
flush_all();
rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
if(mcgstl&(1<<0)) /* Recoverable ? */
recover=0;
......@@ -41,13 +154,12 @@ static void intel_machine_check(struct pt_regs * regs, long error_code)
if(high&(1<<27))
{
rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
printk("[%08x%08x]", alow, ahigh);
printk("[%08x%08x]", ahigh, alow);
}
if(high&(1<<26))
{
rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
printk(" at %08x%08x",
ahigh, alow);
printk(" at %08x%08x", ahigh, alow);
}
printk("\n");
/* Clear it */
......@@ -66,9 +178,13 @@ static void intel_machine_check(struct pt_regs * regs, long error_code)
wrmsr(MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
}
static void unexpected_machine_check(struct pt_regs *regs, long error_code)
/*
* Handle unconfigured int18 (should never happen)
*/
static void unexpected_machine_check(struct pt_regs * regs, long error_code)
{
printk("unexpected machine check %lx\n", error_code);
printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id());
}
/*
......@@ -77,13 +193,60 @@ static void unexpected_machine_check(struct pt_regs *regs, long error_code)
static void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
void do_machine_check(struct pt_regs * regs, long error_code)
asmlinkage void do_machine_check(struct pt_regs * regs, long error_code)
{
machine_check_vector(regs, error_code);
}
#ifdef CONFIG_X86_MCE_NONFATAL
struct timer_list mce_timer;
static void mce_checkregs (unsigned int cpu)
{
u32 low, high;
int i;
if (cpu!=smp_processor_id())
BUG();
for (i=0; i<banks; i++) {
rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
if ((low | high) != 0) {
flush_all();
printk (KERN_EMERG "MCE: The hardware reports a non fatal, correctable incident occured on CPU %d.\n", smp_processor_id());
printk (KERN_EMERG "Bank %d: %08x%08x\n", i, high, low);
/* Scrub the error so we don't pick it up in 5 seconds time. */
wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
/* Serialize */
wmb();
}
}
/* Refresh the timer. */
mce_timer.expires = jiffies + 5 * HZ;
add_timer (&mce_timer);
}
static void mce_timerfunc (unsigned long data)
{
int i;
for (i=0; i<smp_num_cpus; i++) {
if (i == smp_processor_id())
mce_checkregs(i);
else
smp_call_function (mce_checkregs, i, 1, 1);
}
}
#endif
/*
* Set up machine check reporting for Intel processors
* Set up machine check reporting for processors with Intel style MCE
*/
static void __init intel_mcheck_init(struct cpuinfo_x86 *c)
......@@ -96,14 +259,14 @@ static void __init intel_mcheck_init(struct cpuinfo_x86 *c)
* Check for MCE support
*/
if( !test_bit(X86_FEATURE_MCE, &c->x86_capability) )
if( !test_bit(X86_FEATURE_MCE, c->x86_capability) )
return;
/*
* Check for PPro style MCA
*/
if( !test_bit(X86_FEATURE_MCA, &c->x86_capability) )
if( !test_bit(X86_FEATURE_MCA, c->x86_capability) )
return;
/* Ok machine check is available */
......@@ -114,19 +277,27 @@ static void __init intel_mcheck_init(struct cpuinfo_x86 *c)
if(done==0)
printk(KERN_INFO "Intel machine check architecture supported.\n");
rdmsr(MSR_IA32_MCG_CAP, l, h);
if(l&(1<<8))
if(l&(1<<8)) /* Control register present ? */
wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
banks = l&0xff;
for(i=1;i<banks;i++)
{
/* Don't enable bank 0 on intel P6 cores, it goes bang quickly. */
if (c->x86_vendor == X86_VENDOR_INTEL && c->x86 == 6) {
for(i=1; i<banks; i++)
wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
} else {
for(i=0; i<banks; i++)
wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
}
for(i=0;i<banks;i++)
{
for(i=0; i<banks; i++)
wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
}
set_in_cr4(X86_CR4_MCE);
printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());
intel_init_thermal(c);
done=1;
}
......@@ -134,8 +305,6 @@ static void __init intel_mcheck_init(struct cpuinfo_x86 *c)
* This has to be run for each processor
*/
void __init mcheck_init(struct cpuinfo_x86 *c)
{
if(mce_disabled==1)
......@@ -144,15 +313,23 @@ void __init mcheck_init(struct cpuinfo_x86 *c)
switch(c->x86_vendor)
{
case X86_VENDOR_AMD:
/*
* AMD K7 machine check is Intel like
*/
if(c->x86 == 6)
if(c->x86 == 6 || c->x86 == 15) {
intel_mcheck_init(c);
#ifdef CONFIG_X86_MCE_NONFATAL
/* Set the timer to check for non-fatal errors every 5 seconds */
init_timer (&mce_timer);
mce_timer.expires = jiffies + 5 * HZ;
mce_timer.data = 0;
mce_timer.function = &mce_timerfunc;
add_timer (&mce_timer);
#endif
}
break;
case X86_VENDOR_INTEL:
intel_mcheck_init(c);
break;
default:
break;
}
......
/*
* Implement 'Simple Boot Flag Specification 1.0'
*
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <asm/io.h>
#include <linux/mc146818rtc.h>
#define SBF_RESERVED (0x78)
#define SBF_PNPOS (1<<0)
#define SBF_BOOTING (1<<1)
#define SBF_DIAG (1<<2)
#define SBF_PARITY (1<<7)
struct sbf_boot
{
u8 sbf_signature[4];
u32 sbf_len;
u8 sbf_revision __attribute((packed));
u8 sbf_csum __attribute((packed));
u8 sbf_oemid[6] __attribute((packed));
u8 sbf_oemtable[8] __attribute((packed));
u8 sbf_revdata[4] __attribute((packed));
u8 sbf_creator[4] __attribute((packed));
u8 sbf_crearev[4] __attribute((packed));
u8 sbf_cmos __attribute((packed));
u8 sbf_spare[3] __attribute((packed));
};
static int sbf_port __initdata = -1;
static int __init sbf_struct_valid(unsigned long tptr)
{
u8 *ap;
u8 v;
unsigned int i;
struct sbf_boot sb;
memcpy_fromio(&sb, tptr, sizeof(sb));
if(sb.sbf_len != 40 && sb.sbf_len != 39)
// 39 on IBM ThinkPad A21m, BIOS version 1.02b (KXET24WW; 2000-12-19).
return 0;
ap = (u8 *)&sb;
v= 0;
for(i=0;i<sb.sbf_len;i++)
v+=*ap++;
if(v)
return 0;
if(memcmp(sb.sbf_signature, "BOOT", 4))
return 0;
if (sb.sbf_len == 39)
printk (KERN_WARNING "SBF: ACPI BOOT descriptor is wrong length (%d)\n",
sb.sbf_len);
sbf_port = sb.sbf_cmos; /* Save CMOS port */
return 1;
}
static int __init parity(u8 v)
{
int x = 0;
int i;
for(i=0;i<8;i++)
{
x^=(v&1);
v>>=1;
}
return x;
}
static void __init sbf_write(u8 v)
{
unsigned long flags;
if(sbf_port != -1)
{
v &= ~SBF_PARITY;
if(!parity(v))
v|=SBF_PARITY;
printk(KERN_INFO "SBF: Setting boot flags 0x%x\n",v);
spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(v, sbf_port);
spin_unlock_irqrestore(&rtc_lock, flags);
}
}
static u8 __init sbf_read(void)
{
u8 v;
unsigned long flags;
if(sbf_port == -1)
return 0;
spin_lock_irqsave(&rtc_lock, flags);
v = CMOS_READ(sbf_port);
spin_unlock_irqrestore(&rtc_lock, flags);
return v;
}
static int __init sbf_value_valid(u8 v)
{
if(v&SBF_RESERVED) /* Reserved bits */
return 0;
if(!parity(v))
return 0;
return 1;
}
static void __init sbf_bootup(void)
{
u8 v;
if(sbf_port == -1)
return;
v = sbf_read();
if(!sbf_value_valid(v))
printk(KERN_WARNING "SBF: Simple boot flag value 0x%x read from CMOS RAM was invalid\n",v);
v &= ~SBF_RESERVED;
v &= ~SBF_BOOTING;
v &= ~SBF_DIAG;
#if defined(CONFIG_ISAPNP)
v |= SBF_PNPOS;
#endif
sbf_write(v);
}
static int __init sbf_init(void)
{
unsigned int i;
void *rsdt;
u32 rsdtlen = 0;
u32 rsdtbase = 0;
u8 sum = 0;
int n;
u8 *p;
for(i=0xE0000; i <= 0xFFFE0; i+=16)
{
p = phys_to_virt(i);
if(memcmp(p, "RSD PTR ", 8))
continue;
sum = 0;
for(n=0; n<20; n++)
sum+=p[n];
if(sum != 0)
continue;
/* So it says RSD PTR and it checksums... */
/*
* Process the RDSP pointer
*/
rsdtbase = *(u32 *)(p+16);
/*
* RSDT length is ACPI 2 only, for ACPI 1 we must map
* and remap.
*/
if(p[15]>1)
rsdtlen = *(u32 *)(p+20);
else
rsdtlen = 36;
if(rsdtlen < 36 || rsdtlen > 1024)
continue;
break;
}
if(i>0xFFFE0)
return 0;
rsdt = ioremap(rsdtbase, rsdtlen);
if(rsdt == 0)
return 0;
i = readl(rsdt + 4);
/*
* Remap if needed
*/
if(i > rsdtlen)
{
rsdtlen = i;
iounmap(rsdt);
rsdt = ioremap(rsdtbase, rsdtlen);
if(rsdt == 0)
return 0;
}
for(n = 0; n < i; n++)
sum += readb(rsdt + n);
if(sum)
{
iounmap(rsdt);
return 0;
}
/* Ok the RSDT checksums too */
for(n = 36; n+3 < i; n += 4)
{
unsigned long rp = readl(rsdt+n);
int len = 4096;
if(rp > 0xFFFFFFFFUL - len)
len = 0xFFFFFFFFUL - rp;
/* Too close to the end!! */
if(len < 20)
continue;
rp = (unsigned long)ioremap(rp, 4096);
if(rp == 0)
continue;
if(sbf_struct_valid(rp))
{
/* Found the BOOT table and processed it */
printk(KERN_INFO "SBF: Simple Boot Flag extension found and enabled.\n");
}
iounmap((void *)rp);
}
iounmap(rsdt);
sbf_bootup();
return 0;
}
module_init(sbf_init);
......@@ -35,6 +35,7 @@
#include <linux/poll.h>
#include <linux/smp.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
......
#define printk real_printk
#include <asm/io.h>
#undef printk
/* This is "wrong" address to access it, we should access it using
0xffff8000000b8000ul; but 0xffff8000000b8000ul is not available
early at boot. */
#define VGABASE 0xffffffff800b8000ul
#define VGABASE 0xffffffff800b8000ul /* This is "wrong" address to access it, we should access it using 0xffff8000000b8000ul; but 0xffff8000000b8000ul is not available early at boot. */
#define MAX_YPOS 25
#define MAX_XPOS 80
......@@ -62,6 +62,8 @@ early_puts (const char *str)
static char buf[1024];
int printk(const char *fmt, ...) __attribute__((alias("early_printk")));
int early_printk(const char *fmt, ...)
{
va_list args;
......
This diff is collapsed.
......@@ -4,29 +4,30 @@
* Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
* Copyright (C) 2000 Pavel Machek <pavel@suse.cz>
* Copyright (C) 2000 Karsten Keil <kkeil@suse.de>
* Copyright (C) 2001 2002 Andi Kleen <ak@suse.de>
* Copyright (C) 2001,2002 Andi Kleen <ak@suse.de>
*
* $Id: head.S,v 1.41 2001/07/05 23:43:45 ak Exp $
* $Id: head.S,v 1.49 2002/03/19 17:39:25 ak Exp $
*/
.code64
.text
#include <linux/linkage.h>
#include <linux/threads.h>
#include <asm/desc.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/offset.h>
#include <asm/msr.h>
/* we don't able to switch in one step to final KERNEL ADDRESS SPACE
/* we are not able to switch in one step to the final KERNEL ADRESS SPACE
* because we need identity-mapped pages on setup so define __START_KERNEL to
* 0x100000 for this stage
*
*/
.text
.code32
/* %bx: 1 if comming from smp trampoline on secondary cpu */
startup_32:
.code32
/*
* At this point the CPU runs in 32bit protected mode (CS.D = 1) with
* paging disabled and the point of this file is to switch to 64bit
......@@ -35,7 +36,9 @@ startup_32:
* There is no stack until we set one up.
*/
/* As first check if extended functions are implemented */
movl %ebx,%ebp /* Save trampoline flag */
/* First check if extended functions are implemented */
movl $0x80000000, %eax
cpuid
cmpl $0x80000000, %eax
......@@ -46,6 +49,8 @@ startup_32:
btl $29, %edx
jnc no_long_mode
movl %edx,%edi
/*
* Prepare for entering 64bits mode
*/
......@@ -61,14 +66,23 @@ startup_32:
movl %eax, %cr3
/* Setup EFER (Extended Feature Enable Register) */
movl $0xc0000080, %ecx
movl $MSR_EFER, %ecx
rdmsr
/* Fool rdmsr and reset %eax to avoid dependences */
xorl %eax, %eax
/* Enable Long Mode */
btsl $8, %eax
btsl $_EFER_LME, %eax
/* Enable System Call */
btsl $0, %eax
btsl $_EFER_SCE, %eax
#if 0
/* No Execute supported? */
btl $20,%edi
jnc 1f
btsl $_EFER_NX, %eax
1:
#endif
/* Make changes effective */
wrmsr
......@@ -99,27 +113,37 @@ reach_compatibility_mode:
* the new gdt/idt that has __KERNEL_CS with CS.L = 1.
*/
testw %bp,%bp /* secondary CPU? */
jnz second
/* Load new GDT with the 64bit segment using 32bit descriptor */
/* to avoid 32bit relocations we use fixed adresses here */
movl $0x100F00, %eax
lgdt (%eax)
movl $0x100F10, %eax
/* Finally jump in 64bit mode */
ljmp *(%eax)
.code64
reach_long64:
/*
* Where we're running at 0x0000000000100000, and yes, finally
* in 64bit mode.
*/
.globl init_rsp
second:
/* abuse syscall to get into 64bit mode. this way we don't need
a working low identity mapping just for the short 32bit roundtrip.
XXX kludge. this should not be needed. */
movl $MSR_STAR,%ecx
xorl %eax,%eax
movl $(__USER32_CS<<16)|__KERNEL_CS,%edx
wrmsr
/* Setup the first kernel stack (this instruction is modified by smpboot) */
.byte 0x48, 0xb8 /* movq *init_rsp,%rax */
init_rsp:
.quad init_thread_union+THREAD_SIZE
movq %rax, %rsp
movl $MSR_CSTAR,%ecx
movl $0xffffffff,%edx
movl $0x80100100,%eax # reach_long64 absolute
wrmsr
syscall
.code64
.org 0x100
reach_long64:
movq init_rsp(%rip),%rsp
/* zero EFLAGS after setting rsp */
pushq $0
......@@ -133,15 +157,15 @@ init_rsp:
*/
lgdt pGDT64
/* esi is pointer to real mode structure with interesting info.
pass it to C */
movl %esi, %edi
movl $__KERNEL_DS,%eax
movl %eax,%ss
movl %eax,%ds
movl %eax,%ss
movl %eax,%es
/* esi is pointer to real mode structure with interesting info.
pass it to C */
movl %esi, %edi
/* 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
......@@ -150,11 +174,14 @@ init_rsp:
movq initial_code(%rip),%rax
jmp *%rax
/* SMP bootup changes this */
/* SMP bootup changes these two */
.globl initial_code
initial_code:
.quad x86_64_start_kernel
.globl init_rsp
init_rsp:
.quad init_thread_union+THREAD_SIZE-8
.code32
ENTRY(no_long_mode)
......@@ -165,7 +192,7 @@ ENTRY(no_long_mode)
.org 0xf00
pGDT32:
.word gdt32_end-gdt_table32
.quad gdt_table32-__START_KERNEL+0x100000
.long gdt_table32-__START_KERNEL+0x100000
.org 0xf10
ljumpvector:
......@@ -182,10 +209,9 @@ ENTRY(_stext)
* 2Mbyte large pages provided by PAE mode)
*/
.org 0x1000
ENTRY(level4_pgt)
ENTRY(init_level4_pgt)
.quad 0x0000000000102007 /* -> level3_ident_pgt */
.fill 255,8,0
/* __PAGE_OFFSET 0xffff800000000000 */
.quad 0x000000000010a007
.fill 254,8,0
/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
......@@ -193,7 +219,6 @@ ENTRY(level4_pgt)
.org 0x2000
/* Kernel does not "know" about 4-th level of page tables. */
ENTRY(swapper_pg_dir)
ENTRY(level3_ident_pgt)
.quad 0x0000000000104007
.fill 511,8,0
......@@ -207,10 +232,8 @@ ENTRY(level3_kernel_pgt)
.org 0x4000
ENTRY(level2_ident_pgt)
/* 2 Mbytes are enough, this is necessary only for head.S */
/* 40MB for bootup. */
.quad 0x0000000000000283
/* .fill 511,8,0 */
/* Jan needs more than 2Mbytes, so set a 40Mbyte mapping instead */
.quad 0x0000000000200183
.quad 0x0000000000400183
.quad 0x0000000000600183
......@@ -230,10 +253,15 @@ ENTRY(level2_ident_pgt)
.quad 0x0000000002200183
.quad 0x0000000002400183
.quad 0x0000000002600183
/* Temporary mappings for the super early allocator in arch/x86_64/mm/init.c */
.globl temp_boot_pmds
temp_boot_pmds:
.fill 492,8,0
.org 0x5000
ENTRY(level2_kernel_pgt)
/* 40MB kernel mapping. The kernel code cannot be bigger than that.
When you change this change KERNEL_TEXT_SIZE in pgtable.h too. */
/* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */
.quad 0x0000000000000183
.quad 0x0000000000200183
......@@ -255,11 +283,7 @@ ENTRY(level2_kernel_pgt)
.quad 0x0000000002200183
.quad 0x0000000002400183
.quad 0x0000000002600183
/*
* We could go ahead without any downside (except typing programmer
* wise :) but 40Mbyte are just enough for the kernel statically
* linked part (and extending it is trivial).
*/
/* Module mapping starts here */
.fill 492,8,0
.org 0x6000
......@@ -278,11 +302,7 @@ ENTRY(empty_bad_pmd_table)
ENTRY(level3_physmem_pgt)
.quad 0x0000000000105007 /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */
.org 0xb000
.data
.globl SYMBOL_NAME(gdt)
......@@ -317,16 +337,17 @@ ENTRY(gdt_table)
.quad 0x00cffe000000ffff /* __USER32_CS */
.quad 0x00cff2000000ffff /* __USER_DS, __USER32_DS */
.quad 0x00affa000000ffff /* __USER_CS */
.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 # base address = 0
.word 0x9A00 # code read/exec
.word 0x00CF # granularity = 4096, 386
# (+5th nibble of limit)
/* __KERNEL32_CS */
.globl tss_start
tss_start:
.rept NR_CPUS
.quad 0,0 /* TSS descriptors. filled in later */
.endr
.globl ldt_start
ldt_start:
.rept NR_CPUS
.quad 0,0 /* LDT descriptors. filled in later */
.quad 0,0,0,0,0,0,0,0 /* TSS/LDT/per cpu entries. filled in later */
.endr
gdt_end:
.globl gdt_end
......@@ -337,6 +358,3 @@ ENTRY(idt_table)
.quad 0
.quad 0
.endr
.section .text.lock
ENTRY(stext_lock)
......@@ -64,7 +64,7 @@ static void __init setup_boot_cpu_data(void)
(int *)&boot_cpu_data.x86_vendor_id[4]);
/* get cpu type */
cpuid(1, &eax, &dummy, &dummy, &boot_cpu_data.x86_capability[0]);
cpuid(1, &eax, &dummy, &dummy, (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;
......
This diff is collapsed.
This diff is collapsed.
......@@ -7,7 +7,6 @@
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/desc.h>
#include <asm/thread_info.h>
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
......@@ -15,7 +14,7 @@ static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM(init_mm);
/*
* Initial thread structure.
* Initial task structure.
*
* We need to make sure that this is 8192-byte aligned due to the
* way process stacks are handled. This is done by having a special
......@@ -39,4 +38,9 @@ struct task_struct init_task = INIT_TASK(init_task);
* section. Since TSS's are completely CPU-local, we want them
* on exact cacheline boundaries, to eliminate cacheline ping-pong.
*/
struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS };
struct tss_struct init_tss[NR_CPUS] __cacheline_aligned;
#define ALIGN_TO_4K __attribute__((section(".data.init_task")))
pgd_t boot_vmalloc_pgt[512] ALIGN_TO_4K;
......@@ -67,7 +67,7 @@ static struct irq_pin_list {
* shared ISA-space IRQs, so we have to support them. We are super
* fast in the common case, and fast for shared ISA-space IRQs.
*/
static void add_pin_to_irq(unsigned int irq, int apic, int pin)
static void __init add_pin_to_irq(unsigned int irq, int apic, int pin)
{
static int first_free_entry = NR_IRQS;
struct irq_pin_list *entry = irq_2_pin + irq;
......
......@@ -354,7 +354,7 @@ static inline void get_irqlock(int cpu)
*/
void __global_cli(void)
{
unsigned int flags;
unsigned long flags;
__save_flags(flags);
if (flags & (1 << EFLAGS_IF_SHIFT)) {
......@@ -570,12 +570,14 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
* 0 return value means that this irq is already being
* handled by some other CPU. (or is disabled)
*/
int irq = regs->orig_rax & 0xff; /* high bits used in ret_from_ code */
unsigned irq = regs->orig_rax & 0xff; /* high bits used in ret_from_ code */
int cpu = smp_processor_id();
irq_desc_t *desc = irq_desc + irq;
struct irqaction * action;
unsigned int status;
if (irq > 256) BUG();
kstat.irqs[cpu][irq]++;
spin_lock(&desc->lock);
desc->handler->ack(irq);
......@@ -632,6 +634,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
* The ->end() handler has to deal with interrupts which got
* disabled while the handler was running.
*/
if (irq > 256) BUG();
desc->handler->end(irq);
spin_unlock(&desc->lock);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -14,8 +14,6 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
void *ret;
int gfp = GFP_ATOMIC;
/* We need to always allocate below 4Gig. We probably need new
GPF mask to say that */
gfp |= GFP_DMA;
ret = (void *)__get_free_pages(gfp, get_order(size));
......
This diff is collapsed.
This diff is collapsed.
......@@ -18,9 +18,11 @@
#define PCI_NO_SORT 0x0100
#define PCI_BIOS_SORT 0x0200
#define PCI_NO_CHECKS 0x0400
#define PCI_USE_PIRQ_MASK 0x0800
#define PCI_ASSIGN_ROMS 0x1000
#define PCI_BIOS_IRQ_SCAN 0x2000
#define PCI_ASSIGN_ALL_BUSSES 0x4000
#define PCI_NO_ACPI_ROUTING 0x8000
extern unsigned int pci_probe;
......@@ -67,6 +69,8 @@ struct irq_routing_table {
extern unsigned int pcibios_irq_mask;
extern int pci_use_acpi_routing;
void pcibios_irq_init(void);
void pcibios_fixup_irqs(void);
void pcibios_enable_irq(struct pci_dev *dev);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment