Port of Linux 2.6.28 for use with network simulation cradle.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/README Sun Jan 11 20:20:11 2009 +0100
1.3 @@ -0,0 +1,18 @@
1.4 +This repository must be put into to main
1.5 +nsc (network simulation cradle) directory.
1.6 +
1.7 +Then, edit SConstruct and add the nsc-linux-2.6.28 directory:
1.8 +
1.9 +--- a/SConstruct Wed Nov 19 12:16:31 2008 -0800
1.10 ++++ b/SConstruct Sun Jan 11 20:16:18 2009 +0100
1.11 +@@ -145,5 +145,6 @@
1.12 + SConscript('linux-2.6/SConscript')
1.13 + SConscript("linux-2.6.18/SConscript")
1.14 + SConscript("linux-2.6.26/SConscript")
1.15 ++SConscript("nsc-linux-2.6.28/SConscript")
1.16 +
1.17 + SConscript('test/SConscript')
1.18 +
1.19 +
1.20 +Then, run "python scons.py nsc-linux-2.6.28" to build the linux 2.6.28 port.
1.21 +the library will be called liblinux2.6.28.so.
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/SConscript Sun Jan 11 20:20:11 2009 +0100
2.3 @@ -0,0 +1,184 @@
2.4 +# vim:filetype=python
2.5 +
2.6 +# Network Simulation Cradle
2.7 +# Copyright (C) 2003-2005 Sam Jansen
2.8 +#
2.9 +# This program is free software; you can redistribute it and/or modify it
2.10 +# under the terms of the GNU General Public License as published by the Free
2.11 +# Software Foundation; either version 2 of the License, or (at your option)
2.12 +# any later version.
2.13 +#
2.14 +# This program is distributed in the hope that it will be useful, but WITHOUT
2.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
2.17 +# more details.
2.18 +#
2.19 +# You should have received a copy of the GNU General Public License along
2.20 +# with this program; if not, write to the Free Software Foundation, Inc., 59
2.21 +# Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.22 +
2.23 +# The following compilers have been shown to not be able to compile this code:
2.24 +# - gcc version 4.0.3 (Ubuntu 4.0.3-1ubuntu5) -- compiler bug
2.25 +
2.26 +import os, glob
2.27 +
2.28 +Import('default_env')
2.29 +
2.30 +stackname = "linux2.6.28"
2.31 +arch_i386 = default_env['NSC_TARGET_ARCHITECTURE'] != 'amd64'
2.32 +curdir = Dir('.').path + '/'
2.33 +
2.34 +net = {}
2.35 +net['core'] = Split("""
2.36 +datagram.c ethtool.c iovec.c sock.c
2.37 +dev.c filter.c link_watch.c stream.c
2.38 +dev_mcast.c flow.c neighbour.c rtnetlink.c sysctl_net_core.c
2.39 +dst.c gen_estimator.c net-sysfs.c scm.c utils.c
2.40 + gen_stats.c skbuff.c netevent.c net_namespace.c
2.41 +request_sock.c""")
2.42 +net['ethernet'] = Split("""
2.43 +eth.c""")
2.44 +net['ipv4'] = Split("""
2.45 +af_inet.c icmp.c syncookies.c udp.c udplite.c
2.46 +ah4.c igmp.c ipconfig.c sysctl_net_ipv4.c
2.47 +arp.c inetpeer.c tcp.c
2.48 +datagram.c ip_forward.c inet_diag.c
2.49 +devinet.c ip_fragment.c tcp_input.c
2.50 +esp4.c tcp_ipv4.c
2.51 +fib_frontend.c ip_input.c tcp_minisocks.c
2.52 +fib_hash.c ip_options.c protocol.c tcp_output.c
2.53 + ip_output.c raw.c
2.54 +fib_semantics.c ip_sockglue.c route.c tcp_timer.c
2.55 +inet_connection_sock.c
2.56 +inet_fragment.c
2.57 +tcp_cong.c tcp_cubic.c tcp_highspeed.c
2.58 +tcp_htcp.c tcp_vegas.c tcp_veno.c tcp_westwood.c
2.59 +inet_hashtables.c tcp_diag.c tcp_scalable.c
2.60 +inet_timewait_sock.c tcp_hybla.c tcp_illinois.c
2.61 +tcp_lp.c tcp_bic.c tcp_yeah.c""")
2.62 +net['ipv6'] = Split("""
2.63 +addrconf.c addrlabel.c protocol.c syncookies.c
2.64 +udp.c udplite.c
2.65 +af_inet6.c icmp.c ipv6_sockglue.c raw.c
2.66 +ip6_fib.c reassembly.c
2.67 +anycast.c ip6_flowlabel.c mcast.c route.c
2.68 +datagram.c ip6_input.c ndisc.c
2.69 +ip6_output.c sysctl_net_ipv6.c
2.70 +addrconf_core.c
2.71 +exthdrs.c tcp_ipv6.c
2.72 +inet6_hashtables.c inet6_connection_sock.c""")
2.73 +net['sctp'] = Split("""
2.74 +auth.c associola.c endpointola.c outqueue.c sm_statefuns.c tsnmap.c
2.75 +bind_addr.c input.c primitive.c sm_statetable.c ulpevent.c
2.76 +chunk.c inqueue.c socket.c ulpqueue.c
2.77 +command.c ipv6.c protocol.c ssnmap.c
2.78 +sm_make_chunk.c sysctl.c
2.79 +debug.c output.c sm_sideeffect.c transport.c""")
2.80 +
2.81 +# NOTE: DCCP does not work completely yet; there is an infinite loop when
2.82 +# a dccp connection is being shut down.
2.83 +# For the time being, it isn't compiled.
2.84 +net['dccp'] = Split("""
2.85 +feat.c ipv4.c minisocks.c proto.c ccid.c options.c sysctl.c
2.86 +ackvec.c input.c output.c timer.c
2.87 +ccids/ccid2.c""")
2.88 +net['dccp/ccids'] = Split("""
2.89 +loss_interval.c packet_history.c tfrc.c tfrc_equation.c""")
2.90 +
2.91 +net['netlink'] = Split("""
2.92 +attr.c
2.93 +af_netlink.c""")
2.94 +net['packet'] = ['af_packet.c']
2.95 +net['sched'] = Split("""
2.96 + cls_api.c cls_u32.c sch_atm.c sch_hfsc.c
2.97 + cls_basic.c sch_blackhole.c sch_htb.c
2.98 + cls_fw.c sch_cbq.c sch_ingress.c
2.99 + sch_dsmark.c sch_netem.c
2.100 + sch_fifo.c sch_prio.c
2.101 + cls_rsvp.c sch_generic.c sch_red.c
2.102 + sch_sfq.c
2.103 + cls_rsvp6.c sch_tbf.c
2.104 + cls_tcindex.c sch_api.c sch_gred.c sch_teql.c
2.105 +""")
2.106 +net['.'] = ['socket.c', 'sysctl_net.c']
2.107 +
2.108 +# This array specifies the order. This order is used when linking; we need
2.109 +# to make sure things are linked in the correct order so the initialisation
2.110 +# functions -- initcall functions -- are called in the correct order.
2.111 +# There was a problem earlier where sctp_init was being called before
2.112 +# inet_init, which caused problems. The array below fixes that.
2.113 +dir_order = ['.', 'core', 'packet', 'sched', 'netlink', 'ethernet', 'ipv4',
2.114 + 'ipv6', 'sctp']
2.115 +src_to_globalise = reduce(lambda x,y:x+y,
2.116 + [['net/' + d + '/' + f for f in net[d]] for d in dir_order])
2.117 +
2.118 +src_to_globalise.extend([
2.119 + 'nsc/unimplemented.c', 'nsc/implemented.c', 'nsc/support.c',
2.120 + 'nsc/sysctl.c', 'nsc/tc.c', 'nsc/stub.c',
2.121 + 'kernel/softirq.c', 'kernel/timer.c', 'kernel/itimer.c', 'kernel/sysctl.c',
2.122 + 'kernel/rwsem.c', 'drivers/net/loopback.c', 'drivers/char/random.c',
2.123 + 'lib/find_next_bit.c', 'lib/libcrc32c.c', 'lib/idr.c',
2.124 + 'lib/rbtree.c', 'lib/hexdump.c'])
2.125 +
2.126 +sim_sources = ['nsc/sim_support.cpp']
2.127 +asm_sources = []
2.128 +
2.129 +if arch_i386:
2.130 + linker_script = 'arch/x86/kernel/linker-script-32.ld'
2.131 + asm_sources.extend(['arch/x86/lib/checksum_32.S'])
2.132 +else:
2.133 + linker_script = 'arch/x86/kernel/linker-script-64.ld'
2.134 + src_to_globalise.extend(['arch/x86/lib/csum-partial_64.c',
2.135 + 'arch/x86/lib/csum-wrappers_64.c'])
2.136 + asm_sources.extend(['arch/x86/lib/csum-copy_64.S'])
2.137 +
2.138 +# -----------------------------------------------------------------------------
2.139 +cflags = ('-O -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -nostdinc '
2.140 + '-fno-inline -iwithprefix include -DKBUILD_BASENAME=\\"clnt\\" '
2.141 + '-DKBUILD_MODNAME=\\"nsc\\" -DMODVERSIONS -DEXPORT_SYMTAB '
2.142 + '-include linux/config.h -g')
2.143 +
2.144 +# You really need to undefine whatever symbol is defined for the operating
2.145 +# system you are compiling on and make sure the various linux symbols are
2.146 +# defined. __linux__ is the only important one I've found; though compilers
2.147 +# tend to define __linux and __Linux__ and so on and so forth.
2.148 +cflags += ' -U__FreeBSD__ -D__linux__=1 -Dlinux=1 -D__linux=1 '
2.149 +
2.150 +glb_cflags = '-include nsc_override.h '
2.151 +
2.152 +include_path = ['include', 'arch/x86/include', 'arch/x86/include/asm/mach-default', '../sim', 'nsc',
2.153 + 'override']
2.154 +
2.155 +# We need a special linker script to set up some variables for
2.156 +# initialisation in Linux
2.157 +link_flags = '-Wl,-O1 -shared -Wl,-O1 -Wl,-T' + curdir + linker_script
2.158 +ext_cflags = ''
2.159 +as_flags = '-D__ASSEMBLY__'
2.160 +
2.161 +if arch_i386:
2.162 + cflags += '-DCONFIG_X86_32=1 '
2.163 +else:
2.164 + ext_cflags += '-fPIC '
2.165 + as_flags += '-fPIC '
2.166 + cflags += '-DCONFIG_X86_64=1 '
2.167 +
2.168 +cflags += ext_cflags
2.169 +
2.170 +# -----------------------------------------------------------------------------
2.171 +env = default_env.Clone(CCFLAGS=cflags, CPPPATH=include_path,
2.172 + GLB_CCFLAGS=glb_cflags,
2.173 + GLB_LIST=curdir + '/global_list.txt')
2.174 +sim_env = default_env.Clone(CCFLAGS='-g -Wall -O2 ' + ext_cflags,
2.175 + CPPPATH=['../sim', 'nsc'])
2.176 +
2.177 +objects = env.Globaliser(src_to_globalise)
2.178 +objects.extend([sim_env.SharedObject(s) for s in sim_sources])
2.179 +objects.extend(asm_sources)
2.180 +
2.181 +# Using Program and -shared is a hacky way to make a shared library in SCons
2.182 +# without requiring -fPIC.
2.183 +env['LINKFLAGS'] += link_flags
2.184 +env['ASFLAGS'] += as_flags
2.185 +output = env.Program(source=objects, target='lib%s.so' % stackname)
2.186 +
2.187 +Install(dir = "..", source = output)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/arch/x86/include/asm/Kbuild Sun Jan 11 20:20:11 2009 +0100
3.3 @@ -0,0 +1,24 @@
3.4 +include include/asm-generic/Kbuild.asm
3.5 +
3.6 +header-y += boot.h
3.7 +header-y += bootparam.h
3.8 +header-y += debugreg.h
3.9 +header-y += ldt.h
3.10 +header-y += msr-index.h
3.11 +header-y += prctl.h
3.12 +header-y += ptrace-abi.h
3.13 +header-y += sigcontext32.h
3.14 +header-y += ucontext.h
3.15 +header-y += processor-flags.h
3.16 +
3.17 +unifdef-y += e820.h
3.18 +unifdef-y += ist.h
3.19 +unifdef-y += mce.h
3.20 +unifdef-y += msr.h
3.21 +unifdef-y += mtrr.h
3.22 +unifdef-y += posix_types_32.h
3.23 +unifdef-y += posix_types_64.h
3.24 +unifdef-y += unistd_32.h
3.25 +unifdef-y += unistd_64.h
3.26 +unifdef-y += vm86.h
3.27 +unifdef-y += vsyscall.h
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/arch/x86/include/asm/a.out-core.h Sun Jan 11 20:20:11 2009 +0100
4.3 @@ -0,0 +1,73 @@
4.4 +/* a.out coredump register dumper
4.5 + *
4.6 + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4.7 + * Written by David Howells (dhowells@redhat.com)
4.8 + *
4.9 + * This program is free software; you can redistribute it and/or
4.10 + * modify it under the terms of the GNU General Public Licence
4.11 + * as published by the Free Software Foundation; either version
4.12 + * 2 of the Licence, or (at your option) any later version.
4.13 + */
4.14 +
4.15 +#ifndef _ASM_X86_A_OUT_CORE_H
4.16 +#define _ASM_X86_A_OUT_CORE_H
4.17 +
4.18 +#ifdef __KERNEL__
4.19 +#ifdef CONFIG_X86_32
4.20 +
4.21 +#include <linux/user.h>
4.22 +#include <linux/elfcore.h>
4.23 +
4.24 +/*
4.25 + * fill in the user structure for an a.out core dump
4.26 + */
4.27 +static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
4.28 +{
4.29 + u16 gs;
4.30 +
4.31 +/* changed the size calculations - should hopefully work better. lbt */
4.32 + dump->magic = CMAGIC;
4.33 + dump->start_code = 0;
4.34 + dump->start_stack = regs->sp & ~(PAGE_SIZE - 1);
4.35 + dump->u_tsize = ((unsigned long)current->mm->end_code) >> PAGE_SHIFT;
4.36 + dump->u_dsize = ((unsigned long)(current->mm->brk + (PAGE_SIZE - 1)))
4.37 + >> PAGE_SHIFT;
4.38 + dump->u_dsize -= dump->u_tsize;
4.39 + dump->u_ssize = 0;
4.40 + dump->u_debugreg[0] = current->thread.debugreg0;
4.41 + dump->u_debugreg[1] = current->thread.debugreg1;
4.42 + dump->u_debugreg[2] = current->thread.debugreg2;
4.43 + dump->u_debugreg[3] = current->thread.debugreg3;
4.44 + dump->u_debugreg[4] = 0;
4.45 + dump->u_debugreg[5] = 0;
4.46 + dump->u_debugreg[6] = current->thread.debugreg6;
4.47 + dump->u_debugreg[7] = current->thread.debugreg7;
4.48 +
4.49 + if (dump->start_stack < TASK_SIZE)
4.50 + dump->u_ssize = ((unsigned long)(TASK_SIZE - dump->start_stack))
4.51 + >> PAGE_SHIFT;
4.52 +
4.53 + dump->regs.bx = regs->bx;
4.54 + dump->regs.cx = regs->cx;
4.55 + dump->regs.dx = regs->dx;
4.56 + dump->regs.si = regs->si;
4.57 + dump->regs.di = regs->di;
4.58 + dump->regs.bp = regs->bp;
4.59 + dump->regs.ax = regs->ax;
4.60 + dump->regs.ds = (u16)regs->ds;
4.61 + dump->regs.es = (u16)regs->es;
4.62 + dump->regs.fs = (u16)regs->fs;
4.63 + savesegment(gs, gs);
4.64 + dump->regs.orig_ax = regs->orig_ax;
4.65 + dump->regs.ip = regs->ip;
4.66 + dump->regs.cs = (u16)regs->cs;
4.67 + dump->regs.flags = regs->flags;
4.68 + dump->regs.sp = regs->sp;
4.69 + dump->regs.ss = (u16)regs->ss;
4.70 +
4.71 + dump->u_fpvalid = dump_fpu(regs, &dump->i387);
4.72 +}
4.73 +
4.74 +#endif /* CONFIG_X86_32 */
4.75 +#endif /* __KERNEL__ */
4.76 +#endif /* _ASM_X86_A_OUT_CORE_H */
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/arch/x86/include/asm/a.out.h Sun Jan 11 20:20:11 2009 +0100
5.3 @@ -0,0 +1,20 @@
5.4 +#ifndef _ASM_X86_A_OUT_H
5.5 +#define _ASM_X86_A_OUT_H
5.6 +
5.7 +struct exec
5.8 +{
5.9 + unsigned int a_info; /* Use macros N_MAGIC, etc for access */
5.10 + unsigned a_text; /* length of text, in bytes */
5.11 + unsigned a_data; /* length of data, in bytes */
5.12 + unsigned a_bss; /* length of uninitialized data area for file, in bytes */
5.13 + unsigned a_syms; /* length of symbol table data in file, in bytes */
5.14 + unsigned a_entry; /* start address */
5.15 + unsigned a_trsize; /* length of relocation info for text, in bytes */
5.16 + unsigned a_drsize; /* length of relocation info for data, in bytes */
5.17 +};
5.18 +
5.19 +#define N_TRSIZE(a) ((a).a_trsize)
5.20 +#define N_DRSIZE(a) ((a).a_drsize)
5.21 +#define N_SYMSIZE(a) ((a).a_syms)
5.22 +
5.23 +#endif /* _ASM_X86_A_OUT_H */
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/arch/x86/include/asm/acpi.h Sun Jan 11 20:20:11 2009 +0100
6.3 @@ -0,0 +1,177 @@
6.4 +#ifndef _ASM_X86_ACPI_H
6.5 +#define _ASM_X86_ACPI_H
6.6 +
6.7 +/*
6.8 + * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6.9 + * Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
6.10 + *
6.11 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6.12 + *
6.13 + * This program is free software; you can redistribute it and/or modify
6.14 + * it under the terms of the GNU General Public License as published by
6.15 + * the Free Software Foundation; either version 2 of the License, or
6.16 + * (at your option) any later version.
6.17 + *
6.18 + * This program is distributed in the hope that it will be useful,
6.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.21 + * GNU General Public License for more details.
6.22 + *
6.23 + * You should have received a copy of the GNU General Public License
6.24 + * along with this program; if not, write to the Free Software
6.25 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6.26 + *
6.27 + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6.28 + */
6.29 +#include <acpi/pdc_intel.h>
6.30 +
6.31 +#include <asm/numa.h>
6.32 +#include <asm/processor.h>
6.33 +#include <asm/mmu.h>
6.34 +#include <asm/mpspec.h>
6.35 +
6.36 +#define COMPILER_DEPENDENT_INT64 long long
6.37 +#define COMPILER_DEPENDENT_UINT64 unsigned long long
6.38 +
6.39 +/*
6.40 + * Calling conventions:
6.41 + *
6.42 + * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads)
6.43 + * ACPI_EXTERNAL_XFACE - External ACPI interfaces
6.44 + * ACPI_INTERNAL_XFACE - Internal ACPI interfaces
6.45 + * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces
6.46 + */
6.47 +#define ACPI_SYSTEM_XFACE
6.48 +#define ACPI_EXTERNAL_XFACE
6.49 +#define ACPI_INTERNAL_XFACE
6.50 +#define ACPI_INTERNAL_VAR_XFACE
6.51 +
6.52 +/* Asm macros */
6.53 +
6.54 +#define ACPI_ASM_MACROS
6.55 +#define BREAKPOINT3
6.56 +#define ACPI_DISABLE_IRQS() local_irq_disable()
6.57 +#define ACPI_ENABLE_IRQS() local_irq_enable()
6.58 +#define ACPI_FLUSH_CPU_CACHE() wbinvd()
6.59 +
6.60 +int __acpi_acquire_global_lock(unsigned int *lock);
6.61 +int __acpi_release_global_lock(unsigned int *lock);
6.62 +
6.63 +#define ACPI_ACQUIRE_GLOBAL_LOCK(facs, Acq) \
6.64 + ((Acq) = __acpi_acquire_global_lock(&facs->global_lock))
6.65 +
6.66 +#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \
6.67 + ((Acq) = __acpi_release_global_lock(&facs->global_lock))
6.68 +
6.69 +/*
6.70 + * Math helper asm macros
6.71 + */
6.72 +#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \
6.73 + asm("divl %2;" \
6.74 + : "=a"(q32), "=d"(r32) \
6.75 + : "r"(d32), \
6.76 + "0"(n_lo), "1"(n_hi))
6.77 +
6.78 +
6.79 +#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \
6.80 + asm("shrl $1,%2 ;" \
6.81 + "rcrl $1,%3;" \
6.82 + : "=r"(n_hi), "=r"(n_lo) \
6.83 + : "0"(n_hi), "1"(n_lo))
6.84 +
6.85 +#ifdef CONFIG_ACPI
6.86 +extern int acpi_lapic;
6.87 +extern int acpi_ioapic;
6.88 +extern int acpi_noirq;
6.89 +extern int acpi_strict;
6.90 +extern int acpi_disabled;
6.91 +extern int acpi_ht;
6.92 +extern int acpi_pci_disabled;
6.93 +extern int acpi_skip_timer_override;
6.94 +extern int acpi_use_timer_override;
6.95 +
6.96 +extern u8 acpi_sci_flags;
6.97 +extern int acpi_sci_override_gsi;
6.98 +void acpi_pic_sci_set_trigger(unsigned int, u16);
6.99 +
6.100 +static inline void disable_acpi(void)
6.101 +{
6.102 + acpi_disabled = 1;
6.103 + acpi_ht = 0;
6.104 + acpi_pci_disabled = 1;
6.105 + acpi_noirq = 1;
6.106 +}
6.107 +
6.108 +/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
6.109 +#define FIX_ACPI_PAGES 4
6.110 +
6.111 +extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
6.112 +
6.113 +static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
6.114 +static inline void acpi_disable_pci(void)
6.115 +{
6.116 + acpi_pci_disabled = 1;
6.117 + acpi_noirq_set();
6.118 +}
6.119 +
6.120 +/* routines for saving/restoring kernel state */
6.121 +extern int acpi_save_state_mem(void);
6.122 +extern void acpi_restore_state_mem(void);
6.123 +
6.124 +extern unsigned long acpi_wakeup_address;
6.125 +
6.126 +/* early initialization routine */
6.127 +extern void acpi_reserve_bootmem(void);
6.128 +
6.129 +/*
6.130 + * Check if the CPU can handle C2 and deeper
6.131 + */
6.132 +static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
6.133 +{
6.134 + /*
6.135 + * Early models (<=5) of AMD Opterons are not supposed to go into
6.136 + * C2 state.
6.137 + *
6.138 + * Steppings 0x0A and later are good
6.139 + */
6.140 + if (boot_cpu_data.x86 == 0x0F &&
6.141 + boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
6.142 + boot_cpu_data.x86_model <= 0x05 &&
6.143 + boot_cpu_data.x86_mask < 0x0A)
6.144 + return 1;
6.145 + else if (boot_cpu_has(X86_FEATURE_AMDC1E))
6.146 + return 1;
6.147 + else
6.148 + return max_cstate;
6.149 +}
6.150 +
6.151 +#else /* !CONFIG_ACPI */
6.152 +
6.153 +#define acpi_lapic 0
6.154 +#define acpi_ioapic 0
6.155 +static inline void acpi_noirq_set(void) { }
6.156 +static inline void acpi_disable_pci(void) { }
6.157 +static inline void disable_acpi(void) { }
6.158 +
6.159 +#endif /* !CONFIG_ACPI */
6.160 +
6.161 +#define ARCH_HAS_POWER_INIT 1
6.162 +
6.163 +struct bootnode;
6.164 +
6.165 +#ifdef CONFIG_ACPI_NUMA
6.166 +extern int acpi_numa;
6.167 +extern int acpi_scan_nodes(unsigned long start, unsigned long end);
6.168 +#define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
6.169 +extern void acpi_fake_nodes(const struct bootnode *fake_nodes,
6.170 + int num_nodes);
6.171 +#else
6.172 +static inline void acpi_fake_nodes(const struct bootnode *fake_nodes,
6.173 + int num_nodes)
6.174 +{
6.175 +}
6.176 +#endif
6.177 +
6.178 +#define acpi_unlazy_tlb(x) leave_mm(x)
6.179 +
6.180 +#endif /* _ASM_X86_ACPI_H */
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/arch/x86/include/asm/agp.h Sun Jan 11 20:20:11 2009 +0100
7.3 @@ -0,0 +1,35 @@
7.4 +#ifndef _ASM_X86_AGP_H
7.5 +#define _ASM_X86_AGP_H
7.6 +
7.7 +#include <asm/pgtable.h>
7.8 +#include <asm/cacheflush.h>
7.9 +
7.10 +/*
7.11 + * Functions to keep the agpgart mappings coherent with the MMU. The
7.12 + * GART gives the CPU a physical alias of pages in memory. The alias
7.13 + * region is mapped uncacheable. Make sure there are no conflicting
7.14 + * mappings with different cachability attributes for the same
7.15 + * page. This avoids data corruption on some CPUs.
7.16 + */
7.17 +
7.18 +#define map_page_into_agp(page) set_pages_uc(page, 1)
7.19 +#define unmap_page_from_agp(page) set_pages_wb(page, 1)
7.20 +
7.21 +/*
7.22 + * Could use CLFLUSH here if the cpu supports it. But then it would
7.23 + * need to be called for each cacheline of the whole page so it may
7.24 + * not be worth it. Would need a page for it.
7.25 + */
7.26 +#define flush_agp_cache() wbinvd()
7.27 +
7.28 +/* Convert a physical address to an address suitable for the GART. */
7.29 +#define phys_to_gart(x) (x)
7.30 +#define gart_to_phys(x) (x)
7.31 +
7.32 +/* GATT allocation. Returns/accepts GATT kernel virtual address. */
7.33 +#define alloc_gatt_pages(order) \
7.34 + ((char *)__get_free_pages(GFP_KERNEL, (order)))
7.35 +#define free_gatt_pages(table, order) \
7.36 + free_pages((unsigned long)(table), (order))
7.37 +
7.38 +#endif /* _ASM_X86_AGP_H */
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/arch/x86/include/asm/alternative-asm.h Sun Jan 11 20:20:11 2009 +0100
8.3 @@ -0,0 +1,22 @@
8.4 +#ifdef __ASSEMBLY__
8.5 +
8.6 +#ifdef CONFIG_X86_32
8.7 +# define X86_ALIGN .long
8.8 +#else
8.9 +# define X86_ALIGN .quad
8.10 +#endif
8.11 +
8.12 +#ifdef CONFIG_SMP
8.13 + .macro LOCK_PREFIX
8.14 +1: lock
8.15 + .section .smp_locks,"a"
8.16 + .align 4
8.17 + X86_ALIGN 1b
8.18 + .previous
8.19 + .endm
8.20 +#else
8.21 + .macro LOCK_PREFIX
8.22 + .endm
8.23 +#endif
8.24 +
8.25 +#endif /* __ASSEMBLY__ */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/arch/x86/include/asm/alternative.h Sun Jan 11 20:20:11 2009 +0100
9.3 @@ -0,0 +1,183 @@
9.4 +#ifndef _ASM_X86_ALTERNATIVE_H
9.5 +#define _ASM_X86_ALTERNATIVE_H
9.6 +
9.7 +#include <linux/types.h>
9.8 +#include <linux/stddef.h>
9.9 +#include <asm/asm.h>
9.10 +
9.11 +/*
9.12 + * Alternative inline assembly for SMP.
9.13 + *
9.14 + * The LOCK_PREFIX macro defined here replaces the LOCK and
9.15 + * LOCK_PREFIX macros used everywhere in the source tree.
9.16 + *
9.17 + * SMP alternatives use the same data structures as the other
9.18 + * alternatives and the X86_FEATURE_UP flag to indicate the case of a
9.19 + * UP system running a SMP kernel. The existing apply_alternatives()
9.20 + * works fine for patching a SMP kernel for UP.
9.21 + *
9.22 + * The SMP alternative tables can be kept after boot and contain both
9.23 + * UP and SMP versions of the instructions to allow switching back to
9.24 + * SMP at runtime, when hotplugging in a new CPU, which is especially
9.25 + * useful in virtualized environments.
9.26 + *
9.27 + * The very common lock prefix is handled as special case in a
9.28 + * separate table which is a pure address list without replacement ptr
9.29 + * and size information. That keeps the table sizes small.
9.30 + */
9.31 +
9.32 +#ifdef CONFIG_SMP
9.33 +#define LOCK_PREFIX \
9.34 + ".section .smp_locks,\"a\"\n" \
9.35 + _ASM_ALIGN "\n" \
9.36 + _ASM_PTR "661f\n" /* address */ \
9.37 + ".previous\n" \
9.38 + "661:\n\tlock; "
9.39 +
9.40 +#else /* ! CONFIG_SMP */
9.41 +#define LOCK_PREFIX ""
9.42 +#endif
9.43 +
9.44 +/* This must be included *after* the definition of LOCK_PREFIX */
9.45 +#include <asm/cpufeature.h>
9.46 +
9.47 +struct alt_instr {
9.48 + u8 *instr; /* original instruction */
9.49 + u8 *replacement;
9.50 + u8 cpuid; /* cpuid bit set for replacement */
9.51 + u8 instrlen; /* length of original instruction */
9.52 + u8 replacementlen; /* length of new instruction, <= instrlen */
9.53 + u8 pad1;
9.54 +#ifdef CONFIG_X86_64
9.55 + u32 pad2;
9.56 +#endif
9.57 +};
9.58 +
9.59 +extern void alternative_instructions(void);
9.60 +extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
9.61 +
9.62 +struct module;
9.63 +
9.64 +#ifdef CONFIG_SMP
9.65 +extern void alternatives_smp_module_add(struct module *mod, char *name,
9.66 + void *locks, void *locks_end,
9.67 + void *text, void *text_end);
9.68 +extern void alternatives_smp_module_del(struct module *mod);
9.69 +extern void alternatives_smp_switch(int smp);
9.70 +#else
9.71 +static inline void alternatives_smp_module_add(struct module *mod, char *name,
9.72 + void *locks, void *locks_end,
9.73 + void *text, void *text_end) {}
9.74 +static inline void alternatives_smp_module_del(struct module *mod) {}
9.75 +static inline void alternatives_smp_switch(int smp) {}
9.76 +#endif /* CONFIG_SMP */
9.77 +
9.78 +const unsigned char *const *find_nop_table(void);
9.79 +
9.80 +/*
9.81 + * Alternative instructions for different CPU types or capabilities.
9.82 + *
9.83 + * This allows to use optimized instructions even on generic binary
9.84 + * kernels.
9.85 + *
9.86 + * length of oldinstr must be longer or equal the length of newinstr
9.87 + * It can be padded with nops as needed.
9.88 + *
9.89 + * For non barrier like inlines please define new variants
9.90 + * without volatile and memory clobber.
9.91 + */
9.92 +#define alternative(oldinstr, newinstr, feature) \
9.93 + asm volatile ("661:\n\t" oldinstr "\n662:\n" \
9.94 + ".section .altinstructions,\"a\"\n" \
9.95 + _ASM_ALIGN "\n" \
9.96 + _ASM_PTR "661b\n" /* label */ \
9.97 + _ASM_PTR "663f\n" /* new instruction */ \
9.98 + " .byte %c0\n" /* feature bit */ \
9.99 + " .byte 662b-661b\n" /* sourcelen */ \
9.100 + " .byte 664f-663f\n" /* replacementlen */ \
9.101 + ".previous\n" \
9.102 + ".section .altinstr_replacement,\"ax\"\n" \
9.103 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
9.104 + ".previous" :: "i" (feature) : "memory")
9.105 +
9.106 +/*
9.107 + * Alternative inline assembly with input.
9.108 + *
9.109 + * Pecularities:
9.110 + * No memory clobber here.
9.111 + * Argument numbers start with 1.
9.112 + * Best is to use constraints that are fixed size (like (%1) ... "r")
9.113 + * If you use variable sized constraints like "m" or "g" in the
9.114 + * replacement make sure to pad to the worst case length.
9.115 + */
9.116 +#define alternative_input(oldinstr, newinstr, feature, input...) \
9.117 + asm volatile ("661:\n\t" oldinstr "\n662:\n" \
9.118 + ".section .altinstructions,\"a\"\n" \
9.119 + _ASM_ALIGN "\n" \
9.120 + _ASM_PTR "661b\n" /* label */ \
9.121 + _ASM_PTR "663f\n" /* new instruction */ \
9.122 + " .byte %c0\n" /* feature bit */ \
9.123 + " .byte 662b-661b\n" /* sourcelen */ \
9.124 + " .byte 664f-663f\n" /* replacementlen */ \
9.125 + ".previous\n" \
9.126 + ".section .altinstr_replacement,\"ax\"\n" \
9.127 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
9.128 + ".previous" :: "i" (feature), ##input)
9.129 +
9.130 +/* Like alternative_input, but with a single output argument */
9.131 +#define alternative_io(oldinstr, newinstr, feature, output, input...) \
9.132 + asm volatile ("661:\n\t" oldinstr "\n662:\n" \
9.133 + ".section .altinstructions,\"a\"\n" \
9.134 + _ASM_ALIGN "\n" \
9.135 + _ASM_PTR "661b\n" /* label */ \
9.136 + _ASM_PTR "663f\n" /* new instruction */ \
9.137 + " .byte %c[feat]\n" /* feature bit */ \
9.138 + " .byte 662b-661b\n" /* sourcelen */ \
9.139 + " .byte 664f-663f\n" /* replacementlen */ \
9.140 + ".previous\n" \
9.141 + ".section .altinstr_replacement,\"ax\"\n" \
9.142 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
9.143 + ".previous" : output : [feat] "i" (feature), ##input)
9.144 +
9.145 +/*
9.146 + * use this macro(s) if you need more than one output parameter
9.147 + * in alternative_io
9.148 + */
9.149 +#define ASM_OUTPUT2(a, b) a, b
9.150 +
9.151 +struct paravirt_patch_site;
9.152 +#ifdef CONFIG_PARAVIRT
9.153 +void apply_paravirt(struct paravirt_patch_site *start,
9.154 + struct paravirt_patch_site *end);
9.155 +#else
9.156 +static inline void apply_paravirt(struct paravirt_patch_site *start,
9.157 + struct paravirt_patch_site *end)
9.158 +{}
9.159 +#define __parainstructions NULL
9.160 +#define __parainstructions_end NULL
9.161 +#endif
9.162 +
9.163 +extern void add_nops(void *insns, unsigned int len);
9.164 +
9.165 +/*
9.166 + * Clear and restore the kernel write-protection flag on the local CPU.
9.167 + * Allows the kernel to edit read-only pages.
9.168 + * Side-effect: any interrupt handler running between save and restore will have
9.169 + * the ability to write to read-only pages.
9.170 + *
9.171 + * Warning:
9.172 + * Code patching in the UP case is safe if NMIs and MCE handlers are stopped and
9.173 + * no thread can be preempted in the instructions being modified (no iret to an
9.174 + * invalid instruction possible) or if the instructions are changed from a
9.175 + * consistent state to another consistent state atomically.
9.176 + * More care must be taken when modifying code in the SMP case because of
9.177 + * Intel's errata.
9.178 + * On the local CPU you need to be protected again NMI or MCE handlers seeing an
9.179 + * inconsistent instruction while you patch.
9.180 + * The _early version expects the memory to already be RW.
9.181 + */
9.182 +
9.183 +extern void *text_poke(void *addr, const void *opcode, size_t len);
9.184 +extern void *text_poke_early(void *addr, const void *opcode, size_t len);
9.185 +
9.186 +#endif /* _ASM_X86_ALTERNATIVE_H */
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/arch/x86/include/asm/amd_iommu.h Sun Jan 11 20:20:11 2009 +0100
10.3 @@ -0,0 +1,35 @@
10.4 +/*
10.5 + * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
10.6 + * Author: Joerg Roedel <joerg.roedel@amd.com>
10.7 + * Leo Duran <leo.duran@amd.com>
10.8 + *
10.9 + * This program is free software; you can redistribute it and/or modify it
10.10 + * under the terms of the GNU General Public License version 2 as published
10.11 + * by the Free Software Foundation.
10.12 + *
10.13 + * This program is distributed in the hope that it will be useful,
10.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.16 + * GNU General Public License for more details.
10.17 + *
10.18 + * You should have received a copy of the GNU General Public License
10.19 + * along with this program; if not, write to the Free Software
10.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
10.21 + */
10.22 +
10.23 +#ifndef _ASM_X86_AMD_IOMMU_H
10.24 +#define _ASM_X86_AMD_IOMMU_H
10.25 +
10.26 +#include <linux/irqreturn.h>
10.27 +
10.28 +#ifdef CONFIG_AMD_IOMMU
10.29 +extern int amd_iommu_init(void);
10.30 +extern int amd_iommu_init_dma_ops(void);
10.31 +extern void amd_iommu_detect(void);
10.32 +extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
10.33 +#else
10.34 +static inline int amd_iommu_init(void) { return -ENODEV; }
10.35 +static inline void amd_iommu_detect(void) { }
10.36 +#endif
10.37 +
10.38 +#endif /* _ASM_X86_AMD_IOMMU_H */
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/arch/x86/include/asm/amd_iommu_types.h Sun Jan 11 20:20:11 2009 +0100
11.3 @@ -0,0 +1,404 @@
11.4 +/*
11.5 + * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
11.6 + * Author: Joerg Roedel <joerg.roedel@amd.com>
11.7 + * Leo Duran <leo.duran@amd.com>
11.8 + *
11.9 + * This program is free software; you can redistribute it and/or modify it
11.10 + * under the terms of the GNU General Public License version 2 as published
11.11 + * by the Free Software Foundation.
11.12 + *
11.13 + * This program is distributed in the hope that it will be useful,
11.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.16 + * GNU General Public License for more details.
11.17 + *
11.18 + * You should have received a copy of the GNU General Public License
11.19 + * along with this program; if not, write to the Free Software
11.20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
11.21 + */
11.22 +
11.23 +#ifndef _ASM_X86_AMD_IOMMU_TYPES_H
11.24 +#define _ASM_X86_AMD_IOMMU_TYPES_H
11.25 +
11.26 +#include <linux/types.h>
11.27 +#include <linux/list.h>
11.28 +#include <linux/spinlock.h>
11.29 +
11.30 +/*
11.31 + * some size calculation constants
11.32 + */
11.33 +#define DEV_TABLE_ENTRY_SIZE 32
11.34 +#define ALIAS_TABLE_ENTRY_SIZE 2
11.35 +#define RLOOKUP_TABLE_ENTRY_SIZE (sizeof(void *))
11.36 +
11.37 +/* Length of the MMIO region for the AMD IOMMU */
11.38 +#define MMIO_REGION_LENGTH 0x4000
11.39 +
11.40 +/* Capability offsets used by the driver */
11.41 +#define MMIO_CAP_HDR_OFFSET 0x00
11.42 +#define MMIO_RANGE_OFFSET 0x0c
11.43 +#define MMIO_MISC_OFFSET 0x10
11.44 +
11.45 +/* Masks, shifts and macros to parse the device range capability */
11.46 +#define MMIO_RANGE_LD_MASK 0xff000000
11.47 +#define MMIO_RANGE_FD_MASK 0x00ff0000
11.48 +#define MMIO_RANGE_BUS_MASK 0x0000ff00
11.49 +#define MMIO_RANGE_LD_SHIFT 24
11.50 +#define MMIO_RANGE_FD_SHIFT 16
11.51 +#define MMIO_RANGE_BUS_SHIFT 8
11.52 +#define MMIO_GET_LD(x) (((x) & MMIO_RANGE_LD_MASK) >> MMIO_RANGE_LD_SHIFT)
11.53 +#define MMIO_GET_FD(x) (((x) & MMIO_RANGE_FD_MASK) >> MMIO_RANGE_FD_SHIFT)
11.54 +#define MMIO_GET_BUS(x) (((x) & MMIO_RANGE_BUS_MASK) >> MMIO_RANGE_BUS_SHIFT)
11.55 +#define MMIO_MSI_NUM(x) ((x) & 0x1f)
11.56 +
11.57 +/* Flag masks for the AMD IOMMU exclusion range */
11.58 +#define MMIO_EXCL_ENABLE_MASK 0x01ULL
11.59 +#define MMIO_EXCL_ALLOW_MASK 0x02ULL
11.60 +
11.61 +/* Used offsets into the MMIO space */
11.62 +#define MMIO_DEV_TABLE_OFFSET 0x0000
11.63 +#define MMIO_CMD_BUF_OFFSET 0x0008
11.64 +#define MMIO_EVT_BUF_OFFSET 0x0010
11.65 +#define MMIO_CONTROL_OFFSET 0x0018
11.66 +#define MMIO_EXCL_BASE_OFFSET 0x0020
11.67 +#define MMIO_EXCL_LIMIT_OFFSET 0x0028
11.68 +#define MMIO_CMD_HEAD_OFFSET 0x2000
11.69 +#define MMIO_CMD_TAIL_OFFSET 0x2008
11.70 +#define MMIO_EVT_HEAD_OFFSET 0x2010
11.71 +#define MMIO_EVT_TAIL_OFFSET 0x2018
11.72 +#define MMIO_STATUS_OFFSET 0x2020
11.73 +
11.74 +/* MMIO status bits */
11.75 +#define MMIO_STATUS_COM_WAIT_INT_MASK 0x04
11.76 +
11.77 +/* event logging constants */
11.78 +#define EVENT_ENTRY_SIZE 0x10
11.79 +#define EVENT_TYPE_SHIFT 28
11.80 +#define EVENT_TYPE_MASK 0xf
11.81 +#define EVENT_TYPE_ILL_DEV 0x1
11.82 +#define EVENT_TYPE_IO_FAULT 0x2
11.83 +#define EVENT_TYPE_DEV_TAB_ERR 0x3
11.84 +#define EVENT_TYPE_PAGE_TAB_ERR 0x4
11.85 +#define EVENT_TYPE_ILL_CMD 0x5
11.86 +#define EVENT_TYPE_CMD_HARD_ERR 0x6
11.87 +#define EVENT_TYPE_IOTLB_INV_TO 0x7
11.88 +#define EVENT_TYPE_INV_DEV_REQ 0x8
11.89 +#define EVENT_DEVID_MASK 0xffff
11.90 +#define EVENT_DEVID_SHIFT 0
11.91 +#define EVENT_DOMID_MASK 0xffff
11.92 +#define EVENT_DOMID_SHIFT 0
11.93 +#define EVENT_FLAGS_MASK 0xfff
11.94 +#define EVENT_FLAGS_SHIFT 0x10
11.95 +
11.96 +/* feature control bits */
11.97 +#define CONTROL_IOMMU_EN 0x00ULL
11.98 +#define CONTROL_HT_TUN_EN 0x01ULL
11.99 +#define CONTROL_EVT_LOG_EN 0x02ULL
11.100 +#define CONTROL_EVT_INT_EN 0x03ULL
11.101 +#define CONTROL_COMWAIT_EN 0x04ULL
11.102 +#define CONTROL_PASSPW_EN 0x08ULL
11.103 +#define CONTROL_RESPASSPW_EN 0x09ULL
11.104 +#define CONTROL_COHERENT_EN 0x0aULL
11.105 +#define CONTROL_ISOC_EN 0x0bULL
11.106 +#define CONTROL_CMDBUF_EN 0x0cULL
11.107 +#define CONTROL_PPFLOG_EN 0x0dULL
11.108 +#define CONTROL_PPFINT_EN 0x0eULL
11.109 +
11.110 +/* command specific defines */
11.111 +#define CMD_COMPL_WAIT 0x01
11.112 +#define CMD_INV_DEV_ENTRY 0x02
11.113 +#define CMD_INV_IOMMU_PAGES 0x03
11.114 +
11.115 +#define CMD_COMPL_WAIT_STORE_MASK 0x01
11.116 +#define CMD_COMPL_WAIT_INT_MASK 0x02
11.117 +#define CMD_INV_IOMMU_PAGES_SIZE_MASK 0x01
11.118 +#define CMD_INV_IOMMU_PAGES_PDE_MASK 0x02
11.119 +
11.120 +#define CMD_INV_IOMMU_ALL_PAGES_ADDRESS 0x7fffffffffffffffULL
11.121 +
11.122 +/* macros and definitions for device table entries */
11.123 +#define DEV_ENTRY_VALID 0x00
11.124 +#define DEV_ENTRY_TRANSLATION 0x01
11.125 +#define DEV_ENTRY_IR 0x3d
11.126 +#define DEV_ENTRY_IW 0x3e
11.127 +#define DEV_ENTRY_NO_PAGE_FAULT 0x62
11.128 +#define DEV_ENTRY_EX 0x67
11.129 +#define DEV_ENTRY_SYSMGT1 0x68
11.130 +#define DEV_ENTRY_SYSMGT2 0x69
11.131 +#define DEV_ENTRY_INIT_PASS 0xb8
11.132 +#define DEV_ENTRY_EINT_PASS 0xb9
11.133 +#define DEV_ENTRY_NMI_PASS 0xba
11.134 +#define DEV_ENTRY_LINT0_PASS 0xbe
11.135 +#define DEV_ENTRY_LINT1_PASS 0xbf
11.136 +#define DEV_ENTRY_MODE_MASK 0x07
11.137 +#define DEV_ENTRY_MODE_SHIFT 0x09
11.138 +
11.139 +/* constants to configure the command buffer */
11.140 +#define CMD_BUFFER_SIZE 8192
11.141 +#define CMD_BUFFER_ENTRIES 512
11.142 +#define MMIO_CMD_SIZE_SHIFT 56
11.143 +#define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT)
11.144 +
11.145 +/* constants for event buffer handling */
11.146 +#define EVT_BUFFER_SIZE 8192 /* 512 entries */
11.147 +#define EVT_LEN_MASK (0x9ULL << 56)
11.148 +
11.149 +#define PAGE_MODE_1_LEVEL 0x01
11.150 +#define PAGE_MODE_2_LEVEL 0x02
11.151 +#define PAGE_MODE_3_LEVEL 0x03
11.152 +
11.153 +#define IOMMU_PDE_NL_0 0x000ULL
11.154 +#define IOMMU_PDE_NL_1 0x200ULL
11.155 +#define IOMMU_PDE_NL_2 0x400ULL
11.156 +#define IOMMU_PDE_NL_3 0x600ULL
11.157 +
11.158 +#define IOMMU_PTE_L2_INDEX(address) (((address) >> 30) & 0x1ffULL)
11.159 +#define IOMMU_PTE_L1_INDEX(address) (((address) >> 21) & 0x1ffULL)
11.160 +#define IOMMU_PTE_L0_INDEX(address) (((address) >> 12) & 0x1ffULL)
11.161 +
11.162 +#define IOMMU_MAP_SIZE_L1 (1ULL << 21)
11.163 +#define IOMMU_MAP_SIZE_L2 (1ULL << 30)
11.164 +#define IOMMU_MAP_SIZE_L3 (1ULL << 39)
11.165 +
11.166 +#define IOMMU_PTE_P (1ULL << 0)
11.167 +#define IOMMU_PTE_TV (1ULL << 1)
11.168 +#define IOMMU_PTE_U (1ULL << 59)
11.169 +#define IOMMU_PTE_FC (1ULL << 60)
11.170 +#define IOMMU_PTE_IR (1ULL << 61)
11.171 +#define IOMMU_PTE_IW (1ULL << 62)
11.172 +
11.173 +#define IOMMU_L1_PDE(address) \
11.174 + ((address) | IOMMU_PDE_NL_1 | IOMMU_PTE_P | IOMMU_PTE_IR | IOMMU_PTE_IW)
11.175 +#define IOMMU_L2_PDE(address) \
11.176 + ((address) | IOMMU_PDE_NL_2 | IOMMU_PTE_P | IOMMU_PTE_IR | IOMMU_PTE_IW)
11.177 +
11.178 +#define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL)
11.179 +#define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P)
11.180 +#define IOMMU_PTE_PAGE(pte) (phys_to_virt((pte) & IOMMU_PAGE_MASK))
11.181 +#define IOMMU_PTE_MODE(pte) (((pte) >> 9) & 0x07)
11.182 +
11.183 +#define IOMMU_PROT_MASK 0x03
11.184 +#define IOMMU_PROT_IR 0x01
11.185 +#define IOMMU_PROT_IW 0x02
11.186 +
11.187 +/* IOMMU capabilities */
11.188 +#define IOMMU_CAP_IOTLB 24
11.189 +#define IOMMU_CAP_NPCACHE 26
11.190 +
11.191 +#define MAX_DOMAIN_ID 65536
11.192 +
11.193 +/* FIXME: move this macro to <linux/pci.h> */
11.194 +#define PCI_BUS(x) (((x) >> 8) & 0xff)
11.195 +
11.196 +/*
11.197 + * This structure contains generic data for IOMMU protection domains
11.198 + * independent of their use.
11.199 + */
11.200 +struct protection_domain {
11.201 + spinlock_t lock; /* mostly used to lock the page table*/
11.202 + u16 id; /* the domain id written to the device table */
11.203 + int mode; /* paging mode (0-6 levels) */
11.204 + u64 *pt_root; /* page table root pointer */
11.205 + void *priv; /* private data */
11.206 +};
11.207 +
11.208 +/*
11.209 + * Data container for a dma_ops specific protection domain
11.210 + */
11.211 +struct dma_ops_domain {
11.212 + struct list_head list;
11.213 +
11.214 + /* generic protection domain information */
11.215 + struct protection_domain domain;
11.216 +
11.217 + /* size of the aperture for the mappings */
11.218 + unsigned long aperture_size;
11.219 +
11.220 + /* address we start to search for free addresses */
11.221 + unsigned long next_bit;
11.222 +
11.223 + /* address allocation bitmap */
11.224 + unsigned long *bitmap;
11.225 +
11.226 + /*
11.227 + * Array of PTE pages for the aperture. In this array we save all the
11.228 + * leaf pages of the domain page table used for the aperture. This way
11.229 + * we don't need to walk the page table to find a specific PTE. We can
11.230 + * just calculate its address in constant time.
11.231 + */
11.232 + u64 **pte_pages;
11.233 +
11.234 + /* This will be set to true when TLB needs to be flushed */
11.235 + bool need_flush;
11.236 +
11.237 + /*
11.238 + * if this is a preallocated domain, keep the device for which it was
11.239 + * preallocated in this variable
11.240 + */
11.241 + u16 target_dev;
11.242 +};
11.243 +
11.244 +/*
11.245 + * Structure where we save information about one hardware AMD IOMMU in the
11.246 + * system.
11.247 + */
11.248 +struct amd_iommu {
11.249 + struct list_head list;
11.250 +
11.251 + /* locks the accesses to the hardware */
11.252 + spinlock_t lock;
11.253 +
11.254 + /* Pointer to PCI device of this IOMMU */
11.255 + struct pci_dev *dev;
11.256 +
11.257 + /* physical address of MMIO space */
11.258 + u64 mmio_phys;
11.259 + /* virtual address of MMIO space */
11.260 + u8 *mmio_base;
11.261 +
11.262 + /* capabilities of that IOMMU read from ACPI */
11.263 + u32 cap;
11.264 +
11.265 + /*
11.266 + * Capability pointer. There could be more than one IOMMU per PCI
11.267 + * device function if there are more than one AMD IOMMU capability
11.268 + * pointers.
11.269 + */
11.270 + u16 cap_ptr;
11.271 +
11.272 + /* pci domain of this IOMMU */
11.273 + u16 pci_seg;
11.274 +
11.275 + /* first device this IOMMU handles. read from PCI */
11.276 + u16 first_device;
11.277 + /* last device this IOMMU handles. read from PCI */
11.278 + u16 last_device;
11.279 +
11.280 + /* start of exclusion range of that IOMMU */
11.281 + u64 exclusion_start;
11.282 + /* length of exclusion range of that IOMMU */
11.283 + u64 exclusion_length;
11.284 +
11.285 + /* command buffer virtual address */
11.286 + u8 *cmd_buf;
11.287 + /* size of command buffer */
11.288 + u32 cmd_buf_size;
11.289 +
11.290 + /* size of event buffer */
11.291 + u32 evt_buf_size;
11.292 + /* event buffer virtual address */
11.293 + u8 *evt_buf;
11.294 + /* MSI number for event interrupt */
11.295 + u16 evt_msi_num;
11.296 +
11.297 + /* true if interrupts for this IOMMU are already enabled */
11.298 + bool int_enabled;
11.299 +
11.300 + /* if one, we need to send a completion wait command */
11.301 + int need_sync;
11.302 +
11.303 + /* default dma_ops domain for that IOMMU */
11.304 + struct dma_ops_domain *default_dom;
11.305 +};
11.306 +
11.307 +/*
11.308 + * List with all IOMMUs in the system. This list is not locked because it is
11.309 + * only written and read at driver initialization or suspend time
11.310 + */
11.311 +extern struct list_head amd_iommu_list;
11.312 +
11.313 +/*
11.314 + * Structure defining one entry in the device table
11.315 + */
11.316 +struct dev_table_entry {
11.317 + u32 data[8];
11.318 +};
11.319 +
11.320 +/*
11.321 + * One entry for unity mappings parsed out of the ACPI table.
11.322 + */
11.323 +struct unity_map_entry {
11.324 + struct list_head list;
11.325 +
11.326 + /* starting device id this entry is used for (including) */
11.327 + u16 devid_start;
11.328 + /* end device id this entry is used for (including) */
11.329 + u16 devid_end;
11.330 +
11.331 + /* start address to unity map (including) */
11.332 + u64 address_start;
11.333 + /* end address to unity map (including) */
11.334 + u64 address_end;
11.335 +
11.336 + /* required protection */
11.337 + int prot;
11.338 +};
11.339 +
11.340 +/*
11.341 + * List of all unity mappings. It is not locked because as runtime it is only
11.342 + * read. It is created at ACPI table parsing time.
11.343 + */
11.344 +extern struct list_head amd_iommu_unity_map;
11.345 +
11.346 +/*
11.347 + * Data structures for device handling
11.348 + */
11.349 +
11.350 +/*
11.351 + * Device table used by hardware. Read and write accesses by software are
11.352 + * locked with the amd_iommu_pd_table lock.
11.353 + */
11.354 +extern struct dev_table_entry *amd_iommu_dev_table;
11.355 +
11.356 +/*
11.357 + * Alias table to find requestor ids to device ids. Not locked because only
11.358 + * read on runtime.
11.359 + */
11.360 +extern u16 *amd_iommu_alias_table;
11.361 +
11.362 +/*
11.363 + * Reverse lookup table to find the IOMMU which translates a specific device.
11.364 + */
11.365 +extern struct amd_iommu **amd_iommu_rlookup_table;
11.366 +
11.367 +/* size of the dma_ops aperture as power of 2 */
11.368 +extern unsigned amd_iommu_aperture_order;
11.369 +
11.370 +/* largest PCI device id we expect translation requests for */
11.371 +extern u16 amd_iommu_last_bdf;
11.372 +
11.373 +/* data structures for protection domain handling */
11.374 +extern struct protection_domain **amd_iommu_pd_table;
11.375 +
11.376 +/* allocation bitmap for domain ids */
11.377 +extern unsigned long *amd_iommu_pd_alloc_bitmap;
11.378 +
11.379 +/* will be 1 if device isolation is enabled */
11.380 +extern int amd_iommu_isolate;
11.381 +
11.382 +/*
11.383 + * If true, the addresses will be flushed on unmap time, not when
11.384 + * they are reused
11.385 + */
11.386 +extern bool amd_iommu_unmap_flush;
11.387 +
11.388 +/* takes a PCI device id and prints it out in a readable form */
11.389 +static inline void print_devid(u16 devid, int nl)
11.390 +{
11.391 + int bus = devid >> 8;
11.392 + int dev = devid >> 3 & 0x1f;
11.393 + int fn = devid & 0x07;
11.394 +
11.395 + printk("%02x:%02x.%x", bus, dev, fn);
11.396 + if (nl)
11.397 + printk("\n");
11.398 +}
11.399 +
11.400 +/* takes bus and device/function and returns the device id
11.401 + * FIXME: should that be in generic PCI code? */
11.402 +static inline u16 calc_devid(u8 bus, u8 devfn)
11.403 +{
11.404 + return (((u16)bus) << 8) | devfn;
11.405 +}
11.406 +
11.407 +#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/arch/x86/include/asm/apic.h Sun Jan 11 20:20:11 2009 +0100
12.3 @@ -0,0 +1,199 @@
12.4 +#ifndef _ASM_X86_APIC_H
12.5 +#define _ASM_X86_APIC_H
12.6 +
12.7 +#include <linux/pm.h>
12.8 +#include <linux/delay.h>
12.9 +
12.10 +#include <asm/alternative.h>
12.11 +#include <asm/fixmap.h>
12.12 +#include <asm/apicdef.h>
12.13 +#include <asm/processor.h>
12.14 +#include <asm/system.h>
12.15 +#include <asm/cpufeature.h>
12.16 +#include <asm/msr.h>
12.17 +
12.18 +#define ARCH_APICTIMER_STOPS_ON_C3 1
12.19 +
12.20 +/*
12.21 + * Debugging macros
12.22 + */
12.23 +#define APIC_QUIET 0
12.24 +#define APIC_VERBOSE 1
12.25 +#define APIC_DEBUG 2
12.26 +
12.27 +/*
12.28 + * Define the default level of output to be very little
12.29 + * This can be turned up by using apic=verbose for more
12.30 + * information and apic=debug for _lots_ of information.
12.31 + * apic_verbosity is defined in apic.c
12.32 + */
12.33 +#define apic_printk(v, s, a...) do { \
12.34 + if ((v) <= apic_verbosity) \
12.35 + printk(s, ##a); \
12.36 + } while (0)
12.37 +
12.38 +
12.39 +extern void generic_apic_probe(void);
12.40 +
12.41 +#ifdef CONFIG_X86_LOCAL_APIC
12.42 +
12.43 +extern unsigned int apic_verbosity;
12.44 +extern int local_apic_timer_c2_ok;
12.45 +
12.46 +extern int disable_apic;
12.47 +/*
12.48 + * Basic functions accessing APICs.
12.49 + */
12.50 +#ifdef CONFIG_PARAVIRT
12.51 +#include <asm/paravirt.h>
12.52 +#else
12.53 +#define setup_boot_clock setup_boot_APIC_clock
12.54 +#define setup_secondary_clock setup_secondary_APIC_clock
12.55 +#endif
12.56 +
12.57 +extern int is_vsmp_box(void);
12.58 +extern void xapic_wait_icr_idle(void);
12.59 +extern u32 safe_xapic_wait_icr_idle(void);
12.60 +extern u64 xapic_icr_read(void);
12.61 +extern void xapic_icr_write(u32, u32);
12.62 +extern int setup_profiling_timer(unsigned int);
12.63 +
12.64 +static inline void native_apic_mem_write(u32 reg, u32 v)
12.65 +{
12.66 + volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
12.67 +
12.68 + alternative_io("movl %0, %1", "xchgl %0, %1", X86_FEATURE_11AP,
12.69 + ASM_OUTPUT2("=r" (v), "=m" (*addr)),
12.70 + ASM_OUTPUT2("0" (v), "m" (*addr)));
12.71 +}
12.72 +
12.73 +static inline u32 native_apic_mem_read(u32 reg)
12.74 +{
12.75 + return *((volatile u32 *)(APIC_BASE + reg));
12.76 +}
12.77 +
12.78 +static inline void native_apic_msr_write(u32 reg, u32 v)
12.79 +{
12.80 + if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
12.81 + reg == APIC_LVR)
12.82 + return;
12.83 +
12.84 + wrmsr(APIC_BASE_MSR + (reg >> 4), v, 0);
12.85 +}
12.86 +
12.87 +static inline u32 native_apic_msr_read(u32 reg)
12.88 +{
12.89 + u32 low, high;
12.90 +
12.91 + if (reg == APIC_DFR)
12.92 + return -1;
12.93 +
12.94 + rdmsr(APIC_BASE_MSR + (reg >> 4), low, high);
12.95 + return low;
12.96 +}
12.97 +
12.98 +#ifndef CONFIG_X86_32
12.99 +extern int x2apic, x2apic_preenabled;
12.100 +extern void check_x2apic(void);
12.101 +extern void enable_x2apic(void);
12.102 +extern void enable_IR_x2apic(void);
12.103 +extern void x2apic_icr_write(u32 low, u32 id);
12.104 +static inline int x2apic_enabled(void)
12.105 +{
12.106 + int msr, msr2;
12.107 +
12.108 + if (!cpu_has_x2apic)
12.109 + return 0;
12.110 +
12.111 + rdmsr(MSR_IA32_APICBASE, msr, msr2);
12.112 + if (msr & X2APIC_ENABLE)
12.113 + return 1;
12.114 + return 0;
12.115 +}
12.116 +#else
12.117 +#define x2apic_enabled() 0
12.118 +#endif
12.119 +
12.120 +struct apic_ops {
12.121 + u32 (*read)(u32 reg);
12.122 + void (*write)(u32 reg, u32 v);
12.123 + u64 (*icr_read)(void);
12.124 + void (*icr_write)(u32 low, u32 high);
12.125 + void (*wait_icr_idle)(void);
12.126 + u32 (*safe_wait_icr_idle)(void);
12.127 +};
12.128 +
12.129 +extern struct apic_ops *apic_ops;
12.130 +
12.131 +#define apic_read (apic_ops->read)
12.132 +#define apic_write (apic_ops->write)
12.133 +#define apic_icr_read (apic_ops->icr_read)
12.134 +#define apic_icr_write (apic_ops->icr_write)
12.135 +#define apic_wait_icr_idle (apic_ops->wait_icr_idle)
12.136 +#define safe_apic_wait_icr_idle (apic_ops->safe_wait_icr_idle)
12.137 +
12.138 +extern int get_physical_broadcast(void);
12.139 +
12.140 +#ifdef CONFIG_X86_64
12.141 +static inline void ack_x2APIC_irq(void)
12.142 +{
12.143 + /* Docs say use 0 for future compatibility */
12.144 + native_apic_msr_write(APIC_EOI, 0);
12.145 +}
12.146 +#endif
12.147 +
12.148 +
12.149 +static inline void ack_APIC_irq(void)
12.150 +{
12.151 + /*
12.152 + * ack_APIC_irq() actually gets compiled as a single instruction
12.153 + * ... yummie.
12.154 + */
12.155 +
12.156 + /* Docs say use 0 for future compatibility */
12.157 + apic_write(APIC_EOI, 0);
12.158 +}
12.159 +
12.160 +extern int lapic_get_maxlvt(void);
12.161 +extern void clear_local_APIC(void);
12.162 +extern void connect_bsp_APIC(void);
12.163 +extern void disconnect_bsp_APIC(int virt_wire_setup);
12.164 +extern void disable_local_APIC(void);
12.165 +extern void lapic_shutdown(void);
12.166 +extern int verify_local_APIC(void);
12.167 +extern void cache_APIC_registers(void);
12.168 +extern void sync_Arb_IDs(void);
12.169 +extern void init_bsp_APIC(void);
12.170 +extern void setup_local_APIC(void);
12.171 +extern void end_local_APIC_setup(void);
12.172 +extern void init_apic_mappings(void);
12.173 +extern void setup_boot_APIC_clock(void);
12.174 +extern void setup_secondary_APIC_clock(void);
12.175 +extern int APIC_init_uniprocessor(void);
12.176 +extern void enable_NMI_through_LVT0(void);
12.177 +
12.178 +/*
12.179 + * On 32bit this is mach-xxx local
12.180 + */
12.181 +#ifdef CONFIG_X86_64
12.182 +extern void early_init_lapic_mapping(void);
12.183 +extern int apic_is_clustered_box(void);
12.184 +#else
12.185 +static inline int apic_is_clustered_box(void)
12.186 +{
12.187 + return 0;
12.188 +}
12.189 +#endif
12.190 +
12.191 +extern u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask);
12.192 +extern u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask);
12.193 +
12.194 +
12.195 +#else /* !CONFIG_X86_LOCAL_APIC */
12.196 +static inline void lapic_shutdown(void) { }
12.197 +#define local_apic_timer_c2_ok 1
12.198 +static inline void init_apic_mappings(void) { }
12.199 +
12.200 +#endif /* !CONFIG_X86_LOCAL_APIC */
12.201 +
12.202 +#endif /* _ASM_X86_APIC_H */
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/arch/x86/include/asm/apicdef.h Sun Jan 11 20:20:11 2009 +0100
13.3 @@ -0,0 +1,417 @@
13.4 +#ifndef _ASM_X86_APICDEF_H
13.5 +#define _ASM_X86_APICDEF_H
13.6 +
13.7 +/*
13.8 + * Constants for various Intel APICs. (local APIC, IOAPIC, etc.)
13.9 + *
13.10 + * Alan Cox <Alan.Cox@linux.org>, 1995.
13.11 + * Ingo Molnar <mingo@redhat.com>, 1999, 2000
13.12 + */
13.13 +
13.14 +#define APIC_DEFAULT_PHYS_BASE 0xfee00000
13.15 +
13.16 +#define APIC_ID 0x20
13.17 +
13.18 +#define APIC_LVR 0x30
13.19 +#define APIC_LVR_MASK 0xFF00FF
13.20 +#define GET_APIC_VERSION(x) ((x) & 0xFFu)
13.21 +#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFFu)
13.22 +#ifdef CONFIG_X86_32
13.23 +# define APIC_INTEGRATED(x) ((x) & 0xF0u)
13.24 +#else
13.25 +# define APIC_INTEGRATED(x) (1)
13.26 +#endif
13.27 +#define APIC_XAPIC(x) ((x) >= 0x14)
13.28 +#define APIC_TASKPRI 0x80
13.29 +#define APIC_TPRI_MASK 0xFFu
13.30 +#define APIC_ARBPRI 0x90
13.31 +#define APIC_ARBPRI_MASK 0xFFu
13.32 +#define APIC_PROCPRI 0xA0
13.33 +#define APIC_EOI 0xB0
13.34 +#define APIC_EIO_ACK 0x0
13.35 +#define APIC_RRR 0xC0
13.36 +#define APIC_LDR 0xD0
13.37 +#define APIC_LDR_MASK (0xFFu << 24)
13.38 +#define GET_APIC_LOGICAL_ID(x) (((x) >> 24) & 0xFFu)
13.39 +#define SET_APIC_LOGICAL_ID(x) (((x) << 24))
13.40 +#define APIC_ALL_CPUS 0xFFu
13.41 +#define APIC_DFR 0xE0
13.42 +#define APIC_DFR_CLUSTER 0x0FFFFFFFul
13.43 +#define APIC_DFR_FLAT 0xFFFFFFFFul
13.44 +#define APIC_SPIV 0xF0
13.45 +#define APIC_SPIV_FOCUS_DISABLED (1 << 9)
13.46 +#define APIC_SPIV_APIC_ENABLED (1 << 8)
13.47 +#define APIC_ISR 0x100
13.48 +#define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */
13.49 +#define APIC_TMR 0x180
13.50 +#define APIC_IRR 0x200
13.51 +#define APIC_ESR 0x280
13.52 +#define APIC_ESR_SEND_CS 0x00001
13.53 +#define APIC_ESR_RECV_CS 0x00002
13.54 +#define APIC_ESR_SEND_ACC 0x00004
13.55 +#define APIC_ESR_RECV_ACC 0x00008
13.56 +#define APIC_ESR_SENDILL 0x00020
13.57 +#define APIC_ESR_RECVILL 0x00040
13.58 +#define APIC_ESR_ILLREGA 0x00080
13.59 +#define APIC_ICR 0x300
13.60 +#define APIC_DEST_SELF 0x40000
13.61 +#define APIC_DEST_ALLINC 0x80000
13.62 +#define APIC_DEST_ALLBUT 0xC0000
13.63 +#define APIC_ICR_RR_MASK 0x30000
13.64 +#define APIC_ICR_RR_INVALID 0x00000
13.65 +#define APIC_ICR_RR_INPROG 0x10000
13.66 +#define APIC_ICR_RR_VALID 0x20000
13.67 +#define APIC_INT_LEVELTRIG 0x08000
13.68 +#define APIC_INT_ASSERT 0x04000
13.69 +#define APIC_ICR_BUSY 0x01000
13.70 +#define APIC_DEST_LOGICAL 0x00800
13.71 +#define APIC_DEST_PHYSICAL 0x00000
13.72 +#define APIC_DM_FIXED 0x00000
13.73 +#define APIC_DM_LOWEST 0x00100
13.74 +#define APIC_DM_SMI 0x00200
13.75 +#define APIC_DM_REMRD 0x00300
13.76 +#define APIC_DM_NMI 0x00400
13.77 +#define APIC_DM_INIT 0x00500
13.78 +#define APIC_DM_STARTUP 0x00600
13.79 +#define APIC_DM_EXTINT 0x00700
13.80 +#define APIC_VECTOR_MASK 0x000FF
13.81 +#define APIC_ICR2 0x310
13.82 +#define GET_APIC_DEST_FIELD(x) (((x) >> 24) & 0xFF)
13.83 +#define SET_APIC_DEST_FIELD(x) ((x) << 24)
13.84 +#define APIC_LVTT 0x320
13.85 +#define APIC_LVTTHMR 0x330
13.86 +#define APIC_LVTPC 0x340
13.87 +#define APIC_LVT0 0x350
13.88 +#define APIC_LVT_TIMER_BASE_MASK (0x3 << 18)
13.89 +#define GET_APIC_TIMER_BASE(x) (((x) >> 18) & 0x3)
13.90 +#define SET_APIC_TIMER_BASE(x) (((x) << 18))
13.91 +#define APIC_TIMER_BASE_CLKIN 0x0
13.92 +#define APIC_TIMER_BASE_TMBASE 0x1
13.93 +#define APIC_TIMER_BASE_DIV 0x2
13.94 +#define APIC_LVT_TIMER_PERIODIC (1 << 17)
13.95 +#define APIC_LVT_MASKED (1 << 16)
13.96 +#define APIC_LVT_LEVEL_TRIGGER (1 << 15)
13.97 +#define APIC_LVT_REMOTE_IRR (1 << 14)
13.98 +#define APIC_INPUT_POLARITY (1 << 13)
13.99 +#define APIC_SEND_PENDING (1 << 12)
13.100 +#define APIC_MODE_MASK 0x700
13.101 +#define GET_APIC_DELIVERY_MODE(x) (((x) >> 8) & 0x7)
13.102 +#define SET_APIC_DELIVERY_MODE(x, y) (((x) & ~0x700) | ((y) << 8))
13.103 +#define APIC_MODE_FIXED 0x0
13.104 +#define APIC_MODE_NMI 0x4
13.105 +#define APIC_MODE_EXTINT 0x7
13.106 +#define APIC_LVT1 0x360
13.107 +#define APIC_LVTERR 0x370
13.108 +#define APIC_TMICT 0x380
13.109 +#define APIC_TMCCT 0x390
13.110 +#define APIC_TDCR 0x3E0
13.111 +#define APIC_SELF_IPI 0x3F0
13.112 +#define APIC_TDR_DIV_TMBASE (1 << 2)
13.113 +#define APIC_TDR_DIV_1 0xB
13.114 +#define APIC_TDR_DIV_2 0x0
13.115 +#define APIC_TDR_DIV_4 0x1
13.116 +#define APIC_TDR_DIV_8 0x2
13.117 +#define APIC_TDR_DIV_16 0x3
13.118 +#define APIC_TDR_DIV_32 0x8
13.119 +#define APIC_TDR_DIV_64 0x9
13.120 +#define APIC_TDR_DIV_128 0xA
13.121 +#define APIC_EILVT0 0x500
13.122 +#define APIC_EILVT_NR_AMD_K8 1 /* # of extended interrupts */
13.123 +#define APIC_EILVT_NR_AMD_10H 4
13.124 +#define APIC_EILVT_LVTOFF(x) (((x) >> 4) & 0xF)
13.125 +#define APIC_EILVT_MSG_FIX 0x0
13.126 +#define APIC_EILVT_MSG_SMI 0x2
13.127 +#define APIC_EILVT_MSG_NMI 0x4
13.128 +#define APIC_EILVT_MSG_EXT 0x7
13.129 +#define APIC_EILVT_MASKED (1 << 16)
13.130 +#define APIC_EILVT1 0x510
13.131 +#define APIC_EILVT2 0x520
13.132 +#define APIC_EILVT3 0x530
13.133 +
13.134 +#define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
13.135 +#define APIC_BASE_MSR 0x800
13.136 +#define X2APIC_ENABLE (1UL << 10)
13.137 +
13.138 +#ifdef CONFIG_X86_32
13.139 +# define MAX_IO_APICS 64
13.140 +#else
13.141 +# define MAX_IO_APICS 128
13.142 +# define MAX_LOCAL_APIC 32768
13.143 +#endif
13.144 +
13.145 +/*
13.146 + * All x86-64 systems are xAPIC compatible.
13.147 + * In the following, "apicid" is a physical APIC ID.
13.148 + */
13.149 +#define XAPIC_DEST_CPUS_SHIFT 4
13.150 +#define XAPIC_DEST_CPUS_MASK ((1u << XAPIC_DEST_CPUS_SHIFT) - 1)
13.151 +#define XAPIC_DEST_CLUSTER_MASK (XAPIC_DEST_CPUS_MASK << XAPIC_DEST_CPUS_SHIFT)
13.152 +#define APIC_CLUSTER(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK)
13.153 +#define APIC_CLUSTERID(apicid) (APIC_CLUSTER(apicid) >> XAPIC_DEST_CPUS_SHIFT)
13.154 +#define APIC_CPUID(apicid) ((apicid) & XAPIC_DEST_CPUS_MASK)
13.155 +#define NUM_APIC_CLUSTERS ((BAD_APICID + 1) >> XAPIC_DEST_CPUS_SHIFT)
13.156 +
13.157 +/*
13.158 + * the local APIC register structure, memory mapped. Not terribly well
13.159 + * tested, but we might eventually use this one in the future - the
13.160 + * problem why we cannot use it right now is the P5 APIC, it has an
13.161 + * errata which cannot take 8-bit reads and writes, only 32-bit ones ...
13.162 + */
13.163 +#define u32 unsigned int
13.164 +
13.165 +struct local_apic {
13.166 +
13.167 +/*000*/ struct { u32 __reserved[4]; } __reserved_01;
13.168 +
13.169 +/*010*/ struct { u32 __reserved[4]; } __reserved_02;
13.170 +
13.171 +/*020*/ struct { /* APIC ID Register */
13.172 + u32 __reserved_1 : 24,
13.173 + phys_apic_id : 4,
13.174 + __reserved_2 : 4;
13.175 + u32 __reserved[3];
13.176 + } id;
13.177 +
13.178 +/*030*/ const
13.179 + struct { /* APIC Version Register */
13.180 + u32 version : 8,
13.181 + __reserved_1 : 8,
13.182 + max_lvt : 8,
13.183 + __reserved_2 : 8;
13.184 + u32 __reserved[3];
13.185 + } version;
13.186 +
13.187 +/*040*/ struct { u32 __reserved[4]; } __reserved_03;
13.188 +
13.189 +/*050*/ struct { u32 __reserved[4]; } __reserved_04;
13.190 +
13.191 +/*060*/ struct { u32 __reserved[4]; } __reserved_05;
13.192 +
13.193 +/*070*/ struct { u32 __reserved[4]; } __reserved_06;
13.194 +
13.195 +/*080*/ struct { /* Task Priority Register */
13.196 + u32 priority : 8,
13.197 + __reserved_1 : 24;
13.198 + u32 __reserved_2[3];
13.199 + } tpr;
13.200 +
13.201 +/*090*/ const
13.202 + struct { /* Arbitration Priority Register */
13.203 + u32 priority : 8,
13.204 + __reserved_1 : 24;
13.205 + u32 __reserved_2[3];
13.206 + } apr;
13.207 +
13.208 +/*0A0*/ const
13.209 + struct { /* Processor Priority Register */
13.210 + u32 priority : 8,
13.211 + __reserved_1 : 24;
13.212 + u32 __reserved_2[3];
13.213 + } ppr;
13.214 +
13.215 +/*0B0*/ struct { /* End Of Interrupt Register */
13.216 + u32 eoi;
13.217 + u32 __reserved[3];
13.218 + } eoi;
13.219 +
13.220 +/*0C0*/ struct { u32 __reserved[4]; } __reserved_07;
13.221 +
13.222 +/*0D0*/ struct { /* Logical Destination Register */
13.223 + u32 __reserved_1 : 24,
13.224 + logical_dest : 8;
13.225 + u32 __reserved_2[3];
13.226 + } ldr;
13.227 +
13.228 +/*0E0*/ struct { /* Destination Format Register */
13.229 + u32 __reserved_1 : 28,
13.230 + model : 4;
13.231 + u32 __reserved_2[3];
13.232 + } dfr;
13.233 +
13.234 +/*0F0*/ struct { /* Spurious Interrupt Vector Register */
13.235 + u32 spurious_vector : 8,
13.236 + apic_enabled : 1,
13.237 + focus_cpu : 1,
13.238 + __reserved_2 : 22;
13.239 + u32 __reserved_3[3];
13.240 + } svr;
13.241 +
13.242 +/*100*/ struct { /* In Service Register */
13.243 +/*170*/ u32 bitfield;
13.244 + u32 __reserved[3];
13.245 + } isr [8];
13.246 +
13.247 +/*180*/ struct { /* Trigger Mode Register */
13.248 +/*1F0*/ u32 bitfield;
13.249 + u32 __reserved[3];
13.250 + } tmr [8];
13.251 +
13.252 +/*200*/ struct { /* Interrupt Request Register */
13.253 +/*270*/ u32 bitfield;
13.254 + u32 __reserved[3];
13.255 + } irr [8];
13.256 +
13.257 +/*280*/ union { /* Error Status Register */
13.258 + struct {
13.259 + u32 send_cs_error : 1,
13.260 + receive_cs_error : 1,
13.261 + send_accept_error : 1,
13.262 + receive_accept_error : 1,
13.263 + __reserved_1 : 1,
13.264 + send_illegal_vector : 1,
13.265 + receive_illegal_vector : 1,
13.266 + illegal_register_address : 1,
13.267 + __reserved_2 : 24;
13.268 + u32 __reserved_3[3];
13.269 + } error_bits;
13.270 + struct {
13.271 + u32 errors;
13.272 + u32 __reserved_3[3];
13.273 + } all_errors;
13.274 + } esr;
13.275 +
13.276 +/*290*/ struct { u32 __reserved[4]; } __reserved_08;
13.277 +
13.278 +/*2A0*/ struct { u32 __reserved[4]; } __reserved_09;
13.279 +
13.280 +/*2B0*/ struct { u32 __reserved[4]; } __reserved_10;
13.281 +
13.282 +/*2C0*/ struct { u32 __reserved[4]; } __reserved_11;
13.283 +
13.284 +/*2D0*/ struct { u32 __reserved[4]; } __reserved_12;
13.285 +
13.286 +/*2E0*/ struct { u32 __reserved[4]; } __reserved_13;
13.287 +
13.288 +/*2F0*/ struct { u32 __reserved[4]; } __reserved_14;
13.289 +
13.290 +/*300*/ struct { /* Interrupt Command Register 1 */
13.291 + u32 vector : 8,
13.292 + delivery_mode : 3,
13.293 + destination_mode : 1,
13.294 + delivery_status : 1,
13.295 + __reserved_1 : 1,
13.296 + level : 1,
13.297 + trigger : 1,
13.298 + __reserved_2 : 2,
13.299 + shorthand : 2,
13.300 + __reserved_3 : 12;
13.301 + u32 __reserved_4[3];
13.302 + } icr1;
13.303 +
13.304 +/*310*/ struct { /* Interrupt Command Register 2 */
13.305 + union {
13.306 + u32 __reserved_1 : 24,
13.307 + phys_dest : 4,
13.308 + __reserved_2 : 4;
13.309 + u32 __reserved_3 : 24,
13.310 + logical_dest : 8;
13.311 + } dest;
13.312 + u32 __reserved_4[3];
13.313 + } icr2;
13.314 +
13.315 +/*320*/ struct { /* LVT - Timer */
13.316 + u32 vector : 8,
13.317 + __reserved_1 : 4,
13.318 + delivery_status : 1,
13.319 + __reserved_2 : 3,
13.320 + mask : 1,
13.321 + timer_mode : 1,
13.322 + __reserved_3 : 14;
13.323 + u32 __reserved_4[3];
13.324 + } lvt_timer;
13.325 +
13.326 +/*330*/ struct { /* LVT - Thermal Sensor */
13.327 + u32 vector : 8,
13.328 + delivery_mode : 3,
13.329 + __reserved_1 : 1,
13.330 + delivery_status : 1,
13.331 + __reserved_2 : 3,
13.332 + mask : 1,
13.333 + __reserved_3 : 15;
13.334 + u32 __reserved_4[3];
13.335 + } lvt_thermal;
13.336 +
13.337 +/*340*/ struct { /* LVT - Performance Counter */
13.338 + u32 vector : 8,
13.339 + delivery_mode : 3,
13.340 + __reserved_1 : 1,
13.341 + delivery_status : 1,
13.342 + __reserved_2 : 3,
13.343 + mask : 1,
13.344 + __reserved_3 : 15;
13.345 + u32 __reserved_4[3];
13.346 + } lvt_pc;
13.347 +
13.348 +/*350*/ struct { /* LVT - LINT0 */
13.349 + u32 vector : 8,
13.350 + delivery_mode : 3,
13.351 + __reserved_1 : 1,
13.352 + delivery_status : 1,
13.353 + polarity : 1,
13.354 + remote_irr : 1,
13.355 + trigger : 1,
13.356 + mask : 1,
13.357 + __reserved_2 : 15;
13.358 + u32 __reserved_3[3];
13.359 + } lvt_lint0;
13.360 +
13.361 +/*360*/ struct { /* LVT - LINT1 */
13.362 + u32 vector : 8,
13.363 + delivery_mode : 3,
13.364 + __reserved_1 : 1,
13.365 + delivery_status : 1,
13.366 + polarity : 1,
13.367 + remote_irr : 1,
13.368 + trigger : 1,
13.369 + mask : 1,
13.370 + __reserved_2 : 15;
13.371 + u32 __reserved_3[3];
13.372 + } lvt_lint1;
13.373 +
13.374 +/*370*/ struct { /* LVT - Error */
13.375 + u32 vector : 8,
13.376 + __reserved_1 : 4,
13.377 + delivery_status : 1,
13.378 + __reserved_2 : 3,
13.379 + mask : 1,
13.380 + __reserved_3 : 15;
13.381 + u32 __reserved_4[3];
13.382 + } lvt_error;
13.383 +
13.384 +/*380*/ struct { /* Timer Initial Count Register */
13.385 + u32 initial_count;
13.386 + u32 __reserved_2[3];
13.387 + } timer_icr;
13.388 +
13.389 +/*390*/ const
13.390 + struct { /* Timer Current Count Register */
13.391 + u32 curr_count;
13.392 + u32 __reserved_2[3];
13.393 + } timer_ccr;
13.394 +
13.395 +/*3A0*/ struct { u32 __reserved[4]; } __reserved_16;
13.396 +
13.397 +/*3B0*/ struct { u32 __reserved[4]; } __reserved_17;
13.398 +
13.399 +/*3C0*/ struct { u32 __reserved[4]; } __reserved_18;
13.400 +
13.401 +/*3D0*/ struct { u32 __reserved[4]; } __reserved_19;
13.402 +
13.403 +/*3E0*/ struct { /* Timer Divide Configuration Register */
13.404 + u32 divisor : 4,
13.405 + __reserved_1 : 28;
13.406 + u32 __reserved_2[3];
13.407 + } timer_dcr;
13.408 +
13.409 +/*3F0*/ struct { u32 __reserved[4]; } __reserved_20;
13.410 +
13.411 +} __attribute__ ((packed));
13.412 +
13.413 +#undef u32
13.414 +
13.415 +#ifdef CONFIG_X86_32
13.416 + #define BAD_APICID 0xFFu
13.417 +#else
13.418 + #define BAD_APICID 0xFFFFu
13.419 +#endif
13.420 +#endif /* _ASM_X86_APICDEF_H */
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/arch/x86/include/asm/arch_hooks.h Sun Jan 11 20:20:11 2009 +0100
14.3 @@ -0,0 +1,26 @@
14.4 +#ifndef _ASM_X86_ARCH_HOOKS_H
14.5 +#define _ASM_X86_ARCH_HOOKS_H
14.6 +
14.7 +#include <linux/interrupt.h>
14.8 +
14.9 +/*
14.10 + * linux/include/asm/arch_hooks.h
14.11 + *
14.12 + * define the architecture specific hooks
14.13 + */
14.14 +
14.15 +/* these aren't arch hooks, they are generic routines
14.16 + * that can be used by the hooks */
14.17 +extern void init_ISA_irqs(void);
14.18 +extern irqreturn_t timer_interrupt(int irq, void *dev_id);
14.19 +
14.20 +/* these are the defined hooks */
14.21 +extern void intr_init_hook(void);
14.22 +extern void pre_intr_init_hook(void);
14.23 +extern void pre_setup_arch_hook(void);
14.24 +extern void trap_init_hook(void);
14.25 +extern void pre_time_init_hook(void);
14.26 +extern void time_init_hook(void);
14.27 +extern void mca_nmi_hook(void);
14.28 +
14.29 +#endif /* _ASM_X86_ARCH_HOOKS_H */
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/arch/x86/include/asm/asm.h Sun Jan 11 20:20:11 2009 +0100
15.3 @@ -0,0 +1,47 @@
15.4 +#ifndef _ASM_X86_ASM_H
15.5 +#define _ASM_X86_ASM_H
15.6 +
15.7 +#ifdef __ASSEMBLY__
15.8 +# define __ASM_FORM(x) x
15.9 +# define __ASM_EX_SEC .section __ex_table
15.10 +#else
15.11 +# define __ASM_FORM(x) " " #x " "
15.12 +# define __ASM_EX_SEC " .section __ex_table,\"a\"\n"
15.13 +#endif
15.14 +
15.15 +#ifdef CONFIG_X86_32
15.16 +# define __ASM_SEL(a,b) __ASM_FORM(a)
15.17 +#else
15.18 +# define __ASM_SEL(a,b) __ASM_FORM(b)
15.19 +#endif
15.20 +
15.21 +#define __ASM_SIZE(inst) __ASM_SEL(inst##l, inst##q)
15.22 +#define __ASM_REG(reg) __ASM_SEL(e##reg, r##reg)
15.23 +
15.24 +#define _ASM_PTR __ASM_SEL(.long, .quad)
15.25 +#define _ASM_ALIGN __ASM_SEL(.balign 4, .balign 8)
15.26 +
15.27 +#define _ASM_MOV __ASM_SIZE(mov)
15.28 +#define _ASM_INC __ASM_SIZE(inc)
15.29 +#define _ASM_DEC __ASM_SIZE(dec)
15.30 +#define _ASM_ADD __ASM_SIZE(add)
15.31 +#define _ASM_SUB __ASM_SIZE(sub)
15.32 +#define _ASM_XADD __ASM_SIZE(xadd)
15.33 +
15.34 +#define _ASM_AX __ASM_REG(ax)
15.35 +#define _ASM_BX __ASM_REG(bx)
15.36 +#define _ASM_CX __ASM_REG(cx)
15.37 +#define _ASM_DX __ASM_REG(dx)
15.38 +#define _ASM_SP __ASM_REG(sp)
15.39 +#define _ASM_BP __ASM_REG(bp)
15.40 +#define _ASM_SI __ASM_REG(si)
15.41 +#define _ASM_DI __ASM_REG(di)
15.42 +
15.43 +/* Exception table entry */
15.44 +# define _ASM_EXTABLE(from,to) \
15.45 + __ASM_EX_SEC \
15.46 + _ASM_ALIGN "\n" \
15.47 + _ASM_PTR #from "," #to "\n" \
15.48 + " .previous\n"
15.49 +
15.50 +#endif /* _ASM_X86_ASM_H */
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/arch/x86/include/asm/atomic.h Sun Jan 11 20:20:11 2009 +0100
16.3 @@ -0,0 +1,5 @@
16.4 +#ifdef CONFIG_X86_32
16.5 +# include "atomic_32.h"
16.6 +#else
16.7 +# include "atomic_64.h"
16.8 +#endif
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/arch/x86/include/asm/atomic_32.h Sun Jan 11 20:20:11 2009 +0100
17.3 @@ -0,0 +1,259 @@
17.4 +#ifndef _ASM_X86_ATOMIC_32_H
17.5 +#define _ASM_X86_ATOMIC_32_H
17.6 +
17.7 +#include <linux/compiler.h>
17.8 +#include <asm/processor.h>
17.9 +#include <asm/cmpxchg.h>
17.10 +
17.11 +/*
17.12 + * Atomic operations that C can't guarantee us. Useful for
17.13 + * resource counting etc..
17.14 + */
17.15 +
17.16 +/*
17.17 + * Make sure gcc doesn't try to be clever and move things around
17.18 + * on us. We need to use _exactly_ the address the user gave us,
17.19 + * not some alias that contains the same information.
17.20 + */
17.21 +typedef struct {
17.22 + int counter;
17.23 +} atomic_t;
17.24 +
17.25 +#define ATOMIC_INIT(i) { (i) }
17.26 +
17.27 +/**
17.28 + * atomic_read - read atomic variable
17.29 + * @v: pointer of type atomic_t
17.30 + *
17.31 + * Atomically reads the value of @v.
17.32 + */
17.33 +#define atomic_read(v) ((v)->counter)
17.34 +
17.35 +/**
17.36 + * atomic_set - set atomic variable
17.37 + * @v: pointer of type atomic_t
17.38 + * @i: required value
17.39 + *
17.40 + * Atomically sets the value of @v to @i.
17.41 + */
17.42 +#define atomic_set(v, i) (((v)->counter) = (i))
17.43 +
17.44 +/**
17.45 + * atomic_add - add integer to atomic variable
17.46 + * @i: integer value to add
17.47 + * @v: pointer of type atomic_t
17.48 + *
17.49 + * Atomically adds @i to @v.
17.50 + */
17.51 +static inline void atomic_add(int i, atomic_t *v)
17.52 +{
17.53 + asm volatile(LOCK_PREFIX "addl %1,%0"
17.54 + : "+m" (v->counter)
17.55 + : "ir" (i));
17.56 +}
17.57 +
17.58 +/**
17.59 + * atomic_sub - subtract integer from atomic variable
17.60 + * @i: integer value to subtract
17.61 + * @v: pointer of type atomic_t
17.62 + *
17.63 + * Atomically subtracts @i from @v.
17.64 + */
17.65 +static inline void atomic_sub(int i, atomic_t *v)
17.66 +{
17.67 + asm volatile(LOCK_PREFIX "subl %1,%0"
17.68 + : "+m" (v->counter)
17.69 + : "ir" (i));
17.70 +}
17.71 +
17.72 +/**
17.73 + * atomic_sub_and_test - subtract value from variable and test result
17.74 + * @i: integer value to subtract
17.75 + * @v: pointer of type atomic_t
17.76 + *
17.77 + * Atomically subtracts @i from @v and returns
17.78 + * true if the result is zero, or false for all
17.79 + * other cases.
17.80 + */
17.81 +static inline int atomic_sub_and_test(int i, atomic_t *v)
17.82 +{
17.83 + unsigned char c;
17.84 +
17.85 + asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
17.86 + : "+m" (v->counter), "=qm" (c)
17.87 + : "ir" (i) : "memory");
17.88 + return c;
17.89 +}
17.90 +
17.91 +/**
17.92 + * atomic_inc - increment atomic variable
17.93 + * @v: pointer of type atomic_t
17.94 + *
17.95 + * Atomically increments @v by 1.
17.96 + */
17.97 +static inline void atomic_inc(atomic_t *v)
17.98 +{
17.99 + asm volatile(LOCK_PREFIX "incl %0"
17.100 + : "+m" (v->counter));
17.101 +}
17.102 +
17.103 +/**
17.104 + * atomic_dec - decrement atomic variable
17.105 + * @v: pointer of type atomic_t
17.106 + *
17.107 + * Atomically decrements @v by 1.
17.108 + */
17.109 +static inline void atomic_dec(atomic_t *v)
17.110 +{
17.111 + asm volatile(LOCK_PREFIX "decl %0"
17.112 + : "+m" (v->counter));
17.113 +}
17.114 +
17.115 +/**
17.116 + * atomic_dec_and_test - decrement and test
17.117 + * @v: pointer of type atomic_t
17.118 + *
17.119 + * Atomically decrements @v by 1 and
17.120 + * returns true if the result is 0, or false for all other
17.121 + * cases.
17.122 + */
17.123 +static inline int atomic_dec_and_test(atomic_t *v)
17.124 +{
17.125 + unsigned char c;
17.126 +
17.127 + asm volatile(LOCK_PREFIX "decl %0; sete %1"
17.128 + : "+m" (v->counter), "=qm" (c)
17.129 + : : "memory");
17.130 + return c != 0;
17.131 +}
17.132 +
17.133 +/**
17.134 + * atomic_inc_and_test - increment and test
17.135 + * @v: pointer of type atomic_t
17.136 + *
17.137 + * Atomically increments @v by 1
17.138 + * and returns true if the result is zero, or false for all
17.139 + * other cases.
17.140 + */
17.141 +static inline int atomic_inc_and_test(atomic_t *v)
17.142 +{
17.143 + unsigned char c;
17.144 +
17.145 + asm volatile(LOCK_PREFIX "incl %0; sete %1"
17.146 + : "+m" (v->counter), "=qm" (c)
17.147 + : : "memory");
17.148 + return c != 0;
17.149 +}
17.150 +
17.151 +/**
17.152 + * atomic_add_negative - add and test if negative
17.153 + * @v: pointer of type atomic_t
17.154 + * @i: integer value to add
17.155 + *
17.156 + * Atomically adds @i to @v and returns true
17.157 + * if the result is negative, or false when
17.158 + * result is greater than or equal to zero.
17.159 + */
17.160 +static inline int atomic_add_negative(int i, atomic_t *v)
17.161 +{
17.162 + unsigned char c;
17.163 +
17.164 + asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
17.165 + : "+m" (v->counter), "=qm" (c)
17.166 + : "ir" (i) : "memory");
17.167 + return c;
17.168 +}
17.169 +
17.170 +/**
17.171 + * atomic_add_return - add integer and return
17.172 + * @v: pointer of type atomic_t
17.173 + * @i: integer value to add
17.174 + *
17.175 + * Atomically adds @i to @v and returns @i + @v
17.176 + */
17.177 +static inline int atomic_add_return(int i, atomic_t *v)
17.178 +{
17.179 + int __i;
17.180 +#ifdef CONFIG_M386
17.181 + unsigned long flags;
17.182 + if (unlikely(boot_cpu_data.x86 <= 3))
17.183 + goto no_xadd;
17.184 +#endif
17.185 + /* Modern 486+ processor */
17.186 + __i = i;
17.187 + asm volatile(LOCK_PREFIX "xaddl %0, %1"
17.188 + : "+r" (i), "+m" (v->counter)
17.189 + : : "memory");
17.190 + return i + __i;
17.191 +
17.192 +#ifdef CONFIG_M386
17.193 +no_xadd: /* Legacy 386 processor */
17.194 + local_irq_save(flags);
17.195 + __i = atomic_read(v);
17.196 + atomic_set(v, i + __i);
17.197 + local_irq_restore(flags);
17.198 + return i + __i;
17.199 +#endif
17.200 +}
17.201 +
17.202 +/**
17.203 + * atomic_sub_return - subtract integer and return
17.204 + * @v: pointer of type atomic_t
17.205 + * @i: integer value to subtract
17.206 + *
17.207 + * Atomically subtracts @i from @v and returns @v - @i
17.208 + */
17.209 +static inline int atomic_sub_return(int i, atomic_t *v)
17.210 +{
17.211 + return atomic_add_return(-i, v);
17.212 +}
17.213 +
17.214 +#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
17.215 +#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
17.216 +
17.217 +/**
17.218 + * atomic_add_unless - add unless the number is already a given value
17.219 + * @v: pointer of type atomic_t
17.220 + * @a: the amount to add to v...
17.221 + * @u: ...unless v is equal to u.
17.222 + *
17.223 + * Atomically adds @a to @v, so long as @v was not already @u.
17.224 + * Returns non-zero if @v was not @u, and zero otherwise.
17.225 + */
17.226 +static inline int atomic_add_unless(atomic_t *v, int a, int u)
17.227 +{
17.228 + int c, old;
17.229 + c = atomic_read(v);
17.230 + for (;;) {
17.231 + if (unlikely(c == (u)))
17.232 + break;
17.233 + old = atomic_cmpxchg((v), c, c + (a));
17.234 + if (likely(old == c))
17.235 + break;
17.236 + c = old;
17.237 + }
17.238 + return c != (u);
17.239 +}
17.240 +
17.241 +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
17.242 +
17.243 +#define atomic_inc_return(v) (atomic_add_return(1, v))
17.244 +#define atomic_dec_return(v) (atomic_sub_return(1, v))
17.245 +
17.246 +/* These are x86-specific, used by some header files */
17.247 +#define atomic_clear_mask(mask, addr) \
17.248 + asm volatile(LOCK_PREFIX "andl %0,%1" \
17.249 + : : "r" (~(mask)), "m" (*(addr)) : "memory")
17.250 +
17.251 +#define atomic_set_mask(mask, addr) \
17.252 + asm volatile(LOCK_PREFIX "orl %0,%1" \
17.253 + : : "r" (mask), "m" (*(addr)) : "memory")
17.254 +
17.255 +/* Atomic operations are already serializing on x86 */
17.256 +#define smp_mb__before_atomic_dec() barrier()
17.257 +#define smp_mb__after_atomic_dec() barrier()
17.258 +#define smp_mb__before_atomic_inc() barrier()
17.259 +#define smp_mb__after_atomic_inc() barrier()
17.260 +
17.261 +#include <asm-generic/atomic.h>
17.262 +#endif /* _ASM_X86_ATOMIC_32_H */
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/arch/x86/include/asm/atomic_64.h Sun Jan 11 20:20:11 2009 +0100
18.3 @@ -0,0 +1,473 @@
18.4 +#ifndef _ASM_X86_ATOMIC_64_H
18.5 +#define _ASM_X86_ATOMIC_64_H
18.6 +
18.7 +#include <asm/alternative.h>
18.8 +#include <asm/cmpxchg.h>
18.9 +
18.10 +/* atomic_t should be 32 bit signed type */
18.11 +
18.12 +/*
18.13 + * Atomic operations that C can't guarantee us. Useful for
18.14 + * resource counting etc..
18.15 + */
18.16 +
18.17 +/*
18.18 + * Make sure gcc doesn't try to be clever and move things around
18.19 + * on us. We need to use _exactly_ the address the user gave us,
18.20 + * not some alias that contains the same information.
18.21 + */
18.22 +typedef struct {
18.23 + int counter;
18.24 +} atomic_t;
18.25 +
18.26 +#define ATOMIC_INIT(i) { (i) }
18.27 +
18.28 +/**
18.29 + * atomic_read - read atomic variable
18.30 + * @v: pointer of type atomic_t
18.31 + *
18.32 + * Atomically reads the value of @v.
18.33 + */
18.34 +#define atomic_read(v) ((v)->counter)
18.35 +
18.36 +/**
18.37 + * atomic_set - set atomic variable
18.38 + * @v: pointer of type atomic_t
18.39 + * @i: required value
18.40 + *
18.41 + * Atomically sets the value of @v to @i.
18.42 + */
18.43 +#define atomic_set(v, i) (((v)->counter) = (i))
18.44 +
18.45 +/**
18.46 + * atomic_add - add integer to atomic variable
18.47 + * @i: integer value to add
18.48 + * @v: pointer of type atomic_t
18.49 + *
18.50 + * Atomically adds @i to @v.
18.51 + */
18.52 +static inline void atomic_add(int i, atomic_t *v)
18.53 +{
18.54 + asm volatile(LOCK_PREFIX "addl %1,%0"
18.55 + : "=m" (v->counter)
18.56 + : "ir" (i), "m" (v->counter));
18.57 +}
18.58 +
18.59 +/**
18.60 + * atomic_sub - subtract the atomic variable
18.61 + * @i: integer value to subtract
18.62 + * @v: pointer of type atomic_t
18.63 + *
18.64 + * Atomically subtracts @i from @v.
18.65 + */
18.66 +static inline void atomic_sub(int i, atomic_t *v)
18.67 +{
18.68 + asm volatile(LOCK_PREFIX "subl %1,%0"
18.69 + : "=m" (v->counter)
18.70 + : "ir" (i), "m" (v->counter));
18.71 +}
18.72 +
18.73 +/**
18.74 + * atomic_sub_and_test - subtract value from variable and test result
18.75 + * @i: integer value to subtract
18.76 + * @v: pointer of type atomic_t
18.77 + *
18.78 + * Atomically subtracts @i from @v and returns
18.79 + * true if the result is zero, or false for all
18.80 + * other cases.
18.81 + */
18.82 +static inline int atomic_sub_and_test(int i, atomic_t *v)
18.83 +{
18.84 + unsigned char c;
18.85 +
18.86 + asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
18.87 + : "=m" (v->counter), "=qm" (c)
18.88 + : "ir" (i), "m" (v->counter) : "memory");
18.89 + return c;
18.90 +}
18.91 +
18.92 +/**
18.93 + * atomic_inc - increment atomic variable
18.94 + * @v: pointer of type atomic_t
18.95 + *
18.96 + * Atomically increments @v by 1.
18.97 + */
18.98 +static inline void atomic_inc(atomic_t *v)
18.99 +{
18.100 + asm volatile(LOCK_PREFIX "incl %0"
18.101 + : "=m" (v->counter)
18.102 + : "m" (v->counter));
18.103 +}
18.104 +
18.105 +/**
18.106 + * atomic_dec - decrement atomic variable
18.107 + * @v: pointer of type atomic_t
18.108 + *
18.109 + * Atomically decrements @v by 1.
18.110 + */
18.111 +static inline void atomic_dec(atomic_t *v)
18.112 +{
18.113 + asm volatile(LOCK_PREFIX "decl %0"
18.114 + : "=m" (v->counter)
18.115 + : "m" (v->counter));
18.116 +}
18.117 +
18.118 +/**
18.119 + * atomic_dec_and_test - decrement and test
18.120 + * @v: pointer of type atomic_t
18.121 + *
18.122 + * Atomically decrements @v by 1 and
18.123 + * returns true if the result is 0, or false for all other
18.124 + * cases.
18.125 + */
18.126 +static inline int atomic_dec_and_test(atomic_t *v)
18.127 +{
18.128 + unsigned char c;
18.129 +
18.130 + asm volatile(LOCK_PREFIX "decl %0; sete %1"
18.131 + : "=m" (v->counter), "=qm" (c)
18.132 + : "m" (v->counter) : "memory");
18.133 + return c != 0;
18.134 +}
18.135 +
18.136 +/**
18.137 + * atomic_inc_and_test - increment and test
18.138 + * @v: pointer of type atomic_t
18.139 + *
18.140 + * Atomically increments @v by 1
18.141 + * and returns true if the result is zero, or false for all
18.142 + * other cases.
18.143 + */
18.144 +static inline int atomic_inc_and_test(atomic_t *v)
18.145 +{
18.146 + unsigned char c;
18.147 +
18.148 + asm volatile(LOCK_PREFIX "incl %0; sete %1"
18.149 + : "=m" (v->counter), "=qm" (c)
18.150 + : "m" (v->counter) : "memory");
18.151 + return c != 0;
18.152 +}
18.153 +
18.154 +/**
18.155 + * atomic_add_negative - add and test if negative
18.156 + * @i: integer value to add
18.157 + * @v: pointer of type atomic_t
18.158 + *
18.159 + * Atomically adds @i to @v and returns true
18.160 + * if the result is negative, or false when
18.161 + * result is greater than or equal to zero.
18.162 + */
18.163 +static inline int atomic_add_negative(int i, atomic_t *v)
18.164 +{
18.165 + unsigned char c;
18.166 +
18.167 + asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
18.168 + : "=m" (v->counter), "=qm" (c)
18.169 + : "ir" (i), "m" (v->counter) : "memory");
18.170 + return c;
18.171 +}
18.172 +
18.173 +/**
18.174 + * atomic_add_return - add and return
18.175 + * @i: integer value to add
18.176 + * @v: pointer of type atomic_t
18.177 + *
18.178 + * Atomically adds @i to @v and returns @i + @v
18.179 + */
18.180 +static inline int atomic_add_return(int i, atomic_t *v)
18.181 +{
18.182 + int __i = i;
18.183 + asm volatile(LOCK_PREFIX "xaddl %0, %1"
18.184 + : "+r" (i), "+m" (v->counter)
18.185 + : : "memory");
18.186 + return i + __i;
18.187 +}
18.188 +
18.189 +static inline int atomic_sub_return(int i, atomic_t *v)
18.190 +{
18.191 + return atomic_add_return(-i, v);
18.192 +}
18.193 +
18.194 +#define atomic_inc_return(v) (atomic_add_return(1, v))
18.195 +#define atomic_dec_return(v) (atomic_sub_return(1, v))
18.196 +
18.197 +/* An 64bit atomic type */
18.198 +
18.199 +typedef struct {
18.200 + long counter;
18.201 +} atomic64_t;
18.202 +
18.203 +#define ATOMIC64_INIT(i) { (i) }
18.204 +
18.205 +/**
18.206 + * atomic64_read - read atomic64 variable
18.207 + * @v: pointer of type atomic64_t
18.208 + *
18.209 + * Atomically reads the value of @v.
18.210 + * Doesn't imply a read memory barrier.
18.211 + */
18.212 +#define atomic64_read(v) ((v)->counter)
18.213 +
18.214 +/**
18.215 + * atomic64_set - set atomic64 variable
18.216 + * @v: pointer to type atomic64_t
18.217 + * @i: required value
18.218 + *
18.219 + * Atomically sets the value of @v to @i.
18.220 + */
18.221 +#define atomic64_set(v, i) (((v)->counter) = (i))
18.222 +
18.223 +/**
18.224 + * atomic64_add - add integer to atomic64 variable
18.225 + * @i: integer value to add
18.226 + * @v: pointer to type atomic64_t
18.227 + *
18.228 + * Atomically adds @i to @v.
18.229 + */
18.230 +static inline void atomic64_add(long i, atomic64_t *v)
18.231 +{
18.232 + asm volatile(LOCK_PREFIX "addq %1,%0"
18.233 + : "=m" (v->counter)
18.234 + : "er" (i), "m" (v->counter));
18.235 +}
18.236 +
18.237 +/**
18.238 + * atomic64_sub - subtract the atomic64 variable
18.239 + * @i: integer value to subtract
18.240 + * @v: pointer to type atomic64_t
18.241 + *
18.242 + * Atomically subtracts @i from @v.
18.243 + */
18.244 +static inline void atomic64_sub(long i, atomic64_t *v)
18.245 +{
18.246 + asm volatile(LOCK_PREFIX "subq %1,%0"
18.247 + : "=m" (v->counter)
18.248 + : "er" (i), "m" (v->counter));
18.249 +}
18.250 +
18.251 +/**
18.252 + * atomic64_sub_and_test - subtract value from variable and test result
18.253 + * @i: integer value to subtract
18.254 + * @v: pointer to type atomic64_t
18.255 + *
18.256 + * Atomically subtracts @i from @v and returns
18.257 + * true if the result is zero, or false for all
18.258 + * other cases.
18.259 + */
18.260 +static inline int atomic64_sub_and_test(long i, atomic64_t *v)
18.261 +{
18.262 + unsigned char c;
18.263 +
18.264 + asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
18.265 + : "=m" (v->counter), "=qm" (c)
18.266 + : "er" (i), "m" (v->counter) : "memory");
18.267 + return c;
18.268 +}
18.269 +
18.270 +/**
18.271 + * atomic64_inc - increment atomic64 variable
18.272 + * @v: pointer to type atomic64_t
18.273 + *
18.274 + * Atomically increments @v by 1.
18.275 + */
18.276 +static inline void atomic64_inc(atomic64_t *v)
18.277 +{
18.278 + asm volatile(LOCK_PREFIX "incq %0"
18.279 + : "=m" (v->counter)
18.280 + : "m" (v->counter));
18.281 +}
18.282 +
18.283 +/**
18.284 + * atomic64_dec - decrement atomic64 variable
18.285 + * @v: pointer to type atomic64_t
18.286 + *
18.287 + * Atomically decrements @v by 1.
18.288 + */
18.289 +static inline void atomic64_dec(atomic64_t *v)
18.290 +{
18.291 + asm volatile(LOCK_PREFIX "decq %0"
18.292 + : "=m" (v->counter)
18.293 + : "m" (v->counter));
18.294 +}
18.295 +
18.296 +/**
18.297 + * atomic64_dec_and_test - decrement and test
18.298 + * @v: pointer to type atomic64_t
18.299 + *
18.300 + * Atomically decrements @v by 1 and
18.301 + * returns true if the result is 0, or false for all other
18.302 + * cases.
18.303 + */
18.304 +static inline int atomic64_dec_and_test(atomic64_t *v)
18.305 +{
18.306 + unsigned char c;
18.307 +
18.308 + asm volatile(LOCK_PREFIX "decq %0; sete %1"
18.309 + : "=m" (v->counter), "=qm" (c)
18.310 + : "m" (v->counter) : "memory");
18.311 + return c != 0;
18.312 +}
18.313 +
18.314 +/**
18.315 + * atomic64_inc_and_test - increment and test
18.316 + * @v: pointer to type atomic64_t
18.317 + *
18.318 + * Atomically increments @v by 1
18.319 + * and returns true if the result is zero, or false for all
18.320 + * other cases.
18.321 + */
18.322 +static inline int atomic64_inc_and_test(atomic64_t *v)
18.323 +{
18.324 + unsigned char c;
18.325 +
18.326 + asm volatile(LOCK_PREFIX "incq %0; sete %1"
18.327 + : "=m" (v->counter), "=qm" (c)
18.328 + : "m" (v->counter) : "memory");
18.329 + return c != 0;
18.330 +}
18.331 +
18.332 +/**
18.333 + * atomic64_add_negative - add and test if negative
18.334 + * @i: integer value to add
18.335 + * @v: pointer to type atomic64_t
18.336 + *
18.337 + * Atomically adds @i to @v and returns true
18.338 + * if the result is negative, or false when
18.339 + * result is greater than or equal to zero.
18.340 + */
18.341 +static inline int atomic64_add_negative(long i, atomic64_t *v)
18.342 +{
18.343 + unsigned char c;
18.344 +
18.345 + asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
18.346 + : "=m" (v->counter), "=qm" (c)
18.347 + : "er" (i), "m" (v->counter) : "memory");
18.348 + return c;
18.349 +}
18.350 +
18.351 +/**
18.352 + * atomic64_add_return - add and return
18.353 + * @i: integer value to add
18.354 + * @v: pointer to type atomic64_t
18.355 + *
18.356 + * Atomically adds @i to @v and returns @i + @v
18.357 + */
18.358 +static inline long atomic64_add_return(long i, atomic64_t *v)
18.359 +{
18.360 + long __i = i;
18.361 + asm volatile(LOCK_PREFIX "xaddq %0, %1;"
18.362 + : "+r" (i), "+m" (v->counter)
18.363 + : : "memory");
18.364 + return i + __i;
18.365 +}
18.366 +
18.367 +static inline long atomic64_sub_return(long i, atomic64_t *v)
18.368 +{
18.369 + return atomic64_add_return(-i, v);
18.370 +}
18.371 +
18.372 +#define atomic64_inc_return(v) (atomic64_add_return(1, (v)))
18.373 +#define atomic64_dec_return(v) (atomic64_sub_return(1, (v)))
18.374 +
18.375 +#define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
18.376 +#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
18.377 +
18.378 +#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
18.379 +#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
18.380 +
18.381 +/**
18.382 + * atomic_add_unless - add unless the number is a given value
18.383 + * @v: pointer of type atomic_t
18.384 + * @a: the amount to add to v...
18.385 + * @u: ...unless v is equal to u.
18.386 + *
18.387 + * Atomically adds @a to @v, so long as it was not @u.
18.388 + * Returns non-zero if @v was not @u, and zero otherwise.
18.389 + */
18.390 +static inline int atomic_add_unless(atomic_t *v, int a, int u)
18.391 +{
18.392 + int c, old;
18.393 + c = atomic_read(v);
18.394 + for (;;) {
18.395 + if (unlikely(c == (u)))
18.396 + break;
18.397 + old = atomic_cmpxchg((v), c, c + (a));
18.398 + if (likely(old == c))
18.399 + break;
18.400 + c = old;
18.401 + }
18.402 + return c != (u);
18.403 +}
18.404 +
18.405 +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
18.406 +
18.407 +/**
18.408 + * atomic64_add_unless - add unless the number is a given value
18.409 + * @v: pointer of type atomic64_t
18.410 + * @a: the amount to add to v...
18.411 + * @u: ...unless v is equal to u.
18.412 + *
18.413 + * Atomically adds @a to @v, so long as it was not @u.
18.414 + * Returns non-zero if @v was not @u, and zero otherwise.
18.415 + */
18.416 +static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
18.417 +{
18.418 + long c, old;
18.419 + c = atomic64_read(v);
18.420 + for (;;) {
18.421 + if (unlikely(c == (u)))
18.422 + break;
18.423 + old = atomic64_cmpxchg((v), c, c + (a));
18.424 + if (likely(old == c))
18.425 + break;
18.426 + c = old;
18.427 + }
18.428 + return c != (u);
18.429 +}
18.430 +
18.431 +/**
18.432 + * atomic_inc_short - increment of a short integer
18.433 + * @v: pointer to type int
18.434 + *
18.435 + * Atomically adds 1 to @v
18.436 + * Returns the new value of @u
18.437 + */
18.438 +static inline short int atomic_inc_short(short int *v)
18.439 +{
18.440 + asm(LOCK_PREFIX "addw $1, %0" : "+m" (*v));
18.441 + return *v;
18.442 +}
18.443 +
18.444 +/**
18.445 + * atomic_or_long - OR of two long integers
18.446 + * @v1: pointer to type unsigned long
18.447 + * @v2: pointer to type unsigned long
18.448 + *
18.449 + * Atomically ORs @v1 and @v2
18.450 + * Returns the result of the OR
18.451 + */
18.452 +static inline void atomic_or_long(unsigned long *v1, unsigned long v2)
18.453 +{
18.454 + asm(LOCK_PREFIX "orq %1, %0" : "+m" (*v1) : "r" (v2));
18.455 +}
18.456 +
18.457 +#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
18.458 +
18.459 +/* These are x86-specific, used by some header files */
18.460 +#define atomic_clear_mask(mask, addr) \
18.461 + asm volatile(LOCK_PREFIX "andl %0,%1" \
18.462 + : : "r" (~(mask)), "m" (*(addr)) : "memory")
18.463 +
18.464 +#define atomic_set_mask(mask, addr) \
18.465 + asm volatile(LOCK_PREFIX "orl %0,%1" \
18.466 + : : "r" ((unsigned)(mask)), "m" (*(addr)) \
18.467 + : "memory")
18.468 +
18.469 +/* Atomic operations are already serializing on x86 */
18.470 +#define smp_mb__before_atomic_dec() barrier()
18.471 +#define smp_mb__after_atomic_dec() barrier()
18.472 +#define smp_mb__before_atomic_inc() barrier()
18.473 +#define smp_mb__after_atomic_inc() barrier()
18.474 +
18.475 +#include <asm-generic/atomic.h>
18.476 +#endif /* _ASM_X86_ATOMIC_64_H */
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/arch/x86/include/asm/auxvec.h Sun Jan 11 20:20:11 2009 +0100
19.3 @@ -0,0 +1,12 @@
19.4 +#ifndef _ASM_X86_AUXVEC_H
19.5 +#define _ASM_X86_AUXVEC_H
19.6 +/*
19.7 + * Architecture-neutral AT_ values in 0-17, leave some room
19.8 + * for more of them, start the x86-specific ones at 32.
19.9 + */
19.10 +#ifdef __i386__
19.11 +#define AT_SYSINFO 32
19.12 +#endif
19.13 +#define AT_SYSINFO_EHDR 33
19.14 +
19.15 +#endif /* _ASM_X86_AUXVEC_H */
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/arch/x86/include/asm/bigsmp/apic.h Sun Jan 11 20:20:11 2009 +0100
20.3 @@ -0,0 +1,139 @@
20.4 +#ifndef __ASM_MACH_APIC_H
20.5 +#define __ASM_MACH_APIC_H
20.6 +
20.7 +#define xapic_phys_to_log_apicid(cpu) (per_cpu(x86_bios_cpu_apicid, cpu))
20.8 +#define esr_disable (1)
20.9 +
20.10 +static inline int apic_id_registered(void)
20.11 +{
20.12 + return (1);
20.13 +}
20.14 +
20.15 +static inline cpumask_t target_cpus(void)
20.16 +{
20.17 +#ifdef CONFIG_SMP
20.18 + return cpu_online_map;
20.19 +#else
20.20 + return cpumask_of_cpu(0);
20.21 +#endif
20.22 +}
20.23 +
20.24 +#undef APIC_DEST_LOGICAL
20.25 +#define APIC_DEST_LOGICAL 0
20.26 +#define APIC_DFR_VALUE (APIC_DFR_FLAT)
20.27 +#define INT_DELIVERY_MODE (dest_Fixed)
20.28 +#define INT_DEST_MODE (0) /* phys delivery to target proc */
20.29 +#define NO_BALANCE_IRQ (0)
20.30 +#define WAKE_SECONDARY_VIA_INIT
20.31 +
20.32 +
20.33 +static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
20.34 +{
20.35 + return (0);
20.36 +}
20.37 +
20.38 +static inline unsigned long check_apicid_present(int bit)
20.39 +{
20.40 + return (1);
20.41 +}
20.42 +
20.43 +static inline unsigned long calculate_ldr(int cpu)
20.44 +{
20.45 + unsigned long val, id;
20.46 + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
20.47 + id = xapic_phys_to_log_apicid(cpu);
20.48 + val |= SET_APIC_LOGICAL_ID(id);
20.49 + return val;
20.50 +}
20.51 +
20.52 +/*
20.53 + * Set up the logical destination ID.
20.54 + *
20.55 + * Intel recommends to set DFR, LDR and TPR before enabling
20.56 + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
20.57 + * document number 292116). So here it goes...
20.58 + */
20.59 +static inline void init_apic_ldr(void)
20.60 +{
20.61 + unsigned long val;
20.62 + int cpu = smp_processor_id();
20.63 +
20.64 + apic_write(APIC_DFR, APIC_DFR_VALUE);
20.65 + val = calculate_ldr(cpu);
20.66 + apic_write(APIC_LDR, val);
20.67 +}
20.68 +
20.69 +static inline void setup_apic_routing(void)
20.70 +{
20.71 + printk("Enabling APIC mode: %s. Using %d I/O APICs\n",
20.72 + "Physflat", nr_ioapics);
20.73 +}
20.74 +
20.75 +static inline int multi_timer_check(int apic, int irq)
20.76 +{
20.77 + return (0);
20.78 +}
20.79 +
20.80 +static inline int apicid_to_node(int logical_apicid)
20.81 +{
20.82 + return apicid_2_node[hard_smp_processor_id()];
20.83 +}
20.84 +
20.85 +static inline int cpu_present_to_apicid(int mps_cpu)
20.86 +{
20.87 + if (mps_cpu < NR_CPUS)
20.88 + return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
20.89 +
20.90 + return BAD_APICID;
20.91 +}
20.92 +
20.93 +static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
20.94 +{
20.95 + return physid_mask_of_physid(phys_apicid);
20.96 +}
20.97 +
20.98 +extern u8 cpu_2_logical_apicid[];
20.99 +/* Mapping from cpu number to logical apicid */
20.100 +static inline int cpu_to_logical_apicid(int cpu)
20.101 +{
20.102 + if (cpu >= NR_CPUS)
20.103 + return BAD_APICID;
20.104 + return cpu_physical_id(cpu);
20.105 +}
20.106 +
20.107 +static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
20.108 +{
20.109 + /* For clustered we don't have a good way to do this yet - hack */
20.110 + return physids_promote(0xFFL);
20.111 +}
20.112 +
20.113 +static inline void setup_portio_remap(void)
20.114 +{
20.115 +}
20.116 +
20.117 +static inline void enable_apic_mode(void)
20.118 +{
20.119 +}
20.120 +
20.121 +static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
20.122 +{
20.123 + return (1);
20.124 +}
20.125 +
20.126 +/* As we are using single CPU as destination, pick only one CPU here */
20.127 +static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
20.128 +{
20.129 + int cpu;
20.130 + int apicid;
20.131 +
20.132 + cpu = first_cpu(cpumask);
20.133 + apicid = cpu_to_logical_apicid(cpu);
20.134 + return apicid;
20.135 +}
20.136 +
20.137 +static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
20.138 +{
20.139 + return cpuid_apic >> index_msb;
20.140 +}
20.141 +
20.142 +#endif /* __ASM_MACH_APIC_H */
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/arch/x86/include/asm/bigsmp/apicdef.h Sun Jan 11 20:20:11 2009 +0100
21.3 @@ -0,0 +1,13 @@
21.4 +#ifndef __ASM_MACH_APICDEF_H
21.5 +#define __ASM_MACH_APICDEF_H
21.6 +
21.7 +#define APIC_ID_MASK (0xFF<<24)
21.8 +
21.9 +static inline unsigned get_apic_id(unsigned long x)
21.10 +{
21.11 + return (((x)>>24)&0xFF);
21.12 +}
21.13 +
21.14 +#define GET_APIC_ID(x) get_apic_id(x)
21.15 +
21.16 +#endif
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/arch/x86/include/asm/bigsmp/ipi.h Sun Jan 11 20:20:11 2009 +0100
22.3 @@ -0,0 +1,25 @@
22.4 +#ifndef __ASM_MACH_IPI_H
22.5 +#define __ASM_MACH_IPI_H
22.6 +
22.7 +void send_IPI_mask_sequence(cpumask_t mask, int vector);
22.8 +
22.9 +static inline void send_IPI_mask(cpumask_t mask, int vector)
22.10 +{
22.11 + send_IPI_mask_sequence(mask, vector);
22.12 +}
22.13 +
22.14 +static inline void send_IPI_allbutself(int vector)
22.15 +{
22.16 + cpumask_t mask = cpu_online_map;
22.17 + cpu_clear(smp_processor_id(), mask);
22.18 +
22.19 + if (!cpus_empty(mask))
22.20 + send_IPI_mask(mask, vector);
22.21 +}
22.22 +
22.23 +static inline void send_IPI_all(int vector)
22.24 +{
22.25 + send_IPI_mask(cpu_online_map, vector);
22.26 +}
22.27 +
22.28 +#endif /* __ASM_MACH_IPI_H */
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/arch/x86/include/asm/bios_ebda.h Sun Jan 11 20:20:11 2009 +0100
23.3 @@ -0,0 +1,36 @@
23.4 +#ifndef _ASM_X86_BIOS_EBDA_H
23.5 +#define _ASM_X86_BIOS_EBDA_H
23.6 +
23.7 +#include <asm/io.h>
23.8 +
23.9 +/*
23.10 + * there is a real-mode segmented pointer pointing to the
23.11 + * 4K EBDA area at 0x40E.
23.12 + */
23.13 +static inline unsigned int get_bios_ebda(void)
23.14 +{
23.15 + unsigned int address = *(unsigned short *)phys_to_virt(0x40E);
23.16 + address <<= 4;
23.17 + return address; /* 0 means none */
23.18 +}
23.19 +
23.20 +void reserve_ebda_region(void);
23.21 +
23.22 +#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
23.23 +/*
23.24 + * This is obviously not a great place for this, but we want to be
23.25 + * able to scatter it around anywhere in the kernel.
23.26 + */
23.27 +void check_for_bios_corruption(void);
23.28 +void start_periodic_check_for_corruption(void);
23.29 +#else
23.30 +static inline void check_for_bios_corruption(void)
23.31 +{
23.32 +}
23.33 +
23.34 +static inline void start_periodic_check_for_corruption(void)
23.35 +{
23.36 +}
23.37 +#endif
23.38 +
23.39 +#endif /* _ASM_X86_BIOS_EBDA_H */
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/arch/x86/include/asm/bitops.h Sun Jan 11 20:20:11 2009 +0100
24.3 @@ -0,0 +1,451 @@
24.4 +#ifndef _ASM_X86_BITOPS_H
24.5 +#define _ASM_X86_BITOPS_H
24.6 +
24.7 +/*
24.8 + * Copyright 1992, Linus Torvalds.
24.9 + */
24.10 +
24.11 +#ifndef _LINUX_BITOPS_H
24.12 +#error only <linux/bitops.h> can be included directly
24.13 +#endif
24.14 +
24.15 +#include <linux/compiler.h>
24.16 +#include <asm/alternative.h>
24.17 +
24.18 +/*
24.19 + * These have to be done with inline assembly: that way the bit-setting
24.20 + * is guaranteed to be atomic. All bit operations return 0 if the bit
24.21 + * was cleared before the operation and != 0 if it was not.
24.22 + *
24.23 + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
24.24 + */
24.25 +
24.26 +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
24.27 +/* Technically wrong, but this avoids compilation errors on some gcc
24.28 + versions. */
24.29 +#define BITOP_ADDR(x) "=m" (*(volatile long *) (x))
24.30 +#else
24.31 +#define BITOP_ADDR(x) "+m" (*(volatile long *) (x))
24.32 +#endif
24.33 +
24.34 +#define ADDR BITOP_ADDR(addr)
24.35 +
24.36 +/*
24.37 + * We do the locked ops that don't return the old value as
24.38 + * a mask operation on a byte.
24.39 + */
24.40 +#define IS_IMMEDIATE(nr) (__builtin_constant_p(nr))
24.41 +#define CONST_MASK_ADDR(nr, addr) BITOP_ADDR((void *)(addr) + ((nr)>>3))
24.42 +#define CONST_MASK(nr) (1 << ((nr) & 7))
24.43 +
24.44 +/**
24.45 + * set_bit - Atomically set a bit in memory
24.46 + * @nr: the bit to set
24.47 + * @addr: the address to start counting from
24.48 + *
24.49 + * This function is atomic and may not be reordered. See __set_bit()
24.50 + * if you do not require the atomic guarantees.
24.51 + *
24.52 + * Note: there are no guarantees that this function will not be reordered
24.53 + * on non x86 architectures, so if you are writing portable code,
24.54 + * make sure not to rely on its reordering guarantees.
24.55 + *
24.56 + * Note that @nr may be almost arbitrarily large; this function is not
24.57 + * restricted to acting on a single-word quantity.
24.58 + */
24.59 +static inline void set_bit(unsigned int nr, volatile unsigned long *addr)
24.60 +{
24.61 + if (IS_IMMEDIATE(nr)) {
24.62 + asm volatile(LOCK_PREFIX "orb %1,%0"
24.63 + : CONST_MASK_ADDR(nr, addr)
24.64 + : "iq" ((u8)CONST_MASK(nr))
24.65 + : "memory");
24.66 + } else {
24.67 + asm volatile(LOCK_PREFIX "bts %1,%0"
24.68 + : BITOP_ADDR(addr) : "Ir" (nr) : "memory");
24.69 + }
24.70 +}
24.71 +
24.72 +/**
24.73 + * __set_bit - Set a bit in memory
24.74 + * @nr: the bit to set
24.75 + * @addr: the address to start counting from
24.76 + *
24.77 + * Unlike set_bit(), this function is non-atomic and may be reordered.
24.78 + * If it's called on the same region of memory simultaneously, the effect
24.79 + * may be that only one operation succeeds.
24.80 + */
24.81 +static inline void __set_bit(int nr, volatile unsigned long *addr)
24.82 +{
24.83 + asm volatile("bts %1,%0" : ADDR : "Ir" (nr) : "memory");
24.84 +}
24.85 +
24.86 +/**
24.87 + * clear_bit - Clears a bit in memory
24.88 + * @nr: Bit to clear
24.89 + * @addr: Address to start counting from
24.90 + *
24.91 + * clear_bit() is atomic and may not be reordered. However, it does
24.92 + * not contain a memory barrier, so if it is used for locking purposes,
24.93 + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
24.94 + * in order to ensure changes are visible on other processors.
24.95 + */
24.96 +static inline void clear_bit(int nr, volatile unsigned long *addr)
24.97 +{
24.98 + if (IS_IMMEDIATE(nr)) {
24.99 + asm volatile(LOCK_PREFIX "andb %1,%0"
24.100 + : CONST_MASK_ADDR(nr, addr)
24.101 + : "iq" ((u8)~CONST_MASK(nr)));
24.102 + } else {
24.103 + asm volatile(LOCK_PREFIX "btr %1,%0"
24.104 + : BITOP_ADDR(addr)
24.105 + : "Ir" (nr));
24.106 + }
24.107 +}
24.108 +
24.109 +/*
24.110 + * clear_bit_unlock - Clears a bit in memory
24.111 + * @nr: Bit to clear
24.112 + * @addr: Address to start counting from
24.113 + *
24.114 + * clear_bit() is atomic and implies release semantics before the memory
24.115 + * operation. It can be used for an unlock.
24.116 + */
24.117 +static inline void clear_bit_unlock(unsigned nr, volatile unsigned long *addr)
24.118 +{
24.119 + barrier();
24.120 + clear_bit(nr, addr);
24.121 +}
24.122 +
24.123 +static inline void __clear_bit(int nr, volatile unsigned long *addr)
24.124 +{
24.125 + asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
24.126 +}
24.127 +
24.128 +/*
24.129 + * __clear_bit_unlock - Clears a bit in memory
24.130 + * @nr: Bit to clear
24.131 + * @addr: Address to start counting from
24.132 + *
24.133 + * __clear_bit() is non-atomic and implies release semantics before the memory
24.134 + * operation. It can be used for an unlock if no other CPUs can concurrently
24.135 + * modify other bits in the word.
24.136 + *
24.137 + * No memory barrier is required here, because x86 cannot reorder stores past
24.138 + * older loads. Same principle as spin_unlock.
24.139 + */
24.140 +static inline void __clear_bit_unlock(unsigned nr, volatile unsigned long *addr)
24.141 +{
24.142 + barrier();
24.143 + __clear_bit(nr, addr);
24.144 +}
24.145 +
24.146 +#define smp_mb__before_clear_bit() barrier()
24.147 +#define smp_mb__after_clear_bit() barrier()
24.148 +
24.149 +/**
24.150 + * __change_bit - Toggle a bit in memory
24.151 + * @nr: the bit to change
24.152 + * @addr: the address to start counting from
24.153 + *
24.154 + * Unlike change_bit(), this function is non-atomic and may be reordered.
24.155 + * If it's called on the same region of memory simultaneously, the effect
24.156 + * may be that only one operation succeeds.
24.157 + */
24.158 +static inline void __change_bit(int nr, volatile unsigned long *addr)
24.159 +{
24.160 + asm volatile("btc %1,%0" : ADDR : "Ir" (nr));
24.161 +}
24.162 +
24.163 +/**
24.164 + * change_bit - Toggle a bit in memory
24.165 + * @nr: Bit to change
24.166 + * @addr: Address to start counting from
24.167 + *
24.168 + * change_bit() is atomic and may not be reordered.
24.169 + * Note that @nr may be almost arbitrarily large; this function is not
24.170 + * restricted to acting on a single-word quantity.
24.171 + */
24.172 +static inline void change_bit(int nr, volatile unsigned long *addr)
24.173 +{
24.174 + asm volatile(LOCK_PREFIX "btc %1,%0" : ADDR : "Ir" (nr));
24.175 +}
24.176 +
24.177 +/**
24.178 + * test_and_set_bit - Set a bit and return its old value
24.179 + * @nr: Bit to set
24.180 + * @addr: Address to count from
24.181 + *
24.182 + * This operation is atomic and cannot be reordered.
24.183 + * It also implies a memory barrier.
24.184 + */
24.185 +static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
24.186 +{
24.187 + int oldbit;
24.188 +
24.189 + asm volatile(LOCK_PREFIX "bts %2,%1\n\t"
24.190 + "sbb %0,%0" : "=r" (oldbit), ADDR : "Ir" (nr) : "memory");
24.191 +
24.192 + return oldbit;
24.193 +}
24.194 +
24.195 +/**
24.196 + * test_and_set_bit_lock - Set a bit and return its old value for lock
24.197 + * @nr: Bit to set
24.198 + * @addr: Address to count from
24.199 + *
24.200 + * This is the same as test_and_set_bit on x86.
24.201 + */
24.202 +static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr)
24.203 +{
24.204 + return test_and_set_bit(nr, addr);
24.205 +}
24.206 +
24.207 +/**
24.208 + * __test_and_set_bit - Set a bit and return its old value
24.209 + * @nr: Bit to set
24.210 + * @addr: Address to count from
24.211 + *
24.212 + * This operation is non-atomic and can be reordered.
24.213 + * If two examples of this operation race, one can appear to succeed
24.214 + * but actually fail. You must protect multiple accesses with a lock.
24.215 + */
24.216 +static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
24.217 +{
24.218 + int oldbit;
24.219 +
24.220 + asm("bts %2,%1\n\t"
24.221 + "sbb %0,%0"
24.222 + : "=r" (oldbit), ADDR
24.223 + : "Ir" (nr));
24.224 + return oldbit;
24.225 +}
24.226 +
24.227 +/**
24.228 + * test_and_clear_bit - Clear a bit and return its old value
24.229 + * @nr: Bit to clear
24.230 + * @addr: Address to count from
24.231 + *
24.232 + * This operation is atomic and cannot be reordered.
24.233 + * It also implies a memory barrier.
24.234 + */
24.235 +static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
24.236 +{
24.237 + int oldbit;
24.238 +
24.239 + asm volatile(LOCK_PREFIX "btr %2,%1\n\t"
24.240 + "sbb %0,%0"
24.241 + : "=r" (oldbit), ADDR : "Ir" (nr) : "memory");
24.242 +
24.243 + return oldbit;
24.244 +}
24.245 +
24.246 +/**
24.247 + * __test_and_clear_bit - Clear a bit and return its old value
24.248 + * @nr: Bit to clear
24.249 + * @addr: Address to count from
24.250 + *
24.251 + * This operation is non-atomic and can be reordered.
24.252 + * If two examples of this operation race, one can appear to succeed
24.253 + * but actually fail. You must protect multiple accesses with a lock.
24.254 + */
24.255 +static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
24.256 +{
24.257 + int oldbit;
24.258 +
24.259 + asm volatile("btr %2,%1\n\t"
24.260 + "sbb %0,%0"
24.261 + : "=r" (oldbit), ADDR
24.262 + : "Ir" (nr));
24.263 + return oldbit;
24.264 +}
24.265 +
24.266 +/* WARNING: non atomic and it can be reordered! */
24.267 +static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
24.268 +{
24.269 + int oldbit;
24.270 +
24.271 + asm volatile("btc %2,%1\n\t"
24.272 + "sbb %0,%0"
24.273 + : "=r" (oldbit), ADDR
24.274 + : "Ir" (nr) : "memory");
24.275 +
24.276 + return oldbit;
24.277 +}
24.278 +
24.279 +/**
24.280 + * test_and_change_bit - Change a bit and return its old value
24.281 + * @nr: Bit to change
24.282 + * @addr: Address to count from
24.283 + *
24.284 + * This operation is atomic and cannot be reordered.
24.285 + * It also implies a memory barrier.
24.286 + */
24.287 +static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
24.288 +{
24.289 + int oldbit;
24.290 +
24.291 + asm volatile(LOCK_PREFIX "btc %2,%1\n\t"
24.292 + "sbb %0,%0"
24.293 + : "=r" (oldbit), ADDR : "Ir" (nr) : "memory");
24.294 +
24.295 + return oldbit;
24.296 +}
24.297 +
24.298 +static inline int constant_test_bit(int nr, const volatile unsigned long *addr)
24.299 +{
24.300 + return ((1UL << (nr % BITS_PER_LONG)) &
24.301 + (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
24.302 +}
24.303 +
24.304 +static inline int variable_test_bit(int nr, volatile const unsigned long *addr)
24.305 +{
24.306 + int oldbit;
24.307 +
24.308 + asm volatile("bt %2,%1\n\t"
24.309 + "sbb %0,%0"
24.310 + : "=r" (oldbit)
24.311 + : "m" (*(unsigned long *)addr), "Ir" (nr));
24.312 +
24.313 + return oldbit;
24.314 +}
24.315 +
24.316 +#if 0 /* Fool kernel-doc since it doesn't do macros yet */
24.317 +/**
24.318 + * test_bit - Determine whether a bit is set
24.319 + * @nr: bit number to test
24.320 + * @addr: Address to start counting from
24.321 + */
24.322 +static int test_bit(int nr, const volatile unsigned long *addr);
24.323 +#endif
24.324 +
24.325 +#define test_bit(nr, addr) \
24.326 + (__builtin_constant_p((nr)) \
24.327 + ? constant_test_bit((nr), (addr)) \
24.328 + : variable_test_bit((nr), (addr)))
24.329 +
24.330 +/**
24.331 + * __ffs - find first set bit in word
24.332 + * @word: The word to search
24.333 + *
24.334 + * Undefined if no bit exists, so code should check against 0 first.
24.335 + */
24.336 +static inline unsigned long __ffs(unsigned long word)
24.337 +{
24.338 + asm("bsf %1,%0"
24.339 + : "=r" (word)
24.340 + : "rm" (word));
24.341 + return word;
24.342 +}
24.343 +
24.344 +/**
24.345 + * ffz - find first zero bit in word
24.346 + * @word: The word to search
24.347 + *
24.348 + * Undefined if no zero exists, so code should check against ~0UL first.
24.349 + */
24.350 +static inline unsigned long ffz(unsigned long word)
24.351 +{
24.352 + asm("bsf %1,%0"
24.353 + : "=r" (word)
24.354 + : "r" (~word));
24.355 + return word;
24.356 +}
24.357 +
24.358 +/*
24.359 + * __fls: find last set bit in word
24.360 + * @word: The word to search
24.361 + *
24.362 + * Undefined if no set bit exists, so code should check against 0 first.
24.363 + */
24.364 +static inline unsigned long __fls(unsigned long word)
24.365 +{
24.366 + asm("bsr %1,%0"
24.367 + : "=r" (word)
24.368 + : "rm" (word));
24.369 + return word;
24.370 +}
24.371 +
24.372 +#ifdef __KERNEL__
24.373 +/**
24.374 + * ffs - find first set bit in word
24.375 + * @x: the word to search
24.376 + *
24.377 + * This is defined the same way as the libc and compiler builtin ffs
24.378 + * routines, therefore differs in spirit from the other bitops.
24.379 + *
24.380 + * ffs(value) returns 0 if value is 0 or the position of the first
24.381 + * set bit if value is nonzero. The first (least significant) bit
24.382 + * is at position 1.
24.383 + */
24.384 +static inline int ffs(int x)
24.385 +{
24.386 + int r;
24.387 +#ifdef CONFIG_X86_CMOV
24.388 + asm("bsfl %1,%0\n\t"
24.389 + "cmovzl %2,%0"
24.390 + : "=r" (r) : "rm" (x), "r" (-1));
24.391 +#else
24.392 + asm("bsfl %1,%0\n\t"
24.393 + "jnz 1f\n\t"
24.394 + "movl $-1,%0\n"
24.395 + "1:" : "=r" (r) : "rm" (x));
24.396 +#endif
24.397 + return r + 1;
24.398 +}
24.399 +
24.400 +/**
24.401 + * fls - find last set bit in word
24.402 + * @x: the word to search
24.403 + *
24.404 + * This is defined in a similar way as the libc and compiler builtin
24.405 + * ffs, but returns the position of the most significant set bit.
24.406 + *
24.407 + * fls(value) returns 0 if value is 0 or the position of the last
24.408 + * set bit if value is nonzero. The last (most significant) bit is
24.409 + * at position 32.
24.410 + */
24.411 +static inline int fls(int x)
24.412 +{
24.413 + int r;
24.414 +#ifdef CONFIG_X86_CMOV
24.415 + asm("bsrl %1,%0\n\t"
24.416 + "cmovzl %2,%0"
24.417 + : "=&r" (r) : "rm" (x), "rm" (-1));
24.418 +#else
24.419 + asm("bsrl %1,%0\n\t"
24.420 + "jnz 1f\n\t"
24.421 + "movl $-1,%0\n"
24.422 + "1:" : "=r" (r) : "rm" (x));
24.423 +#endif
24.424 + return r + 1;
24.425 +}
24.426 +#endif /* __KERNEL__ */
24.427 +
24.428 +#undef ADDR
24.429 +
24.430 +#ifdef __KERNEL__
24.431 +
24.432 +#include <asm-generic/bitops/sched.h>
24.433 +
24.434 +#define ARCH_HAS_FAST_MULTIPLIER 1
24.435 +
24.436 +#include <asm-generic/bitops/hweight.h>
24.437 +
24.438 +#endif /* __KERNEL__ */
24.439 +
24.440 +#include <asm-generic/bitops/fls64.h>
24.441 +
24.442 +#ifdef __KERNEL__
24.443 +
24.444 +#include <asm-generic/bitops/ext2-non-atomic.h>
24.445 +
24.446 +#define ext2_set_bit_atomic(lock, nr, addr) \
24.447 + test_and_set_bit((nr), (unsigned long *)(addr))
24.448 +#define ext2_clear_bit_atomic(lock, nr, addr) \
24.449 + test_and_clear_bit((nr), (unsigned long *)(addr))
24.450 +
24.451 +#include <asm-generic/bitops/minix.h>
24.452 +
24.453 +#endif /* __KERNEL__ */
24.454 +#endif /* _ASM_X86_BITOPS_H */
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/arch/x86/include/asm/boot.h Sun Jan 11 20:20:11 2009 +0100
25.3 @@ -0,0 +1,26 @@
25.4 +#ifndef _ASM_X86_BOOT_H
25.5 +#define _ASM_X86_BOOT_H
25.6 +
25.7 +/* Don't touch these, unless you really know what you're doing. */
25.8 +#define DEF_SYSSEG 0x1000
25.9 +#define DEF_SYSSIZE 0x7F00
25.10 +
25.11 +/* Internal svga startup constants */
25.12 +#define NORMAL_VGA 0xffff /* 80x25 mode */
25.13 +#define EXTENDED_VGA 0xfffe /* 80x50 mode */
25.14 +#define ASK_VGA 0xfffd /* ask for it at bootup */
25.15 +
25.16 +/* Physical address where kernel should be loaded. */
25.17 +#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
25.18 + + (CONFIG_PHYSICAL_ALIGN - 1)) \
25.19 + & ~(CONFIG_PHYSICAL_ALIGN - 1))
25.20 +
25.21 +#ifdef CONFIG_X86_64
25.22 +#define BOOT_HEAP_SIZE 0x7000
25.23 +#define BOOT_STACK_SIZE 0x4000
25.24 +#else
25.25 +#define BOOT_HEAP_SIZE 0x4000
25.26 +#define BOOT_STACK_SIZE 0x1000
25.27 +#endif
25.28 +
25.29 +#endif /* _ASM_X86_BOOT_H */
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/arch/x86/include/asm/bootparam.h Sun Jan 11 20:20:11 2009 +0100
26.3 @@ -0,0 +1,111 @@
26.4 +#ifndef _ASM_X86_BOOTPARAM_H
26.5 +#define _ASM_X86_BOOTPARAM_H
26.6 +
26.7 +#include <linux/types.h>
26.8 +#include <linux/screen_info.h>
26.9 +#include <linux/apm_bios.h>
26.10 +#include <linux/edd.h>
26.11 +#include <asm/e820.h>
26.12 +#include <asm/ist.h>
26.13 +#include <video/edid.h>
26.14 +
26.15 +/* setup data types */
26.16 +#define SETUP_NONE 0
26.17 +#define SETUP_E820_EXT 1
26.18 +
26.19 +/* extensible setup data list node */
26.20 +struct setup_data {
26.21 + __u64 next;
26.22 + __u32 type;
26.23 + __u32 len;
26.24 + __u8 data[0];
26.25 +};
26.26 +
26.27 +struct setup_header {
26.28 + __u8 setup_sects;
26.29 + __u16 root_flags;
26.30 + __u32 syssize;
26.31 + __u16 ram_size;
26.32 +#define RAMDISK_IMAGE_START_MASK 0x07FF
26.33 +#define RAMDISK_PROMPT_FLAG 0x8000
26.34 +#define RAMDISK_LOAD_FLAG 0x4000
26.35 + __u16 vid_mode;
26.36 + __u16 root_dev;
26.37 + __u16 boot_flag;
26.38 + __u16 jump;
26.39 + __u32 header;
26.40 + __u16 version;
26.41 + __u32 realmode_swtch;
26.42 + __u16 start_sys;
26.43 + __u16 kernel_version;
26.44 + __u8 type_of_loader;
26.45 + __u8 loadflags;
26.46 +#define LOADED_HIGH (1<<0)
26.47 +#define QUIET_FLAG (1<<5)
26.48 +#define KEEP_SEGMENTS (1<<6)
26.49 +#define CAN_USE_HEAP (1<<7)
26.50 + __u16 setup_move_size;
26.51 + __u32 code32_start;
26.52 + __u32 ramdisk_image;
26.53 + __u32 ramdisk_size;
26.54 + __u32 bootsect_kludge;
26.55 + __u16 heap_end_ptr;
26.56 + __u16 _pad1;
26.57 + __u32 cmd_line_ptr;
26.58 + __u32 initrd_addr_max;
26.59 + __u32 kernel_alignment;
26.60 + __u8 relocatable_kernel;
26.61 + __u8 _pad2[3];
26.62 + __u32 cmdline_size;
26.63 + __u32 hardware_subarch;
26.64 + __u64 hardware_subarch_data;
26.65 + __u32 payload_offset;
26.66 + __u32 payload_length;
26.67 + __u64 setup_data;
26.68 +} __attribute__((packed));
26.69 +
26.70 +struct sys_desc_table {
26.71 + __u16 length;
26.72 + __u8 table[14];
26.73 +};
26.74 +
26.75 +struct efi_info {
26.76 + __u32 efi_loader_signature;
26.77 + __u32 efi_systab;
26.78 + __u32 efi_memdesc_size;
26.79 + __u32 efi_memdesc_version;
26.80 + __u32 efi_memmap;
26.81 + __u32 efi_memmap_size;
26.82 + __u32 efi_systab_hi;
26.83 + __u32 efi_memmap_hi;
26.84 +};
26.85 +
26.86 +/* The so-called "zeropage" */
26.87 +struct boot_params {
26.88 + struct screen_info screen_info; /* 0x000 */
26.89 + struct apm_bios_info apm_bios_info; /* 0x040 */
26.90 + __u8 _pad2[12]; /* 0x054 */
26.91 + struct ist_info ist_info; /* 0x060 */
26.92 + __u8 _pad3[16]; /* 0x070 */
26.93 + __u8 hd0_info[16]; /* obsolete! */ /* 0x080 */
26.94 + __u8 hd1_info[16]; /* obsolete! */ /* 0x090 */
26.95 + struct sys_desc_table sys_desc_table; /* 0x0a0 */
26.96 + __u8 _pad4[144]; /* 0x0b0 */
26.97 + struct edid_info edid_info; /* 0x140 */
26.98 + struct efi_info efi_info; /* 0x1c0 */
26.99 + __u32 alt_mem_k; /* 0x1e0 */
26.100 + __u32 scratch; /* Scratch field! */ /* 0x1e4 */
26.101 + __u8 e820_entries; /* 0x1e8 */
26.102 + __u8 eddbuf_entries; /* 0x1e9 */
26.103 + __u8 edd_mbr_sig_buf_entries; /* 0x1ea */
26.104 + __u8 _pad6[6]; /* 0x1eb */
26.105 + struct setup_header hdr; /* setup header */ /* 0x1f1 */
26.106 + __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
26.107 + __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
26.108 + struct e820entry e820_map[E820MAX]; /* 0x2d0 */
26.109 + __u8 _pad8[48]; /* 0xcd0 */
26.110 + struct edd_info eddbuf[EDDMAXNR]; /* 0xd00 */
26.111 + __u8 _pad9[276]; /* 0xeec */
26.112 +} __attribute__((packed));
26.113 +
26.114 +#endif /* _ASM_X86_BOOTPARAM_H */
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/arch/x86/include/asm/bug.h Sun Jan 11 20:20:11 2009 +0100
27.3 @@ -0,0 +1,39 @@
27.4 +#ifndef _ASM_X86_BUG_H
27.5 +#define _ASM_X86_BUG_H
27.6 +
27.7 +#ifdef CONFIG_BUG
27.8 +#define HAVE_ARCH_BUG
27.9 +
27.10 +#ifdef CONFIG_DEBUG_BUGVERBOSE
27.11 +
27.12 +#ifdef CONFIG_X86_32
27.13 +# define __BUG_C0 "2:\t.long 1b, %c0\n"
27.14 +#else
27.15 +# define __BUG_C0 "2:\t.quad 1b, %c0\n"
27.16 +#endif
27.17 +
27.18 +#define BUG() \
27.19 +do { \
27.20 + asm volatile("1:\tud2\n" \
27.21 + ".pushsection __bug_table,\"a\"\n" \
27.22 + __BUG_C0 \
27.23 + "\t.word %c1, 0\n" \
27.24 + "\t.org 2b+%c2\n" \
27.25 + ".popsection" \
27.26 + : : "i" (__FILE__), "i" (__LINE__), \
27.27 + "i" (sizeof(struct bug_entry))); \
27.28 + for (;;) ; \
27.29 +} while (0)
27.30 +
27.31 +#else
27.32 +#define BUG() \
27.33 +do { \
27.34 + asm volatile("ud2"); \
27.35 + for (;;) ; \
27.36 +} while (0)
27.37 +#endif
27.38 +
27.39 +#endif /* !CONFIG_BUG */
27.40 +
27.41 +#include <asm-generic/bug.h>
27.42 +#endif /* _ASM_X86_BUG_H */
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/arch/x86/include/asm/bugs.h Sun Jan 11 20:20:11 2009 +0100
28.3 @@ -0,0 +1,12 @@
28.4 +#ifndef _ASM_X86_BUGS_H
28.5 +#define _ASM_X86_BUGS_H
28.6 +
28.7 +extern void check_bugs(void);
28.8 +
28.9 +#if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
28.10 +int ppro_with_ram_bug(void);
28.11 +#else
28.12 +static inline int ppro_with_ram_bug(void) { return 0; }
28.13 +#endif
28.14 +
28.15 +#endif /* _ASM_X86_BUGS_H */
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/arch/x86/include/asm/byteorder.h Sun Jan 11 20:20:11 2009 +0100
29.3 @@ -0,0 +1,81 @@
29.4 +#ifndef _ASM_X86_BYTEORDER_H
29.5 +#define _ASM_X86_BYTEORDER_H
29.6 +
29.7 +#include <asm/types.h>
29.8 +#include <linux/compiler.h>
29.9 +
29.10 +#ifdef __GNUC__
29.11 +
29.12 +#ifdef __i386__
29.13 +
29.14 +static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
29.15 +{
29.16 +#ifdef CONFIG_X86_BSWAP
29.17 + asm("bswap %0" : "=r" (x) : "0" (x));
29.18 +#else
29.19 + asm("xchgb %b0,%h0\n\t" /* swap lower bytes */
29.20 + "rorl $16,%0\n\t" /* swap words */
29.21 + "xchgb %b0,%h0" /* swap higher bytes */
29.22 + : "=q" (x)
29.23 + : "0" (x));
29.24 +#endif
29.25 + return x;
29.26 +}
29.27 +
29.28 +static inline __attribute_const__ __u64 ___arch__swab64(__u64 val)
29.29 +{
29.30 + union {
29.31 + struct {
29.32 + __u32 a;
29.33 + __u32 b;
29.34 + } s;
29.35 + __u64 u;
29.36 + } v;
29.37 + v.u = val;
29.38 +#ifdef CONFIG_X86_BSWAP
29.39 + asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
29.40 + : "=r" (v.s.a), "=r" (v.s.b)
29.41 + : "0" (v.s.a), "1" (v.s.b));
29.42 +#else
29.43 + v.s.a = ___arch__swab32(v.s.a);
29.44 + v.s.b = ___arch__swab32(v.s.b);
29.45 + asm("xchgl %0,%1"
29.46 + : "=r" (v.s.a), "=r" (v.s.b)
29.47 + : "0" (v.s.a), "1" (v.s.b));
29.48 +#endif
29.49 + return v.u;
29.50 +}
29.51 +
29.52 +#else /* __i386__ */
29.53 +
29.54 +static inline __attribute_const__ __u64 ___arch__swab64(__u64 x)
29.55 +{
29.56 + asm("bswapq %0"
29.57 + : "=r" (x)
29.58 + : "0" (x));
29.59 + return x;
29.60 +}
29.61 +
29.62 +static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
29.63 +{
29.64 + asm("bswapl %0"
29.65 + : "=r" (x)
29.66 + : "0" (x));
29.67 + return x;
29.68 +}
29.69 +
29.70 +#endif
29.71 +
29.72 +/* Do not define swab16. Gcc is smart enough to recognize "C" version and
29.73 + convert it into rotation or exhange. */
29.74 +
29.75 +#define __arch__swab64(x) ___arch__swab64(x)
29.76 +#define __arch__swab32(x) ___arch__swab32(x)
29.77 +
29.78 +#define __BYTEORDER_HAS_U64__
29.79 +
29.80 +#endif /* __GNUC__ */
29.81 +
29.82 +#include <linux/byteorder/little_endian.h>
29.83 +
29.84 +#endif /* _ASM_X86_BYTEORDER_H */
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/arch/x86/include/asm/cache.h Sun Jan 11 20:20:11 2009 +0100
30.3 @@ -0,0 +1,20 @@
30.4 +#ifndef _ASM_X86_CACHE_H
30.5 +#define _ASM_X86_CACHE_H
30.6 +
30.7 +/* L1 cache line size */
30.8 +#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
30.9 +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
30.10 +
30.11 +#define __read_mostly __attribute__((__section__(".data.read_mostly")))
30.12 +
30.13 +#ifdef CONFIG_X86_VSMP
30.14 +/* vSMP Internode cacheline shift */
30.15 +#define INTERNODE_CACHE_SHIFT (12)
30.16 +#ifdef CONFIG_SMP
30.17 +#define __cacheline_aligned_in_smp \
30.18 + __attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT)))) \
30.19 + __attribute__((__section__(".data.page_aligned")))
30.20 +#endif
30.21 +#endif
30.22 +
30.23 +#endif /* _ASM_X86_CACHE_H */
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/arch/x86/include/asm/cacheflush.h Sun Jan 11 20:20:11 2009 +0100
31.3 @@ -0,0 +1,118 @@
31.4 +#ifndef _ASM_X86_CACHEFLUSH_H
31.5 +#define _ASM_X86_CACHEFLUSH_H
31.6 +
31.7 +/* Keep includes the same across arches. */
31.8 +#include <linux/mm.h>
31.9 +
31.10 +/* Caches aren't brain-dead on the intel. */
31.11 +#define flush_cache_all() do { } while (0)
31.12 +#define flush_cache_mm(mm) do { } while (0)
31.13 +#define flush_cache_dup_mm(mm) do { } while (0)
31.14 +#define flush_cache_range(vma, start, end) do { } while (0)
31.15 +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
31.16 +#define flush_dcache_page(page) do { } while (0)
31.17 +#define flush_dcache_mmap_lock(mapping) do { } while (0)
31.18 +#define flush_dcache_mmap_unlock(mapping) do { } while (0)
31.19 +#define flush_icache_range(start, end) do { } while (0)
31.20 +#define flush_icache_page(vma, pg) do { } while (0)
31.21 +#define flush_icache_user_range(vma, pg, adr, len) do { } while (0)
31.22 +#define flush_cache_vmap(start, end) do { } while (0)
31.23 +#define flush_cache_vunmap(start, end) do { } while (0)
31.24 +
31.25 +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
31.26 + memcpy((dst), (src), (len))
31.27 +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
31.28 + memcpy((dst), (src), (len))
31.29 +
31.30 +#define PG_non_WB PG_arch_1
31.31 +PAGEFLAG(NonWB, non_WB)
31.32 +
31.33 +/*
31.34 + * The set_memory_* API can be used to change various attributes of a virtual
31.35 + * address range. The attributes include:
31.36 + * Cachability : UnCached, WriteCombining, WriteBack
31.37 + * Executability : eXeutable, NoteXecutable
31.38 + * Read/Write : ReadOnly, ReadWrite
31.39 + * Presence : NotPresent
31.40 + *
31.41 + * Within a catagory, the attributes are mutually exclusive.
31.42 + *
31.43 + * The implementation of this API will take care of various aspects that
31.44 + * are associated with changing such attributes, such as:
31.45 + * - Flushing TLBs
31.46 + * - Flushing CPU caches
31.47 + * - Making sure aliases of the memory behind the mapping don't violate
31.48 + * coherency rules as defined by the CPU in the system.
31.49 + *
31.50 + * What this API does not do:
31.51 + * - Provide exclusion between various callers - including callers that
31.52 + * operation on other mappings of the same physical page
31.53 + * - Restore default attributes when a page is freed
31.54 + * - Guarantee that mappings other than the requested one are
31.55 + * in any state, other than that these do not violate rules for
31.56 + * the CPU you have. Do not depend on any effects on other mappings,
31.57 + * CPUs other than the one you have may have more relaxed rules.
31.58 + * The caller is required to take care of these.
31.59 + */
31.60 +
31.61 +int _set_memory_uc(unsigned long addr, int numpages);
31.62 +int _set_memory_wc(unsigned long addr, int numpages);
31.63 +int _set_memory_wb(unsigned long addr, int numpages);
31.64 +int set_memory_uc(unsigned long addr, int numpages);
31.65 +int set_memory_wc(unsigned long addr, int numpages);
31.66 +int set_memory_wb(unsigned long addr, int numpages);
31.67 +int set_memory_x(unsigned long addr, int numpages);
31.68 +int set_memory_nx(unsigned long addr, int numpages);
31.69 +int set_memory_ro(unsigned long addr, int numpages);
31.70 +int set_memory_rw(unsigned long addr, int numpages);
31.71 +int set_memory_np(unsigned long addr, int numpages);
31.72 +int set_memory_4k(unsigned long addr, int numpages);
31.73 +
31.74 +int set_memory_array_uc(unsigned long *addr, int addrinarray);
31.75 +int set_memory_array_wb(unsigned long *addr, int addrinarray);
31.76 +
31.77 +/*
31.78 + * For legacy compatibility with the old APIs, a few functions
31.79 + * are provided that work on a "struct page".
31.80 + * These functions operate ONLY on the 1:1 kernel mapping of the
31.81 + * memory that the struct page represents, and internally just
31.82 + * call the set_memory_* function. See the description of the
31.83 + * set_memory_* function for more details on conventions.
31.84 + *
31.85 + * These APIs should be considered *deprecated* and are likely going to
31.86 + * be removed in the future.
31.87 + * The reason for this is the implicit operation on the 1:1 mapping only,
31.88 + * making this not a generally useful API.
31.89 + *
31.90 + * Specifically, many users of the old APIs had a virtual address,
31.91 + * called virt_to_page() or vmalloc_to_page() on that address to
31.92 + * get a struct page* that the old API required.
31.93 + * To convert these cases, use set_memory_*() on the original
31.94 + * virtual address, do not use these functions.
31.95 + */
31.96 +
31.97 +int set_pages_uc(struct page *page, int numpages);
31.98 +int set_pages_wb(struct page *page, int numpages);
31.99 +int set_pages_x(struct page *page, int numpages);
31.100 +int set_pages_nx(struct page *page, int numpages);
31.101 +int set_pages_ro(struct page *page, int numpages);
31.102 +int set_pages_rw(struct page *page, int numpages);
31.103 +
31.104 +
31.105 +void clflush_cache_range(void *addr, unsigned int size);
31.106 +
31.107 +#ifdef CONFIG_DEBUG_RODATA
31.108 +void mark_rodata_ro(void);
31.109 +extern const int rodata_test_data;
31.110 +#endif
31.111 +
31.112 +#ifdef CONFIG_DEBUG_RODATA_TEST
31.113 +int rodata_test(void);
31.114 +#else
31.115 +static inline int rodata_test(void)
31.116 +{
31.117 + return 0;
31.118 +}
31.119 +#endif
31.120 +
31.121 +#endif /* _ASM_X86_CACHEFLUSH_H */
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/arch/x86/include/asm/calgary.h Sun Jan 11 20:20:11 2009 +0100
32.3 @@ -0,0 +1,72 @@
32.4 +/*
32.5 + * Derived from include/asm-powerpc/iommu.h
32.6 + *
32.7 + * Copyright IBM Corporation, 2006-2007
32.8 + *
32.9 + * Author: Jon Mason <jdmason@us.ibm.com>
32.10 + * Author: Muli Ben-Yehuda <muli@il.ibm.com>
32.11 + *
32.12 + * This program is free software; you can redistribute it and/or modify
32.13 + * it under the terms of the GNU General Public License as published by
32.14 + * the Free Software Foundation; either version 2 of the License, or
32.15 + * (at your option) any later version.
32.16 + *
32.17 + * This program is distributed in the hope that it will be useful,
32.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
32.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32.20 + * GNU General Public License for more details.
32.21 + *
32.22 + * You should have received a copy of the GNU General Public License
32.23 + * along with this program; if not, write to the Free Software
32.24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32.25 + */
32.26 +
32.27 +#ifndef _ASM_X86_CALGARY_H
32.28 +#define _ASM_X86_CALGARY_H
32.29 +
32.30 +#include <linux/spinlock.h>
32.31 +#include <linux/device.h>
32.32 +#include <linux/dma-mapping.h>
32.33 +#include <linux/timer.h>
32.34 +#include <asm/types.h>
32.35 +
32.36 +struct iommu_table {
32.37 + struct cal_chipset_ops *chip_ops; /* chipset specific funcs */
32.38 + unsigned long it_base; /* mapped address of tce table */
32.39 + unsigned long it_hint; /* Hint for next alloc */
32.40 + unsigned long *it_map; /* A simple allocation bitmap for now */
32.41 + void __iomem *bbar; /* Bridge BAR */
32.42 + u64 tar_val; /* Table Address Register */
32.43 + struct timer_list watchdog_timer;
32.44 + spinlock_t it_lock; /* Protects it_map */
32.45 + unsigned int it_size; /* Size of iommu table in entries */
32.46 + unsigned char it_busno; /* Bus number this table belongs to */
32.47 +};
32.48 +
32.49 +struct cal_chipset_ops {
32.50 + void (*handle_quirks)(struct iommu_table *tbl, struct pci_dev *dev);
32.51 + void (*tce_cache_blast)(struct iommu_table *tbl);
32.52 + void (*dump_error_regs)(struct iommu_table *tbl);
32.53 +};
32.54 +
32.55 +#define TCE_TABLE_SIZE_UNSPECIFIED ~0
32.56 +#define TCE_TABLE_SIZE_64K 0
32.57 +#define TCE_TABLE_SIZE_128K 1
32.58 +#define TCE_TABLE_SIZE_256K 2
32.59 +#define TCE_TABLE_SIZE_512K 3
32.60 +#define TCE_TABLE_SIZE_1M 4
32.61 +#define TCE_TABLE_SIZE_2M 5
32.62 +#define TCE_TABLE_SIZE_4M 6
32.63 +#define TCE_TABLE_SIZE_8M 7
32.64 +
32.65 +extern int use_calgary;
32.66 +
32.67 +#ifdef CONFIG_CALGARY_IOMMU
32.68 +extern int calgary_iommu_init(void);
32.69 +extern void detect_calgary(void);
32.70 +#else
32.71 +static inline int calgary_iommu_init(void) { return 1; }
32.72 +static inline void detect_calgary(void) { return; }
32.73 +#endif
32.74 +
32.75 +#endif /* _ASM_X86_CALGARY_H */
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/arch/x86/include/asm/calling.h Sun Jan 11 20:20:11 2009 +0100
33.3 @@ -0,0 +1,170 @@
33.4 +/*
33.5 + * Some macros to handle stack frames in assembly.
33.6 + */
33.7 +
33.8 +#define R15 0
33.9 +#define R14 8
33.10 +#define R13 16
33.11 +#define R12 24
33.12 +#define RBP 32
33.13 +#define RBX 40
33.14 +
33.15 +/* arguments: interrupts/non tracing syscalls only save upto here*/
33.16 +#define R11 48
33.17 +#define R10 56
33.18 +#define R9 64
33.19 +#define R8 72
33.20 +#define RAX 80
33.21 +#define RCX 88
33.22 +#define RDX 96
33.23 +#define RSI 104
33.24 +#define RDI 112
33.25 +#define ORIG_RAX 120 /* + error_code */
33.26 +/* end of arguments */
33.27 +
33.28 +/* cpu exception frame or undefined in case of fast syscall. */
33.29 +#define RIP 128
33.30 +#define CS 136
33.31 +#define EFLAGS 144
33.32 +#define RSP 152
33.33 +#define SS 160
33.34 +
33.35 +#define ARGOFFSET R11
33.36 +#define SWFRAME ORIG_RAX
33.37 +
33.38 + .macro SAVE_ARGS addskip=0, norcx=0, nor891011=0
33.39 + subq $9*8+\addskip, %rsp
33.40 + CFI_ADJUST_CFA_OFFSET 9*8+\addskip
33.41 + movq %rdi, 8*8(%rsp)
33.42 + CFI_REL_OFFSET rdi, 8*8
33.43 + movq %rsi, 7*8(%rsp)
33.44 + CFI_REL_OFFSET rsi, 7*8
33.45 + movq %rdx, 6*8(%rsp)
33.46 + CFI_REL_OFFSET rdx, 6*8
33.47 + .if \norcx
33.48 + .else
33.49 + movq %rcx, 5*8(%rsp)
33.50 + CFI_REL_OFFSET rcx, 5*8
33.51 + .endif
33.52 + movq %rax, 4*8(%rsp)
33.53 + CFI_REL_OFFSET rax, 4*8
33.54 + .if \nor891011
33.55 + .else
33.56 + movq %r8, 3*8(%rsp)
33.57 + CFI_REL_OFFSET r8, 3*8
33.58 + movq %r9, 2*8(%rsp)
33.59 + CFI_REL_OFFSET r9, 2*8
33.60 + movq %r10, 1*8(%rsp)
33.61 + CFI_REL_OFFSET r10, 1*8
33.62 + movq %r11, (%rsp)
33.63 + CFI_REL_OFFSET r11, 0*8
33.64 + .endif
33.65 + .endm
33.66 +
33.67 +#define ARG_SKIP 9*8
33.68 +
33.69 + .macro RESTORE_ARGS skiprax=0, addskip=0, skiprcx=0, skipr11=0, \
33.70 + skipr8910=0, skiprdx=0
33.71 + .if \skipr11
33.72 + .else
33.73 + movq (%rsp), %r11
33.74 + CFI_RESTORE r11
33.75 + .endif
33.76 + .if \skipr8910
33.77 + .else
33.78 + movq 1*8(%rsp), %r10
33.79 + CFI_RESTORE r10
33.80 + movq 2*8(%rsp), %r9
33.81 + CFI_RESTORE r9
33.82 + movq 3*8(%rsp), %r8
33.83 + CFI_RESTORE r8
33.84 + .endif
33.85 + .if \skiprax
33.86 + .else
33.87 + movq 4*8(%rsp), %rax
33.88 + CFI_RESTORE rax
33.89 + .endif
33.90 + .if \skiprcx
33.91 + .else
33.92 + movq 5*8(%rsp), %rcx
33.93 + CFI_RESTORE rcx
33.94 + .endif
33.95 + .if \skiprdx
33.96 + .else
33.97 + movq 6*8(%rsp), %rdx
33.98 + CFI_RESTORE rdx
33.99 + .endif
33.100 + movq 7*8(%rsp), %rsi
33.101 + CFI_RESTORE rsi
33.102 + movq 8*8(%rsp), %rdi
33.103 + CFI_RESTORE rdi
33.104 + .if ARG_SKIP+\addskip > 0
33.105 + addq $ARG_SKIP+\addskip, %rsp
33.106 + CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip)
33.107 + .endif
33.108 + .endm
33.109 +
33.110 + .macro LOAD_ARGS offset, skiprax=0
33.111 + movq \offset(%rsp), %r11
33.112 + movq \offset+8(%rsp), %r10
33.113 + movq \offset+16(%rsp), %r9
33.114 + movq \offset+24(%rsp), %r8
33.115 + movq \offset+40(%rsp), %rcx
33.116 + movq \offset+48(%rsp), %rdx
33.117 + movq \offset+56(%rsp), %rsi
33.118 + movq \offset+64(%rsp), %rdi
33.119 + .if \skiprax
33.120 + .else
33.121 + movq \offset+72(%rsp), %rax
33.122 + .endif
33.123 + .endm
33.124 +
33.125 +#define REST_SKIP 6*8
33.126 +
33.127 + .macro SAVE_REST
33.128 + subq $REST_SKIP, %rsp
33.129 + CFI_ADJUST_CFA_OFFSET REST_SKIP
33.130 + movq %rbx, 5*8(%rsp)
33.131 + CFI_REL_OFFSET rbx, 5*8
33.132 + movq %rbp, 4*8(%rsp)
33.133 + CFI_REL_OFFSET rbp, 4*8
33.134 + movq %r12, 3*8(%rsp)
33.135 + CFI_REL_OFFSET r12, 3*8
33.136 + movq %r13, 2*8(%rsp)
33.137 + CFI_REL_OFFSET r13, 2*8
33.138 + movq %r14, 1*8(%rsp)
33.139 + CFI_REL_OFFSET r14, 1*8
33.140 + movq %r15, (%rsp)
33.141 + CFI_REL_OFFSET r15, 0*8
33.142 + .endm
33.143 +
33.144 + .macro RESTORE_REST
33.145 + movq (%rsp), %r15
33.146 + CFI_RESTORE r15
33.147 + movq 1*8(%rsp), %r14
33.148 + CFI_RESTORE r14
33.149 + movq 2*8(%rsp), %r13
33.150 + CFI_RESTORE r13
33.151 + movq 3*8(%rsp), %r12
33.152 + CFI_RESTORE r12
33.153 + movq 4*8(%rsp), %rbp
33.154 + CFI_RESTORE rbp
33.155 + movq 5*8(%rsp), %rbx
33.156 + CFI_RESTORE rbx
33.157 + addq $REST_SKIP, %rsp
33.158 + CFI_ADJUST_CFA_OFFSET -(REST_SKIP)
33.159 + .endm
33.160 +
33.161 + .macro SAVE_ALL
33.162 + SAVE_ARGS
33.163 + SAVE_REST
33.164 + .endm
33.165 +
33.166 + .macro RESTORE_ALL addskip=0
33.167 + RESTORE_REST
33.168 + RESTORE_ARGS 0, \addskip
33.169 + .endm
33.170 +
33.171 + .macro icebp
33.172 + .byte 0xf1
33.173 + .endm
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/arch/x86/include/asm/checksum.h Sun Jan 11 20:20:11 2009 +0100
34.3 @@ -0,0 +1,5 @@
34.4 +#ifdef CONFIG_X86_32
34.5 +# include "checksum_32.h"
34.6 +#else
34.7 +# include "checksum_64.h"
34.8 +#endif
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/arch/x86/include/asm/checksum_32.h Sun Jan 11 20:20:11 2009 +0100
35.3 @@ -0,0 +1,189 @@
35.4 +#ifndef _ASM_X86_CHECKSUM_32_H
35.5 +#define _ASM_X86_CHECKSUM_32_H
35.6 +
35.7 +#include <linux/in6.h>
35.8 +
35.9 +#include <asm/uaccess.h>
35.10 +
35.11 +/*
35.12 + * computes the checksum of a memory block at buff, length len,
35.13 + * and adds in "sum" (32-bit)
35.14 + *
35.15 + * returns a 32-bit number suitable for feeding into itself
35.16 + * or csum_tcpudp_magic
35.17 + *
35.18 + * this function must be called with even lengths, except
35.19 + * for the last fragment, which may be odd
35.20 + *
35.21 + * it's best to have buff aligned on a 32-bit boundary
35.22 + */
35.23 +asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum);
35.24 +
35.25 +/*
35.26 + * the same as csum_partial, but copies from src while it
35.27 + * checksums, and handles user-space pointer exceptions correctly, when needed.
35.28 + *
35.29 + * here even more important to align src and dst on a 32-bit (or even
35.30 + * better 64-bit) boundary
35.31 + */
35.32 +
35.33 +asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
35.34 + int len, __wsum sum,
35.35 + int *src_err_ptr, int *dst_err_ptr);
35.36 +
35.37 +/*
35.38 + * Note: when you get a NULL pointer exception here this means someone
35.39 + * passed in an incorrect kernel address to one of these functions.
35.40 + *
35.41 + * If you use these functions directly please don't forget the
35.42 + * access_ok().
35.43 + */
35.44 +static inline __wsum csum_partial_copy_nocheck(const void *src, void *dst,
35.45 + int len, __wsum sum)
35.46 +{
35.47 + return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL);
35.48 +}
35.49 +
35.50 +static inline __wsum csum_partial_copy_from_user(const void __user *src,
35.51 + void *dst,
35.52 + int len, __wsum sum,
35.53 + int *err_ptr)
35.54 +{
35.55 + might_sleep();
35.56 + return csum_partial_copy_generic((__force void *)src, dst,
35.57 + len, sum, err_ptr, NULL);
35.58 +}
35.59 +
35.60 +/*
35.61 + * This is a version of ip_compute_csum() optimized for IP headers,
35.62 + * which always checksum on 4 octet boundaries.
35.63 + *
35.64 + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
35.65 + * Arnt Gulbrandsen.
35.66 + */
35.67 +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
35.68 +{
35.69 + unsigned int sum;
35.70 +
35.71 + asm volatile("movl (%1), %0 ;\n"
35.72 + "subl $4, %2 ;\n"
35.73 + "jbe 2f ;\n"
35.74 + "addl 4(%1), %0 ;\n"
35.75 + "adcl 8(%1), %0 ;\n"
35.76 + "adcl 12(%1), %0;\n"
35.77 + "1: adcl 16(%1), %0 ;\n"
35.78 + "lea 4(%1), %1 ;\n"
35.79 + "decl %2 ;\n"
35.80 + "jne 1b ;\n"
35.81 + "adcl $0, %0 ;\n"
35.82 + "movl %0, %2 ;\n"
35.83 + "shrl $16, %0 ;\n"
35.84 + "addw %w2, %w0 ;\n"
35.85 + "adcl $0, %0 ;\n"
35.86 + "notl %0 ;\n"
35.87 + "2: ;\n"
35.88 + /* Since the input registers which are loaded with iph and ihl
35.89 + are modified, we must also specify them as outputs, or gcc
35.90 + will assume they contain their original values. */
35.91 + : "=r" (sum), "=r" (iph), "=r" (ihl)
35.92 + : "1" (iph), "2" (ihl)
35.93 + : "memory");
35.94 + return (__force __sum16)sum;
35.95 +}
35.96 +
35.97 +/*
35.98 + * Fold a partial checksum
35.99 + */
35.100 +
35.101 +static inline __sum16 csum_fold(__wsum sum)
35.102 +{
35.103 + asm("addl %1, %0 ;\n"
35.104 + "adcl $0xffff, %0 ;\n"
35.105 + : "=r" (sum)
35.106 + : "r" ((__force u32)sum << 16),
35.107 + "0" ((__force u32)sum & 0xffff0000));
35.108 + return (__force __sum16)(~(__force u32)sum >> 16);
35.109 +}
35.110 +
35.111 +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
35.112 + unsigned short len,
35.113 + unsigned short proto,
35.114 + __wsum sum)
35.115 +{
35.116 + asm("addl %1, %0 ;\n"
35.117 + "adcl %2, %0 ;\n"
35.118 + "adcl %3, %0 ;\n"
35.119 + "adcl $0, %0 ;\n"
35.120 + : "=r" (sum)
35.121 + : "g" (daddr), "g"(saddr),
35.122 + "g" ((len + proto) << 8), "0" (sum));
35.123 + return sum;
35.124 +}
35.125 +
35.126 +/*
35.127 + * computes the checksum of the TCP/UDP pseudo-header
35.128 + * returns a 16-bit checksum, already complemented
35.129 + */
35.130 +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
35.131 + unsigned short len,
35.132 + unsigned short proto,
35.133 + __wsum sum)
35.134 +{
35.135 + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
35.136 +}
35.137 +
35.138 +/*
35.139 + * this routine is used for miscellaneous IP-like checksums, mainly
35.140 + * in icmp.c
35.141 + */
35.142 +
35.143 +static inline __sum16 ip_compute_csum(const void *buff, int len)
35.144 +{
35.145 + return csum_fold(csum_partial(buff, len, 0));
35.146 +}
35.147 +
35.148 +#define _HAVE_ARCH_IPV6_CSUM
35.149 +static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
35.150 + const struct in6_addr *daddr,
35.151 + __u32 len, unsigned short proto,
35.152 + __wsum sum)
35.153 +{
35.154 + asm("addl 0(%1), %0 ;\n"
35.155 + "adcl 4(%1), %0 ;\n"
35.156 + "adcl 8(%1), %0 ;\n"
35.157 + "adcl 12(%1), %0 ;\n"
35.158 + "adcl 0(%2), %0 ;\n"
35.159 + "adcl 4(%2), %0 ;\n"
35.160 + "adcl 8(%2), %0 ;\n"
35.161 + "adcl 12(%2), %0 ;\n"
35.162 + "adcl %3, %0 ;\n"
35.163 + "adcl %4, %0 ;\n"
35.164 + "adcl $0, %0 ;\n"
35.165 + : "=&r" (sum)
35.166 + : "r" (saddr), "r" (daddr),
35.167 + "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
35.168 +
35.169 + return csum_fold(sum);
35.170 +}
35.171 +
35.172 +/*
35.173 + * Copy and checksum to user
35.174 + */
35.175 +#define HAVE_CSUM_COPY_USER
35.176 +static inline __wsum csum_and_copy_to_user(const void *src,
35.177 + void __user *dst,
35.178 + int len, __wsum sum,
35.179 + int *err_ptr)
35.180 +{
35.181 + might_sleep();
35.182 + if (access_ok(VERIFY_WRITE, dst, len))
35.183 + return csum_partial_copy_generic(src, (__force void *)dst,
35.184 + len, sum, NULL, err_ptr);
35.185 +
35.186 + if (len)
35.187 + *err_ptr = -EFAULT;
35.188 +
35.189 + return (__force __wsum)-1; /* invalid checksum */
35.190 +}
35.191 +
35.192 +#endif /* _ASM_X86_CHECKSUM_32_H */
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/arch/x86/include/asm/checksum_64.h Sun Jan 11 20:20:11 2009 +0100
36.3 @@ -0,0 +1,191 @@
36.4 +#ifndef _ASM_X86_CHECKSUM_64_H
36.5 +#define _ASM_X86_CHECKSUM_64_H
36.6 +
36.7 +/*
36.8 + * Checksums for x86-64
36.9 + * Copyright 2002 by Andi Kleen, SuSE Labs
36.10 + * with some code from asm-x86/checksum.h
36.11 + */
36.12 +
36.13 +#include <linux/compiler.h>
36.14 +#include <asm/uaccess.h>
36.15 +#include <asm/byteorder.h>
36.16 +
36.17 +/**
36.18 + * csum_fold - Fold and invert a 32bit checksum.
36.19 + * sum: 32bit unfolded sum
36.20 + *
36.21 + * Fold a 32bit running checksum to 16bit and invert it. This is usually
36.22 + * the last step before putting a checksum into a packet.
36.23 + * Make sure not to mix with 64bit checksums.
36.24 + */
36.25 +static inline __sum16 csum_fold(__wsum sum)
36.26 +{
36.27 + asm(" addl %1,%0\n"
36.28 + " adcl $0xffff,%0"
36.29 + : "=r" (sum)
36.30 + : "r" ((__force u32)sum << 16),
36.31 + "0" ((__force u32)sum & 0xffff0000));
36.32 + return (__force __sum16)(~(__force u32)sum >> 16);
36.33 +}
36.34 +
36.35 +/*
36.36 + * This is a version of ip_compute_csum() optimized for IP headers,
36.37 + * which always checksum on 4 octet boundaries.
36.38 + *
36.39 + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
36.40 + * Arnt Gulbrandsen.
36.41 + */
36.42 +
36.43 +/**
36.44 + * ip_fast_csum - Compute the IPv4 header checksum efficiently.
36.45 + * iph: ipv4 header
36.46 + * ihl: length of header / 4
36.47 + */
36.48 +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
36.49 +{
36.50 + unsigned int sum;
36.51 +
36.52 + asm(" movl (%1), %0\n"
36.53 + " subl $4, %2\n"
36.54 + " jbe 2f\n"
36.55 + " addl 4(%1), %0\n"
36.56 + " adcl 8(%1), %0\n"
36.57 + " adcl 12(%1), %0\n"
36.58 + "1: adcl 16(%1), %0\n"
36.59 + " lea 4(%1), %1\n"
36.60 + " decl %2\n"
36.61 + " jne 1b\n"
36.62 + " adcl $0, %0\n"
36.63 + " movl %0, %2\n"
36.64 + " shrl $16, %0\n"
36.65 + " addw %w2, %w0\n"
36.66 + " adcl $0, %0\n"
36.67 + " notl %0\n"
36.68 + "2:"
36.69 + /* Since the input registers which are loaded with iph and ihl
36.70 + are modified, we must also specify them as outputs, or gcc
36.71 + will assume they contain their original values. */
36.72 + : "=r" (sum), "=r" (iph), "=r" (ihl)
36.73 + : "1" (iph), "2" (ihl)
36.74 + : "memory");
36.75 + return (__force __sum16)sum;
36.76 +}
36.77 +
36.78 +/**
36.79 + * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
36.80 + * @saddr: source address
36.81 + * @daddr: destination address
36.82 + * @len: length of packet
36.83 + * @proto: ip protocol of packet
36.84 + * @sum: initial sum to be added in (32bit unfolded)
36.85 + *
36.86 + * Returns the pseudo header checksum the input data. Result is
36.87 + * 32bit unfolded.
36.88 + */
36.89 +static inline __wsum
36.90 +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
36.91 + unsigned short proto, __wsum sum)
36.92 +{
36.93 + asm(" addl %1, %0\n"
36.94 + " adcl %2, %0\n"
36.95 + " adcl %3, %0\n"
36.96 + " adcl $0, %0\n"
36.97 + : "=r" (sum)
36.98 + : "g" (daddr), "g" (saddr),
36.99 + "g" ((len + proto)<<8), "0" (sum));
36.100 + return sum;
36.101 +}
36.102 +
36.103 +
36.104 +/**
36.105 + * csum_tcpup_magic - Compute an IPv4 pseudo header checksum.
36.106 + * @saddr: source address
36.107 + * @daddr: destination address
36.108 + * @len: length of packet
36.109 + * @proto: ip protocol of packet
36.110 + * @sum: initial sum to be added in (32bit unfolded)
36.111 + *
36.112 + * Returns the 16bit pseudo header checksum the input data already
36.113 + * complemented and ready to be filled in.
36.114 + */
36.115 +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
36.116 + unsigned short len,
36.117 + unsigned short proto, __wsum sum)
36.118 +{
36.119 + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
36.120 +}
36.121 +
36.122 +/**
36.123 + * csum_partial - Compute an internet checksum.
36.124 + * @buff: buffer to be checksummed
36.125 + * @len: length of buffer.
36.126 + * @sum: initial sum to be added in (32bit unfolded)
36.127 + *
36.128 + * Returns the 32bit unfolded internet checksum of the buffer.
36.129 + * Before filling it in it needs to be csum_fold()'ed.
36.130 + * buff should be aligned to a 64bit boundary if possible.
36.131 + */
36.132 +extern __wsum csum_partial(const void *buff, int len, __wsum sum);
36.133 +
36.134 +#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 1
36.135 +#define HAVE_CSUM_COPY_USER 1
36.136 +
36.137 +
36.138 +/* Do not call this directly. Use the wrappers below */
36.139 +extern __wsum csum_partial_copy_generic(const void *src, const void *dst,
36.140 + int len, __wsum sum,
36.141 + int *src_err_ptr, int *dst_err_ptr);
36.142 +
36.143 +
36.144 +extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
36.145 + int len, __wsum isum, int *errp);
36.146 +extern __wsum csum_partial_copy_to_user(const void *src, void __user *dst,
36.147 + int len, __wsum isum, int *errp);
36.148 +extern __wsum csum_partial_copy_nocheck(const void *src, void *dst,
36.149 + int len, __wsum sum);
36.150 +
36.151 +/* Old names. To be removed. */
36.152 +#define csum_and_copy_to_user csum_partial_copy_to_user
36.153 +#define csum_and_copy_from_user csum_partial_copy_from_user
36.154 +
36.155 +/**
36.156 + * ip_compute_csum - Compute an 16bit IP checksum.
36.157 + * @buff: buffer address.
36.158 + * @len: length of buffer.
36.159 + *
36.160 + * Returns the 16bit folded/inverted checksum of the passed buffer.
36.161 + * Ready to fill in.
36.162 + */
36.163 +extern __sum16 ip_compute_csum(const void *buff, int len);
36.164 +
36.165 +/**
36.166 + * csum_ipv6_magic - Compute checksum of an IPv6 pseudo header.
36.167 + * @saddr: source address
36.168 + * @daddr: destination address
36.169 + * @len: length of packet
36.170 + * @proto: protocol of packet
36.171 + * @sum: initial sum (32bit unfolded) to be added in
36.172 + *
36.173 + * Computes an IPv6 pseudo header checksum. This sum is added the checksum
36.174 + * into UDP/TCP packets and contains some link layer information.
36.175 + * Returns the unfolded 32bit checksum.
36.176 + */
36.177 +
36.178 +struct in6_addr;
36.179 +
36.180 +#define _HAVE_ARCH_IPV6_CSUM 1
36.181 +extern __sum16
36.182 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
36.183 + __u32 len, unsigned short proto, __wsum sum);
36.184 +
36.185 +static inline unsigned add32_with_carry(unsigned a, unsigned b)
36.186 +{
36.187 + asm("addl %2,%0\n\t"
36.188 + "adcl $0,%0"
36.189 + : "=r" (a)
36.190 + : "0" (a), "r" (b));
36.191 + return a;
36.192 +}
36.193 +
36.194 +#endif /* _ASM_X86_CHECKSUM_64_H */
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/arch/x86/include/asm/cmpxchg.h Sun Jan 11 20:20:11 2009 +0100
37.3 @@ -0,0 +1,5 @@
37.4 +#ifdef CONFIG_X86_32
37.5 +# include "cmpxchg_32.h"
37.6 +#else
37.7 +# include "cmpxchg_64.h"
37.8 +#endif
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/arch/x86/include/asm/cmpxchg_32.h Sun Jan 11 20:20:11 2009 +0100
38.3 @@ -0,0 +1,344 @@
38.4 +#ifndef _ASM_X86_CMPXCHG_32_H
38.5 +#define _ASM_X86_CMPXCHG_32_H
38.6 +
38.7 +#include <linux/bitops.h> /* for LOCK_PREFIX */
38.8 +
38.9 +/*
38.10 + * Note: if you use set64_bit(), __cmpxchg64(), or their variants, you
38.11 + * you need to test for the feature in boot_cpu_data.
38.12 + */
38.13 +
38.14 +#define xchg(ptr, v) \
38.15 + ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), sizeof(*(ptr))))
38.16 +
38.17 +struct __xchg_dummy {
38.18 + unsigned long a[100];
38.19 +};
38.20 +#define __xg(x) ((struct __xchg_dummy *)(x))
38.21 +
38.22 +/*
38.23 + * The semantics of XCHGCMP8B are a bit strange, this is why
38.24 + * there is a loop and the loading of %%eax and %%edx has to
38.25 + * be inside. This inlines well in most cases, the cached
38.26 + * cost is around ~38 cycles. (in the future we might want
38.27 + * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
38.28 + * might have an implicit FPU-save as a cost, so it's not
38.29 + * clear which path to go.)
38.30 + *
38.31 + * cmpxchg8b must be used with the lock prefix here to allow
38.32 + * the instruction to be executed atomically, see page 3-102
38.33 + * of the instruction set reference 24319102.pdf. We need
38.34 + * the reader side to see the coherent 64bit value.
38.35 + */
38.36 +static inline void __set_64bit(unsigned long long *ptr,
38.37 + unsigned int low, unsigned int high)
38.38 +{
38.39 + asm volatile("\n1:\t"
38.40 + "movl (%0), %%eax\n\t"
38.41 + "movl 4(%0), %%edx\n\t"
38.42 + LOCK_PREFIX "cmpxchg8b (%0)\n\t"
38.43 + "jnz 1b"
38.44 + : /* no outputs */
38.45 + : "D"(ptr),
38.46 + "b"(low),
38.47 + "c"(high)
38.48 + : "ax", "dx", "memory");
38.49 +}
38.50 +
38.51 +static inline void __set_64bit_constant(unsigned long long *ptr,
38.52 + unsigned long long value)
38.53 +{
38.54 + __set_64bit(ptr, (unsigned int)value, (unsigned int)(value >> 32));
38.55 +}
38.56 +
38.57 +#define ll_low(x) *(((unsigned int *)&(x)) + 0)
38.58 +#define ll_high(x) *(((unsigned int *)&(x)) + 1)
38.59 +
38.60 +static inline void __set_64bit_var(unsigned long long *ptr,
38.61 + unsigned long long value)
38.62 +{
38.63 + __set_64bit(ptr, ll_low(value), ll_high(value));
38.64 +}
38.65 +
38.66 +#define set_64bit(ptr, value) \
38.67 + (__builtin_constant_p((value)) \
38.68 + ? __set_64bit_constant((ptr), (value)) \
38.69 + : __set_64bit_var((ptr), (value)))
38.70 +
38.71 +#define _set_64bit(ptr, value) \
38.72 + (__builtin_constant_p(value) \
38.73 + ? __set_64bit(ptr, (unsigned int)(value), \
38.74 + (unsigned int)((value) >> 32)) \
38.75 + : __set_64bit(ptr, ll_low((value)), ll_high((value))))
38.76 +
38.77 +/*
38.78 + * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
38.79 + * Note 2: xchg has side effect, so that attribute volatile is necessary,
38.80 + * but generally the primitive is invalid, *ptr is output argument. --ANK
38.81 + */
38.82 +static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
38.83 + int size)
38.84 +{
38.85 + switch (size) {
38.86 + case 1:
38.87 + asm volatile("xchgb %b0,%1"
38.88 + : "=q" (x)
38.89 + : "m" (*__xg(ptr)), "0" (x)
38.90 + : "memory");
38.91 + break;
38.92 + case 2:
38.93 + asm volatile("xchgw %w0,%1"
38.94 + : "=r" (x)
38.95 + : "m" (*__xg(ptr)), "0" (x)
38.96 + : "memory");
38.97 + break;
38.98 + case 4:
38.99 + asm volatile("xchgl %0,%1"
38.100 + : "=r" (x)
38.101 + : "m" (*__xg(ptr)), "0" (x)
38.102 + : "memory");
38.103 + break;
38.104 + }
38.105 + return x;
38.106 +}
38.107 +
38.108 +/*
38.109 + * Atomic compare and exchange. Compare OLD with MEM, if identical,
38.110 + * store NEW in MEM. Return the initial value in MEM. Success is
38.111 + * indicated by comparing RETURN with OLD.
38.112 + */
38.113 +
38.114 +#ifdef CONFIG_X86_CMPXCHG
38.115 +#define __HAVE_ARCH_CMPXCHG 1
38.116 +#define cmpxchg(ptr, o, n) \
38.117 + ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \
38.118 + (unsigned long)(n), \
38.119 + sizeof(*(ptr))))
38.120 +#define sync_cmpxchg(ptr, o, n) \
38.121 + ((__typeof__(*(ptr)))__sync_cmpxchg((ptr), (unsigned long)(o), \
38.122 + (unsigned long)(n), \
38.123 + sizeof(*(ptr))))
38.124 +#define cmpxchg_local(ptr, o, n) \
38.125 + ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
38.126 + (unsigned long)(n), \
38.127 + sizeof(*(ptr))))
38.128 +#endif
38.129 +
38.130 +#ifdef CONFIG_X86_CMPXCHG64
38.131 +#define cmpxchg64(ptr, o, n) \
38.132 + ((__typeof__(*(ptr)))__cmpxchg64((ptr), (unsigned long long)(o), \
38.133 + (unsigned long long)(n)))
38.134 +#define cmpxchg64_local(ptr, o, n) \
38.135 + ((__typeof__(*(ptr)))__cmpxchg64_local((ptr), (unsigned long long)(o), \
38.136 + (unsigned long long)(n)))
38.137 +#endif
38.138 +
38.139 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
38.140 + unsigned long new, int size)
38.141 +{
38.142 + unsigned long prev;
38.143 + switch (size) {
38.144 + case 1:
38.145 + asm volatile(LOCK_PREFIX "cmpxchgb %b1,%2"
38.146 + : "=a"(prev)
38.147 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
38.148 + : "memory");
38.149 + return prev;
38.150 + case 2:
38.151 + asm volatile(LOCK_PREFIX "cmpxchgw %w1,%2"
38.152 + : "=a"(prev)
38.153 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
38.154 + : "memory");
38.155 + return prev;
38.156 + case 4:
38.157 + asm volatile(LOCK_PREFIX "cmpxchgl %1,%2"
38.158 + : "=a"(prev)
38.159 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
38.160 + : "memory");
38.161 + return prev;
38.162 + }
38.163 + return old;
38.164 +}
38.165 +
38.166 +/*
38.167 + * Always use locked operations when touching memory shared with a
38.168 + * hypervisor, since the system may be SMP even if the guest kernel
38.169 + * isn't.
38.170 + */
38.171 +static inline unsigned long __sync_cmpxchg(volatile void *ptr,
38.172 + unsigned long old,
38.173 + unsigned long new, int size)
38.174 +{
38.175 + unsigned long prev;
38.176 + switch (size) {
38.177 + case 1:
38.178 + asm volatile("lock; cmpxchgb %b1,%2"
38.179 + : "=a"(prev)
38.180 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
38.181 + : "memory");
38.182 + return prev;
38.183 + case 2:
38.184 + asm volatile("lock; cmpxchgw %w1,%2"
38.185 + : "=a"(prev)
38.186 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
38.187 + : "memory");
38.188 + return prev;
38.189 + case 4:
38.190 + asm volatile("lock; cmpxchgl %1,%2"
38.191 + : "=a"(prev)
38.192 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
38.193 + : "memory");
38.194 + return prev;
38.195 + }
38.196 + return old;
38.197 +}
38.198 +
38.199 +static inline unsigned long __cmpxchg_local(volatile void *ptr,
38.200 + unsigned long old,
38.201 + unsigned long new, int size)
38.202 +{
38.203 + unsigned long prev;
38.204 + switch (size) {
38.205 + case 1:
38.206 + asm volatile("cmpxchgb %b1,%2"
38.207 + : "=a"(prev)
38.208 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
38.209 + : "memory");
38.210 + return prev;
38.211 + case 2:
38.212 + asm volatile("cmpxchgw %w1,%2"
38.213 + : "=a"(prev)
38.214 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
38.215 + : "memory");
38.216 + return prev;
38.217 + case 4:
38.218 + asm volatile("cmpxchgl %1,%2"
38.219 + : "=a"(prev)
38.220 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
38.221 + : "memory");
38.222 + return prev;
38.223 + }
38.224 + return old;
38.225 +}
38.226 +
38.227 +static inline unsigned long long __cmpxchg64(volatile void *ptr,
38.228 + unsigned long long old,
38.229 + unsigned long long new)
38.230 +{
38.231 + unsigned long long prev;
38.232 + asm volatile(LOCK_PREFIX "cmpxchg8b %3"
38.233 + : "=A"(prev)
38.234 + : "b"((unsigned long)new),
38.235 + "c"((unsigned long)(new >> 32)),
38.236 + "m"(*__xg(ptr)),
38.237 + "0"(old)
38.238 + : "memory");
38.239 + return prev;
38.240 +}
38.241 +
38.242 +static inline unsigned long long __cmpxchg64_local(volatile void *ptr,
38.243 + unsigned long long old,
38.244 + unsigned long long new)
38.245 +{
38.246 + unsigned long long prev;
38.247 + asm volatile("cmpxchg8b %3"
38.248 + : "=A"(prev)
38.249 + : "b"((unsigned long)new),
38.250 + "c"((unsigned long)(new >> 32)),
38.251 + "m"(*__xg(ptr)),
38.252 + "0"(old)
38.253 + : "memory");
38.254 + return prev;
38.255 +}
38.256 +
38.257 +#ifndef CONFIG_X86_CMPXCHG
38.258 +/*
38.259 + * Building a kernel capable running on 80386. It may be necessary to
38.260 + * simulate the cmpxchg on the 80386 CPU. For that purpose we define
38.261 + * a function for each of the sizes we support.
38.262 + */
38.263 +
38.264 +extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
38.265 +extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
38.266 +extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
38.267 +
38.268 +static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
38.269 + unsigned long new, int size)
38.270 +{
38.271 + switch (size) {
38.272 + case 1:
38.273 + return cmpxchg_386_u8(ptr, old, new);
38.274 + case 2:
38.275 + return cmpxchg_386_u16(ptr, old, new);
38.276 + case 4:
38.277 + return cmpxchg_386_u32(ptr, old, new);
38.278 + }
38.279 + return old;
38.280 +}
38.281 +
38.282 +#define cmpxchg(ptr, o, n) \
38.283 +({ \
38.284 + __typeof__(*(ptr)) __ret; \
38.285 + if (likely(boot_cpu_data.x86 > 3)) \
38.286 + __ret = (__typeof__(*(ptr)))__cmpxchg((ptr), \
38.287 + (unsigned long)(o), (unsigned long)(n), \
38.288 + sizeof(*(ptr))); \
38.289 + else \
38.290 + __ret = (__typeof__(*(ptr)))cmpxchg_386((ptr), \
38.291 + (unsigned long)(o), (unsigned long)(n), \
38.292 + sizeof(*(ptr))); \
38.293 + __ret; \
38.294 +})
38.295 +#define cmpxchg_local(ptr, o, n) \
38.296 +({ \
38.297 + __typeof__(*(ptr)) __ret; \
38.298 + if (likely(boot_cpu_data.x86 > 3)) \
38.299 + __ret = (__typeof__(*(ptr)))__cmpxchg_local((ptr), \
38.300 + (unsigned long)(o), (unsigned long)(n), \
38.301 + sizeof(*(ptr))); \
38.302 + else \
38.303 + __ret = (__typeof__(*(ptr)))cmpxchg_386((ptr), \
38.304 + (unsigned long)(o), (unsigned long)(n), \
38.305 + sizeof(*(ptr))); \
38.306 + __ret; \
38.307 +})
38.308 +#endif
38.309 +
38.310 +#ifndef CONFIG_X86_CMPXCHG64
38.311 +/*
38.312 + * Building a kernel capable running on 80386 and 80486. It may be necessary
38.313 + * to simulate the cmpxchg8b on the 80386 and 80486 CPU.
38.314 + */
38.315 +
38.316 +extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
38.317 +
38.318 +#define cmpxchg64(ptr, o, n) \
38.319 +({ \
38.320 + __typeof__(*(ptr)) __ret; \
38.321 + if (likely(boot_cpu_data.x86 > 4)) \
38.322 + __ret = (__typeof__(*(ptr)))__cmpxchg64((ptr), \
38.323 + (unsigned long long)(o), \
38.324 + (unsigned long long)(n)); \
38.325 + else \
38.326 + __ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr), \
38.327 + (unsigned long long)(o), \
38.328 + (unsigned long long)(n)); \
38.329 + __ret; \
38.330 +})
38.331 +#define cmpxchg64_local(ptr, o, n) \
38.332 +({ \
38.333 + __typeof__(*(ptr)) __ret; \
38.334 + if (likely(boot_cpu_data.x86 > 4)) \
38.335 + __ret = (__typeof__(*(ptr)))__cmpxchg64_local((ptr), \
38.336 + (unsigned long long)(o), \
38.337 + (unsigned long long)(n)); \
38.338 + else \
38.339 + __ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr), \
38.340 + (unsigned long long)(o), \
38.341 + (unsigned long long)(n)); \
38.342 + __ret; \
38.343 +})
38.344 +
38.345 +#endif
38.346 +
38.347 +#endif /* _ASM_X86_CMPXCHG_32_H */
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/arch/x86/include/asm/cmpxchg_64.h Sun Jan 11 20:20:11 2009 +0100
39.3 @@ -0,0 +1,185 @@
39.4 +#ifndef _ASM_X86_CMPXCHG_64_H
39.5 +#define _ASM_X86_CMPXCHG_64_H
39.6 +
39.7 +#include <asm/alternative.h> /* Provides LOCK_PREFIX */
39.8 +
39.9 +#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), \
39.10 + (ptr), sizeof(*(ptr))))
39.11 +
39.12 +#define __xg(x) ((volatile long *)(x))
39.13 +
39.14 +static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
39.15 +{
39.16 + *ptr = val;
39.17 +}
39.18 +
39.19 +#define _set_64bit set_64bit
39.20 +
39.21 +/*
39.22 + * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
39.23 + * Note 2: xchg has side effect, so that attribute volatile is necessary,
39.24 + * but generally the primitive is invalid, *ptr is output argument. --ANK
39.25 + */
39.26 +static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
39.27 + int size)
39.28 +{
39.29 + switch (size) {
39.30 + case 1:
39.31 + asm volatile("xchgb %b0,%1"
39.32 + : "=q" (x)
39.33 + : "m" (*__xg(ptr)), "0" (x)
39.34 + : "memory");
39.35 + break;
39.36 + case 2:
39.37 + asm volatile("xchgw %w0,%1"
39.38 + : "=r" (x)
39.39 + : "m" (*__xg(ptr)), "0" (x)
39.40 + : "memory");
39.41 + break;
39.42 + case 4:
39.43 + asm volatile("xchgl %k0,%1"
39.44 + : "=r" (x)
39.45 + : "m" (*__xg(ptr)), "0" (x)
39.46 + : "memory");
39.47 + break;
39.48 + case 8:
39.49 + asm volatile("xchgq %0,%1"
39.50 + : "=r" (x)
39.51 + : "m" (*__xg(ptr)), "0" (x)
39.52 + : "memory");
39.53 + break;
39.54 + }
39.55 + return x;
39.56 +}
39.57 +
39.58 +/*
39.59 + * Atomic compare and exchange. Compare OLD with MEM, if identical,
39.60 + * store NEW in MEM. Return the initial value in MEM. Success is
39.61 + * indicated by comparing RETURN with OLD.
39.62 + */
39.63 +
39.64 +#define __HAVE_ARCH_CMPXCHG 1
39.65 +
39.66 +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
39.67 + unsigned long new, int size)
39.68 +{
39.69 + unsigned long prev;
39.70 + switch (size) {
39.71 + case 1:
39.72 + asm volatile(LOCK_PREFIX "cmpxchgb %b1,%2"
39.73 + : "=a"(prev)
39.74 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
39.75 + : "memory");
39.76 + return prev;
39.77 + case 2:
39.78 + asm volatile(LOCK_PREFIX "cmpxchgw %w1,%2"
39.79 + : "=a"(prev)
39.80 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
39.81 + : "memory");
39.82 + return prev;
39.83 + case 4:
39.84 + asm volatile(LOCK_PREFIX "cmpxchgl %k1,%2"
39.85 + : "=a"(prev)
39.86 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
39.87 + : "memory");
39.88 + return prev;
39.89 + case 8:
39.90 + asm volatile(LOCK_PREFIX "cmpxchgq %1,%2"
39.91 + : "=a"(prev)
39.92 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
39.93 + : "memory");
39.94 + return prev;
39.95 + }
39.96 + return old;
39.97 +}
39.98 +
39.99 +/*
39.100 + * Always use locked operations when touching memory shared with a
39.101 + * hypervisor, since the system may be SMP even if the guest kernel
39.102 + * isn't.
39.103 + */
39.104 +static inline unsigned long __sync_cmpxchg(volatile void *ptr,
39.105 + unsigned long old,
39.106 + unsigned long new, int size)
39.107 +{
39.108 + unsigned long prev;
39.109 + switch (size) {
39.110 + case 1:
39.111 + asm volatile("lock; cmpxchgb %b1,%2"
39.112 + : "=a"(prev)
39.113 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
39.114 + : "memory");
39.115 + return prev;
39.116 + case 2:
39.117 + asm volatile("lock; cmpxchgw %w1,%2"
39.118 + : "=a"(prev)
39.119 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
39.120 + : "memory");
39.121 + return prev;
39.122 + case 4:
39.123 + asm volatile("lock; cmpxchgl %1,%2"
39.124 + : "=a"(prev)
39.125 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
39.126 + : "memory");
39.127 + return prev;
39.128 + }
39.129 + return old;
39.130 +}
39.131 +
39.132 +static inline unsigned long __cmpxchg_local(volatile void *ptr,
39.133 + unsigned long old,
39.134 + unsigned long new, int size)
39.135 +{
39.136 + unsigned long prev;
39.137 + switch (size) {
39.138 + case 1:
39.139 + asm volatile("cmpxchgb %b1,%2"
39.140 + : "=a"(prev)
39.141 + : "q"(new), "m"(*__xg(ptr)), "0"(old)
39.142 + : "memory");
39.143 + return prev;
39.144 + case 2:
39.145 + asm volatile("cmpxchgw %w1,%2"
39.146 + : "=a"(prev)
39.147 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
39.148 + : "memory");
39.149 + return prev;
39.150 + case 4:
39.151 + asm volatile("cmpxchgl %k1,%2"
39.152 + : "=a"(prev)
39.153 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
39.154 + : "memory");
39.155 + return prev;
39.156 + case 8:
39.157 + asm volatile("cmpxchgq %1,%2"
39.158 + : "=a"(prev)
39.159 + : "r"(new), "m"(*__xg(ptr)), "0"(old)
39.160 + : "memory");
39.161 + return prev;
39.162 + }
39.163 + return old;
39.164 +}
39.165 +
39.166 +#define cmpxchg(ptr, o, n) \
39.167 + ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \
39.168 + (unsigned long)(n), sizeof(*(ptr))))
39.169 +#define cmpxchg64(ptr, o, n) \
39.170 +({ \
39.171 + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
39.172 + cmpxchg((ptr), (o), (n)); \
39.173 +})
39.174 +#define cmpxchg_local(ptr, o, n) \
39.175 + ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
39.176 + (unsigned long)(n), \
39.177 + sizeof(*(ptr))))
39.178 +#define sync_cmpxchg(ptr, o, n) \
39.179 + ((__typeof__(*(ptr)))__sync_cmpxchg((ptr), (unsigned long)(o), \
39.180 + (unsigned long)(n), \
39.181 + sizeof(*(ptr))))
39.182 +#define cmpxchg64_local(ptr, o, n) \
39.183 +({ \
39.184 + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
39.185 + cmpxchg_local((ptr), (o), (n)); \
39.186 +})
39.187 +
39.188 +#endif /* _ASM_X86_CMPXCHG_64_H */
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/arch/x86/include/asm/compat.h Sun Jan 11 20:20:11 2009 +0100
40.3 @@ -0,0 +1,218 @@
40.4 +#ifndef _ASM_X86_COMPAT_H
40.5 +#define _ASM_X86_COMPAT_H
40.6 +
40.7 +/*
40.8 + * Architecture specific compatibility types
40.9 + */
40.10 +#include <linux/types.h>
40.11 +#include <linux/sched.h>
40.12 +#include <asm/user32.h>
40.13 +
40.14 +#define COMPAT_USER_HZ 100
40.15 +
40.16 +typedef u32 compat_size_t;
40.17 +typedef s32 compat_ssize_t;
40.18 +typedef s32 compat_time_t;
40.19 +typedef s32 compat_clock_t;
40.20 +typedef s32 compat_pid_t;
40.21 +typedef u16 __compat_uid_t;
40.22 +typedef u16 __compat_gid_t;
40.23 +typedef u32 __compat_uid32_t;
40.24 +typedef u32 __compat_gid32_t;
40.25 +typedef u16 compat_mode_t;
40.26 +typedef u32 compat_ino_t;
40.27 +typedef u16 compat_dev_t;
40.28 +typedef s32 compat_off_t;
40.29 +typedef s64 compat_loff_t;
40.30 +typedef u16 compat_nlink_t;
40.31 +typedef u16 compat_ipc_pid_t;
40.32 +typedef s32 compat_daddr_t;
40.33 +typedef u32 compat_caddr_t;
40.34 +typedef __kernel_fsid_t compat_fsid_t;
40.35 +typedef s32 compat_timer_t;
40.36 +typedef s32 compat_key_t;
40.37 +
40.38 +typedef s32 compat_int_t;
40.39 +typedef s32 compat_long_t;
40.40 +typedef s64 __attribute__((aligned(4))) compat_s64;
40.41 +typedef u32 compat_uint_t;
40.42 +typedef u32 compat_ulong_t;
40.43 +typedef u64 __attribute__((aligned(4))) compat_u64;
40.44 +
40.45 +struct compat_timespec {
40.46 + compat_time_t tv_sec;
40.47 + s32 tv_nsec;
40.48 +};
40.49 +
40.50 +struct compat_timeval {
40.51 + compat_time_t tv_sec;
40.52 + s32 tv_usec;
40.53 +};
40.54 +
40.55 +struct compat_stat {
40.56 + compat_dev_t st_dev;
40.57 + u16 __pad1;
40.58 + compat_ino_t st_ino;
40.59 + compat_mode_t st_mode;
40.60 + compat_nlink_t st_nlink;
40.61 + __compat_uid_t st_uid;
40.62 + __compat_gid_t st_gid;
40.63 + compat_dev_t st_rdev;
40.64 + u16 __pad2;
40.65 + u32 st_size;
40.66 + u32 st_blksize;
40.67 + u32 st_blocks;
40.68 + u32 st_atime;
40.69 + u32 st_atime_nsec;
40.70 + u32 st_mtime;
40.71 + u32 st_mtime_nsec;
40.72 + u32 st_ctime;
40.73 + u32 st_ctime_nsec;
40.74 + u32 __unused4;
40.75 + u32 __unused5;
40.76 +};
40.77 +
40.78 +struct compat_flock {
40.79 + short l_type;
40.80 + short l_whence;
40.81 + compat_off_t l_start;
40.82 + compat_off_t l_len;
40.83 + compat_pid_t l_pid;
40.84 +};
40.85 +
40.86 +#define F_GETLK64 12 /* using 'struct flock64' */
40.87 +#define F_SETLK64 13
40.88 +#define F_SETLKW64 14
40.89 +
40.90 +/*
40.91 + * IA32 uses 4 byte alignment for 64 bit quantities,
40.92 + * so we need to pack this structure.
40.93 + */
40.94 +struct compat_flock64 {
40.95 + short l_type;
40.96 + short l_whence;
40.97 + compat_loff_t l_start;
40.98 + compat_loff_t l_len;
40.99 + compat_pid_t l_pid;
40.100 +} __attribute__((packed));
40.101 +
40.102 +struct compat_statfs {
40.103 + int f_type;
40.104 + int f_bsize;
40.105 + int f_blocks;
40.106 + int f_bfree;
40.107 + int f_bavail;
40.108 + int f_files;
40.109 + int f_ffree;
40.110 + compat_fsid_t f_fsid;
40.111 + int f_namelen; /* SunOS ignores this field. */
40.112 + int f_frsize;
40.113 + int f_spare[5];
40.114 +};
40.115 +
40.116 +#define COMPAT_RLIM_OLD_INFINITY 0x7fffffff
40.117 +#define COMPAT_RLIM_INFINITY 0xffffffff
40.118 +
40.119 +typedef u32 compat_old_sigset_t; /* at least 32 bits */
40.120 +
40.121 +#define _COMPAT_NSIG 64
40.122 +#define _COMPAT_NSIG_BPW 32
40.123 +
40.124 +typedef u32 compat_sigset_word;
40.125 +
40.126 +#define COMPAT_OFF_T_MAX 0x7fffffff
40.127 +#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
40.128 +
40.129 +struct compat_ipc64_perm {
40.130 + compat_key_t key;
40.131 + __compat_uid32_t uid;
40.132 + __compat_gid32_t gid;
40.133 + __compat_uid32_t cuid;
40.134 + __compat_gid32_t cgid;
40.135 + unsigned short mode;
40.136 + unsigned short __pad1;
40.137 + unsigned short seq;
40.138 + unsigned short __pad2;
40.139 + compat_ulong_t unused1;
40.140 + compat_ulong_t unused2;
40.141 +};
40.142 +
40.143 +struct compat_semid64_ds {
40.144 + struct compat_ipc64_perm sem_perm;
40.145 + compat_time_t sem_otime;
40.146 + compat_ulong_t __unused1;
40.147 + compat_time_t sem_ctime;
40.148 + compat_ulong_t __unused2;
40.149 + compat_ulong_t sem_nsems;
40.150 + compat_ulong_t __unused3;
40.151 + compat_ulong_t __unused4;
40.152 +};
40.153 +
40.154 +struct compat_msqid64_ds {
40.155 + struct compat_ipc64_perm msg_perm;
40.156 + compat_time_t msg_stime;
40.157 + compat_ulong_t __unused1;
40.158 + compat_time_t msg_rtime;
40.159 + compat_ulong_t __unused2;
40.160 + compat_time_t msg_ctime;
40.161 + compat_ulong_t __unused3;
40.162 + compat_ulong_t msg_cbytes;
40.163 + compat_ulong_t msg_qnum;
40.164 + compat_ulong_t msg_qbytes;
40.165 + compat_pid_t msg_lspid;
40.166 + compat_pid_t msg_lrpid;
40.167 + compat_ulong_t __unused4;
40.168 + compat_ulong_t __unused5;
40.169 +};
40.170 +
40.171 +struct compat_shmid64_ds {
40.172 + struct compat_ipc64_perm shm_perm;
40.173 + compat_size_t shm_segsz;
40.174 + compat_time_t shm_atime;
40.175 + compat_ulong_t __unused1;
40.176 + compat_time_t shm_dtime;
40.177 + compat_ulong_t __unused2;
40.178 + compat_time_t shm_ctime;
40.179 + compat_ulong_t __unused3;
40.180 + compat_pid_t shm_cpid;
40.181 + compat_pid_t shm_lpid;
40.182 + compat_ulong_t shm_nattch;
40.183 + compat_ulong_t __unused4;
40.184 + compat_ulong_t __unused5;
40.185 +};
40.186 +
40.187 +/*
40.188 + * The type of struct elf_prstatus.pr_reg in compatible core dumps.
40.189 + */
40.190 +typedef struct user_regs_struct32 compat_elf_gregset_t;
40.191 +
40.192 +/*
40.193 + * A pointer passed in from user mode. This should not
40.194 + * be used for syscall parameters, just declare them
40.195 + * as pointers because the syscall entry code will have
40.196 + * appropriately converted them already.
40.197 + */
40.198 +typedef u32 compat_uptr_t;
40.199 +
40.200 +static inline void __user *compat_ptr(compat_uptr_t uptr)
40.201 +{
40.202 + return (void __user *)(unsigned long)uptr;
40.203 +}
40.204 +
40.205 +static inline compat_uptr_t ptr_to_compat(void __user *uptr)
40.206 +{
40.207 + return (u32)(unsigned long)uptr;
40.208 +}
40.209 +
40.210 +static inline void __user *compat_alloc_user_space(long len)
40.211 +{
40.212 + struct pt_regs *regs = task_pt_regs(current);
40.213 + return (void __user *)regs->sp - len;
40.214 +}
40.215 +
40.216 +static inline int is_compat_task(void)
40.217 +{
40.218 + return current_thread_info()->status & TS_COMPAT;
40.219 +}
40.220 +
40.221 +#endif /* _ASM_X86_COMPAT_H */
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/arch/x86/include/asm/cpu.h Sun Jan 11 20:20:11 2009 +0100
41.3 @@ -0,0 +1,20 @@
41.4 +#ifndef _ASM_X86_CPU_H
41.5 +#define _ASM_X86_CPU_H
41.6 +
41.7 +#include <linux/device.h>
41.8 +#include <linux/cpu.h>
41.9 +#include <linux/topology.h>
41.10 +#include <linux/nodemask.h>
41.11 +#include <linux/percpu.h>
41.12 +
41.13 +struct x86_cpu {
41.14 + struct cpu cpu;
41.15 +};
41.16 +
41.17 +#ifdef CONFIG_HOTPLUG_CPU
41.18 +extern int arch_register_cpu(int num);
41.19 +extern void arch_unregister_cpu(int);
41.20 +#endif
41.21 +
41.22 +DECLARE_PER_CPU(int, cpu_state);
41.23 +#endif /* _ASM_X86_CPU_H */
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/arch/x86/include/asm/cpufeature.h Sun Jan 11 20:20:11 2009 +0100
42.3 @@ -0,0 +1,271 @@
42.4 +/*
42.5 + * Defines x86 CPU feature bits
42.6 + */
42.7 +#ifndef _ASM_X86_CPUFEATURE_H
42.8 +#define _ASM_X86_CPUFEATURE_H
42.9 +
42.10 +#include <asm/required-features.h>
42.11 +
42.12 +#define NCAPINTS 9 /* N 32-bit words worth of info */
42.13 +
42.14 +/*
42.15 + * Note: If the comment begins with a quoted string, that string is used
42.16 + * in /proc/cpuinfo instead of the macro name. If the string is "",
42.17 + * this feature bit is not displayed in /proc/cpuinfo at all.
42.18 + */
42.19 +
42.20 +/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
42.21 +#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */
42.22 +#define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */
42.23 +#define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */
42.24 +#define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */
42.25 +#define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */
42.26 +#define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers */
42.27 +#define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */
42.28 +#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */
42.29 +#define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */
42.30 +#define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */
42.31 +#define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */
42.32 +#define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */
42.33 +#define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */
42.34 +#define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */
42.35 +#define X86_FEATURE_CMOV (0*32+15) /* CMOV instructions */
42.36 + /* (plus FCMOVcc, FCOMI with FPU) */
42.37 +#define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */
42.38 +#define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */
42.39 +#define X86_FEATURE_PN (0*32+18) /* Processor serial number */
42.40 +#define X86_FEATURE_CLFLSH (0*32+19) /* "clflush" CLFLUSH instruction */
42.41 +#define X86_FEATURE_DS (0*32+21) /* "dts" Debug Store */
42.42 +#define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */
42.43 +#define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */
42.44 +#define X86_FEATURE_FXSR (0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */
42.45 +#define X86_FEATURE_XMM (0*32+25) /* "sse" */
42.46 +#define X86_FEATURE_XMM2 (0*32+26) /* "sse2" */
42.47 +#define X86_FEATURE_SELFSNOOP (0*32+27) /* "ss" CPU self snoop */
42.48 +#define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */
42.49 +#define X86_FEATURE_ACC (0*32+29) /* "tm" Automatic clock control */
42.50 +#define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */
42.51 +#define X86_FEATURE_PBE (0*32+31) /* Pending Break Enable */
42.52 +
42.53 +/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
42.54 +/* Don't duplicate feature flags which are redundant with Intel! */
42.55 +#define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */
42.56 +#define X86_FEATURE_MP (1*32+19) /* MP Capable. */
42.57 +#define X86_FEATURE_NX (1*32+20) /* Execute Disable */
42.58 +#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */
42.59 +#define X86_FEATURE_FXSR_OPT (1*32+25) /* FXSAVE/FXRSTOR optimizations */
42.60 +#define X86_FEATURE_GBPAGES (1*32+26) /* "pdpe1gb" GB pages */
42.61 +#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */
42.62 +#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */
42.63 +#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */
42.64 +#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */
42.65 +
42.66 +/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
42.67 +#define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */
42.68 +#define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */
42.69 +#define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */
42.70 +
42.71 +/* Other features, Linux-defined mapping, word 3 */
42.72 +/* This range is used for feature bits which conflict or are synthesized */
42.73 +#define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */
42.74 +#define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */
42.75 +#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
42.76 +#define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */
42.77 +/* cpu types for specific tunings: */
42.78 +#define X86_FEATURE_K8 (3*32+ 4) /* "" Opteron, Athlon64 */
42.79 +#define X86_FEATURE_K7 (3*32+ 5) /* "" Athlon */
42.80 +#define X86_FEATURE_P3 (3*32+ 6) /* "" P3 */
42.81 +#define X86_FEATURE_P4 (3*32+ 7) /* "" P4 */
42.82 +#define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
42.83 +#define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */
42.84 +#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* "" FXSAVE leaks FOP/FIP/FOP */
42.85 +#define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */
42.86 +#define X86_FEATURE_NOPL (3*32+20) /* The NOPL (0F 1F) instructions */
42.87 +#define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */
42.88 +#define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */
42.89 +#define X86_FEATURE_SYSCALL32 (3*32+14) /* "" syscall in ia32 userspace */
42.90 +#define X86_FEATURE_SYSENTER32 (3*32+15) /* "" sysenter in ia32 userspace */
42.91 +#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well */
42.92 +#define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* "" Mfence synchronizes RDTSC */
42.93 +#define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* "" Lfence synchronizes RDTSC */
42.94 +#define X86_FEATURE_11AP (3*32+19) /* "" Bad local APIC aka 11AP */
42.95 +#define X86_FEATURE_NOPL (3*32+20) /* The NOPL (0F 1F) instructions */
42.96 +#define X86_FEATURE_AMDC1E (3*32+21) /* AMD C1E detected */
42.97 +#define X86_FEATURE_XTOPOLOGY (3*32+22) /* cpu topology enum extensions */
42.98 +
42.99 +/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
42.100 +#define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */
42.101 +#define X86_FEATURE_PCLMULQDQ (4*32+ 1) /* PCLMULQDQ instruction */
42.102 +#define X86_FEATURE_DTES64 (4*32+ 2) /* 64-bit Debug Store */
42.103 +#define X86_FEATURE_MWAIT (4*32+ 3) /* "monitor" Monitor/Mwait support */
42.104 +#define X86_FEATURE_DSCPL (4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */
42.105 +#define X86_FEATURE_VMX (4*32+ 5) /* Hardware virtualization */
42.106 +#define X86_FEATURE_SMX (4*32+ 6) /* Safer mode */
42.107 +#define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */
42.108 +#define X86_FEATURE_TM2 (4*32+ 8) /* Thermal Monitor 2 */
42.109 +#define X86_FEATURE_SSSE3 (4*32+ 9) /* Supplemental SSE-3 */
42.110 +#define X86_FEATURE_CID (4*32+10) /* Context ID */
42.111 +#define X86_FEATURE_FMA (4*32+12) /* Fused multiply-add */
42.112 +#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */
42.113 +#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */
42.114 +#define X86_FEATURE_PDCM (4*32+15) /* Performance Capabilities */
42.115 +#define X86_FEATURE_DCA (4*32+18) /* Direct Cache Access */
42.116 +#define X86_FEATURE_XMM4_1 (4*32+19) /* "sse4_1" SSE-4.1 */
42.117 +#define X86_FEATURE_XMM4_2 (4*32+20) /* "sse4_2" SSE-4.2 */
42.118 +#define X86_FEATURE_X2APIC (4*32+21) /* x2APIC */
42.119 +#define X86_FEATURE_AES (4*32+25) /* AES instructions */
42.120 +#define X86_FEATURE_XSAVE (4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
42.121 +#define X86_FEATURE_OSXSAVE (4*32+27) /* "" XSAVE enabled in the OS */
42.122 +#define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */
42.123 +
42.124 +/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
42.125 +#define X86_FEATURE_XSTORE (5*32+ 2) /* "rng" RNG present (xstore) */
42.126 +#define X86_FEATURE_XSTORE_EN (5*32+ 3) /* "rng_en" RNG enabled */
42.127 +#define X86_FEATURE_XCRYPT (5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */
42.128 +#define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* "ace_en" on-CPU crypto enabled */
42.129 +#define X86_FEATURE_ACE2 (5*32+ 8) /* Advanced Cryptography Engine v2 */
42.130 +#define X86_FEATURE_ACE2_EN (5*32+ 9) /* ACE v2 enabled */
42.131 +#define X86_FEATURE_PHE (5*32+10) /* PadLock Hash Engine */
42.132 +#define X86_FEATURE_PHE_EN (5*32+11) /* PHE enabled */
42.133 +#define X86_FEATURE_PMM (5*32+12) /* PadLock Montgomery Multiplier */
42.134 +#define X86_FEATURE_PMM_EN (5*32+13) /* PMM enabled */
42.135 +
42.136 +/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
42.137 +#define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */
42.138 +#define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
42.139 +#define X86_FEATURE_SVM (6*32+ 2) /* Secure virtual machine */
42.140 +#define X86_FEATURE_EXTAPIC (6*32+ 3) /* Extended APIC space */
42.141 +#define X86_FEATURE_CR8_LEGACY (6*32+ 4) /* CR8 in 32-bit mode */
42.142 +#define X86_FEATURE_ABM (6*32+ 5) /* Advanced bit manipulation */
42.143 +#define X86_FEATURE_SSE4A (6*32+ 6) /* SSE-4A */
42.144 +#define X86_FEATURE_MISALIGNSSE (6*32+ 7) /* Misaligned SSE mode */
42.145 +#define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */
42.146 +#define X86_FEATURE_OSVW (6*32+ 9) /* OS Visible Workaround */
42.147 +#define X86_FEATURE_IBS (6*32+10) /* Instruction Based Sampling */
42.148 +#define X86_FEATURE_SSE5 (6*32+11) /* SSE-5 */
42.149 +#define X86_FEATURE_SKINIT (6*32+12) /* SKINIT/STGI instructions */
42.150 +#define X86_FEATURE_WDT (6*32+13) /* Watchdog timer */
42.151 +
42.152 +/*
42.153 + * Auxiliary flags: Linux defined - For features scattered in various
42.154 + * CPUID levels like 0x6, 0xA etc
42.155 + */
42.156 +#define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */
42.157 +
42.158 +/* Virtualization flags: Linux defined */
42.159 +#define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */
42.160 +#define X86_FEATURE_VNMI (8*32+ 1) /* Intel Virtual NMI */
42.161 +#define X86_FEATURE_FLEXPRIORITY (8*32+ 2) /* Intel FlexPriority */
42.162 +#define X86_FEATURE_EPT (8*32+ 3) /* Intel Extended Page Table */
42.163 +#define X86_FEATURE_VPID (8*32+ 4) /* Intel Virtual Processor ID */
42.164 +
42.165 +#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
42.166 +
42.167 +#include <linux/bitops.h>
42.168 +
42.169 +extern const char * const x86_cap_flags[NCAPINTS*32];
42.170 +extern const char * const x86_power_flags[32];
42.171 +
42.172 +#define test_cpu_cap(c, bit) \
42.173 + test_bit(bit, (unsigned long *)((c)->x86_capability))
42.174 +
42.175 +#define cpu_has(c, bit) \
42.176 + (__builtin_constant_p(bit) && \
42.177 + ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) || \
42.178 + (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) || \
42.179 + (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) || \
42.180 + (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) || \
42.181 + (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) || \
42.182 + (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) || \
42.183 + (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \
42.184 + (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ) \
42.185 + ? 1 : \
42.186 + test_cpu_cap(c, bit))
42.187 +
42.188 +#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
42.189 +
42.190 +#define set_cpu_cap(c, bit) set_bit(bit, (unsigned long *)((c)->x86_capability))
42.191 +#define clear_cpu_cap(c, bit) clear_bit(bit, (unsigned long *)((c)->x86_capability))
42.192 +#define setup_clear_cpu_cap(bit) do { \
42.193 + clear_cpu_cap(&boot_cpu_data, bit); \
42.194 + set_bit(bit, (unsigned long *)cleared_cpu_caps); \
42.195 +} while (0)
42.196 +#define setup_force_cpu_cap(bit) do { \
42.197 + set_cpu_cap(&boot_cpu_data, bit); \
42.198 + clear_bit(bit, (unsigned long *)cleared_cpu_caps); \
42.199 +} while (0)
42.200 +
42.201 +#define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU)
42.202 +#define cpu_has_vme boot_cpu_has(X86_FEATURE_VME)
42.203 +#define cpu_has_de boot_cpu_has(X86_FEATURE_DE)
42.204 +#define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE)
42.205 +#define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC)
42.206 +#define cpu_has_pae boot_cpu_has(X86_FEATURE_PAE)
42.207 +#define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE)
42.208 +#define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC)
42.209 +#define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP)
42.210 +#define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR)
42.211 +#define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX)
42.212 +#define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR)
42.213 +#define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM)
42.214 +#define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2)
42.215 +#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3)
42.216 +#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
42.217 +#define cpu_has_mp boot_cpu_has(X86_FEATURE_MP)
42.218 +#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX)
42.219 +#define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR)
42.220 +#define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR)
42.221 +#define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR)
42.222 +#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE)
42.223 +#define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN)
42.224 +#define cpu_has_xcrypt boot_cpu_has(X86_FEATURE_XCRYPT)
42.225 +#define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN)
42.226 +#define cpu_has_ace2 boot_cpu_has(X86_FEATURE_ACE2)
42.227 +#define cpu_has_ace2_enabled boot_cpu_has(X86_FEATURE_ACE2_EN)
42.228 +#define cpu_has_phe boot_cpu_has(X86_FEATURE_PHE)
42.229 +#define cpu_has_phe_enabled boot_cpu_has(X86_FEATURE_PHE_EN)
42.230 +#define cpu_has_pmm boot_cpu_has(X86_FEATURE_PMM)
42.231 +#define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN)
42.232 +#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS)
42.233 +#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS)
42.234 +#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH)
42.235 +#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS)
42.236 +#define cpu_has_gbpages boot_cpu_has(X86_FEATURE_GBPAGES)
42.237 +#define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
42.238 +#define cpu_has_pat boot_cpu_has(X86_FEATURE_PAT)
42.239 +#define cpu_has_xmm4_1 boot_cpu_has(X86_FEATURE_XMM4_1)
42.240 +#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2)
42.241 +#define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC)
42.242 +#define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE)
42.243 +
42.244 +#if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
42.245 +# define cpu_has_invlpg 1
42.246 +#else
42.247 +# define cpu_has_invlpg (boot_cpu_data.x86 > 3)
42.248 +#endif
42.249 +
42.250 +#ifdef CONFIG_X86_64
42.251 +
42.252 +#undef cpu_has_vme
42.253 +#define cpu_has_vme 0
42.254 +
42.255 +#undef cpu_has_pae
42.256 +#define cpu_has_pae ___BUG___
42.257 +
42.258 +#undef cpu_has_mp
42.259 +#define cpu_has_mp 1
42.260 +
42.261 +#undef cpu_has_k6_mtrr
42.262 +#define cpu_has_k6_mtrr 0
42.263 +
42.264 +#undef cpu_has_cyrix_arr
42.265 +#define cpu_has_cyrix_arr 0
42.266 +
42.267 +#undef cpu_has_centaur_mcr
42.268 +#define cpu_has_centaur_mcr 0
42.269 +
42.270 +#endif /* CONFIG_X86_64 */
42.271 +
42.272 +#endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
42.273 +
42.274 +#endif /* _ASM_X86_CPUFEATURE_H */
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/arch/x86/include/asm/cputime.h Sun Jan 11 20:20:11 2009 +0100
43.3 @@ -0,0 +1,1 @@
43.4 +#include <asm-generic/cputime.h>
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/arch/x86/include/asm/current.h Sun Jan 11 20:20:11 2009 +0100
44.3 @@ -0,0 +1,39 @@
44.4 +#ifndef _ASM_X86_CURRENT_H
44.5 +#define _ASM_X86_CURRENT_H
44.6 +
44.7 +#ifdef CONFIG_X86_32
44.8 +#include <linux/compiler.h>
44.9 +#include <asm/percpu.h>
44.10 +
44.11 +struct task_struct;
44.12 +
44.13 +DECLARE_PER_CPU(struct task_struct *, current_task);
44.14 +static __always_inline struct task_struct *get_current(void)
44.15 +{
44.16 + return x86_read_percpu(current_task);
44.17 +}
44.18 +
44.19 +#else /* X86_32 */
44.20 +
44.21 +#ifndef __ASSEMBLY__
44.22 +#include <asm/pda.h>
44.23 +
44.24 +struct task_struct;
44.25 +
44.26 +static __always_inline struct task_struct *get_current(void)
44.27 +{
44.28 + return read_pda(pcurrent);
44.29 +}
44.30 +
44.31 +#else /* __ASSEMBLY__ */
44.32 +
44.33 +#include <asm/asm-offsets.h>
44.34 +#define GET_CURRENT(reg) movq %gs:(pda_pcurrent),reg
44.35 +
44.36 +#endif /* __ASSEMBLY__ */
44.37 +
44.38 +#endif /* X86_32 */
44.39 +
44.40 +#define current get_current()
44.41 +
44.42 +#endif /* _ASM_X86_CURRENT_H */
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/arch/x86/include/asm/debugreg.h Sun Jan 11 20:20:11 2009 +0100
45.3 @@ -0,0 +1,70 @@
45.4 +#ifndef _ASM_X86_DEBUGREG_H
45.5 +#define _ASM_X86_DEBUGREG_H
45.6 +
45.7 +
45.8 +/* Indicate the register numbers for a number of the specific
45.9 + debug registers. Registers 0-3 contain the addresses we wish to trap on */
45.10 +#define DR_FIRSTADDR 0 /* u_debugreg[DR_FIRSTADDR] */
45.11 +#define DR_LASTADDR 3 /* u_debugreg[DR_LASTADDR] */
45.12 +
45.13 +#define DR_STATUS 6 /* u_debugreg[DR_STATUS] */
45.14 +#define DR_CONTROL 7 /* u_debugreg[DR_CONTROL] */
45.15 +
45.16 +/* Define a few things for the status register. We can use this to determine
45.17 + which debugging register was responsible for the trap. The other bits
45.18 + are either reserved or not of interest to us. */
45.19 +
45.20 +#define DR_TRAP0 (0x1) /* db0 */
45.21 +#define DR_TRAP1 (0x2) /* db1 */
45.22 +#define DR_TRAP2 (0x4) /* db2 */
45.23 +#define DR_TRAP3 (0x8) /* db3 */
45.24 +
45.25 +#define DR_STEP (0x4000) /* single-step */
45.26 +#define DR_SWITCH (0x8000) /* task switch */
45.27 +
45.28 +/* Now define a bunch of things for manipulating the control register.
45.29 + The top two bytes of the control register consist of 4 fields of 4
45.30 + bits - each field corresponds to one of the four debug registers,
45.31 + and indicates what types of access we trap on, and how large the data
45.32 + field is that we are looking at */
45.33 +
45.34 +#define DR_CONTROL_SHIFT 16 /* Skip this many bits in ctl register */
45.35 +#define DR_CONTROL_SIZE 4 /* 4 control bits per register */
45.36 +
45.37 +#define DR_RW_EXECUTE (0x0) /* Settings for the access types to trap on */
45.38 +#define DR_RW_WRITE (0x1)
45.39 +#define DR_RW_READ (0x3)
45.40 +
45.41 +#define DR_LEN_1 (0x0) /* Settings for data length to trap on */
45.42 +#define DR_LEN_2 (0x4)
45.43 +#define DR_LEN_4 (0xC)
45.44 +#define DR_LEN_8 (0x8)
45.45 +
45.46 +/* The low byte to the control register determine which registers are
45.47 + enabled. There are 4 fields of two bits. One bit is "local", meaning
45.48 + that the processor will reset the bit after a task switch and the other
45.49 + is global meaning that we have to explicitly reset the bit. With linux,
45.50 + you can use either one, since we explicitly zero the register when we enter
45.51 + kernel mode. */
45.52 +
45.53 +#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit */
45.54 +#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit */
45.55 +#define DR_ENABLE_SIZE 2 /* 2 enable bits per register */
45.56 +
45.57 +#define DR_LOCAL_ENABLE_MASK (0x55) /* Set local bits for all 4 regs */
45.58 +#define DR_GLOBAL_ENABLE_MASK (0xAA) /* Set global bits for all 4 regs */
45.59 +
45.60 +/* The second byte to the control register has a few special things.
45.61 + We can slow the instruction pipeline for instructions coming via the
45.62 + gdt or the ldt if we want to. I am not sure why this is an advantage */
45.63 +
45.64 +#ifdef __i386__
45.65 +#define DR_CONTROL_RESERVED (0xFC00) /* Reserved by Intel */
45.66 +#else
45.67 +#define DR_CONTROL_RESERVED (0xFFFFFFFF0000FC00UL) /* Reserved */
45.68 +#endif
45.69 +
45.70 +#define DR_LOCAL_SLOWDOWN (0x100) /* Local slow the pipeline */
45.71 +#define DR_GLOBAL_SLOWDOWN (0x200) /* Global slow the pipeline */
45.72 +
45.73 +#endif /* _ASM_X86_DEBUGREG_H */
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
46.2 +++ b/arch/x86/include/asm/delay.h Sun Jan 11 20:20:11 2009 +0100
46.3 @@ -0,0 +1,31 @@
46.4 +#ifndef _ASM_X86_DELAY_H
46.5 +#define _ASM_X86_DELAY_H
46.6 +
46.7 +/*
46.8 + * Copyright (C) 1993 Linus Torvalds
46.9 + *
46.10 + * Delay routines calling functions in arch/x86/lib/delay.c
46.11 + */
46.12 +
46.13 +/* Undefined functions to get compile-time errors */
46.14 +extern void __bad_udelay(void);
46.15 +extern void __bad_ndelay(void);
46.16 +
46.17 +extern void __udelay(unsigned long usecs);
46.18 +extern void __ndelay(unsigned long nsecs);
46.19 +extern void __const_udelay(unsigned long xloops);
46.20 +extern void __delay(unsigned long loops);
46.21 +
46.22 +/* 0x10c7 is 2**32 / 1000000 (rounded up) */
46.23 +#define udelay(n) (__builtin_constant_p(n) ? \
46.24 + ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
46.25 + __udelay(n))
46.26 +
46.27 +/* 0x5 is 2**32 / 1000000000 (rounded up) */
46.28 +#define ndelay(n) (__builtin_constant_p(n) ? \
46.29 + ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
46.30 + __ndelay(n))
46.31 +
46.32 +void use_tsc_delay(void);
46.33 +
46.34 +#endif /* _ASM_X86_DELAY_H */
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
47.2 +++ b/arch/x86/include/asm/desc.h Sun Jan 11 20:20:11 2009 +0100
47.3 @@ -0,0 +1,409 @@
47.4 +#ifndef _ASM_X86_DESC_H
47.5 +#define _ASM_X86_DESC_H
47.6 +
47.7 +#ifndef __ASSEMBLY__
47.8 +#include <asm/desc_defs.h>
47.9 +#include <asm/ldt.h>
47.10 +#include <asm/mmu.h>
47.11 +#include <linux/smp.h>
47.12 +
47.13 +static inline void fill_ldt(struct desc_struct *desc,
47.14 + const struct user_desc *info)
47.15 +{
47.16 + desc->limit0 = info->limit & 0x0ffff;
47.17 + desc->base0 = info->base_addr & 0x0000ffff;
47.18 +
47.19 + desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
47.20 + desc->type = (info->read_exec_only ^ 1) << 1;
47.21 + desc->type |= info->contents << 2;
47.22 + desc->s = 1;
47.23 + desc->dpl = 0x3;
47.24 + desc->p = info->seg_not_present ^ 1;
47.25 + desc->limit = (info->limit & 0xf0000) >> 16;
47.26 + desc->avl = info->useable;
47.27 + desc->d = info->seg_32bit;
47.28 + desc->g = info->limit_in_pages;
47.29 + desc->base2 = (info->base_addr & 0xff000000) >> 24;
47.30 + /*
47.31 + * Don't allow setting of the lm bit. It is useless anyway
47.32 + * because 64bit system calls require __USER_CS:
47.33 + */
47.34 + desc->l = 0;
47.35 +}
47.36 +
47.37 +extern struct desc_ptr idt_descr;
47.38 +extern gate_desc idt_table[];
47.39 +
47.40 +struct gdt_page {
47.41 + struct desc_struct gdt[GDT_ENTRIES];
47.42 +} __attribute__((aligned(PAGE_SIZE)));
47.43 +DECLARE_PER_CPU(struct gdt_page, gdt_page);
47.44 +
47.45 +static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
47.46 +{
47.47 + return per_cpu(gdt_page, cpu).gdt;
47.48 +}
47.49 +
47.50 +#ifdef CONFIG_X86_64
47.51 +
47.52 +static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
47.53 + unsigned dpl, unsigned ist, unsigned seg)
47.54 +{
47.55 + gate->offset_low = PTR_LOW(func);
47.56 + gate->segment = __KERNEL_CS;
47.57 + gate->ist = ist;
47.58 + gate->p = 1;
47.59 + gate->dpl = dpl;
47.60 + gate->zero0 = 0;
47.61 + gate->zero1 = 0;
47.62 + gate->type = type;
47.63 + gate->offset_middle = PTR_MIDDLE(func);
47.64 + gate->offset_high = PTR_HIGH(func);
47.65 +}
47.66 +
47.67 +#else
47.68 +static inline void pack_gate(gate_desc *gate, unsigned char type,
47.69 + unsigned long base, unsigned dpl, unsigned flags,
47.70 + unsigned short seg)
47.71 +{
47.72 + gate->a = (seg << 16) | (base & 0xffff);
47.73 + gate->b = (base & 0xffff0000) |
47.74 + (((0x80 | type | (dpl << 5)) & 0xff) << 8);
47.75 +}
47.76 +
47.77 +#endif
47.78 +
47.79 +static inline int desc_empty(const void *ptr)
47.80 +{
47.81 + const u32 *desc = ptr;
47.82 + return !(desc[0] | desc[1]);
47.83 +}
47.84 +
47.85 +#ifdef CONFIG_PARAVIRT
47.86 +#include <asm/paravirt.h>
47.87 +#else
47.88 +#define load_TR_desc() native_load_tr_desc()
47.89 +#define load_gdt(dtr) native_load_gdt(dtr)
47.90 +#define load_idt(dtr) native_load_idt(dtr)
47.91 +#define load_tr(tr) asm volatile("ltr %0"::"m" (tr))
47.92 +#define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt))
47.93 +
47.94 +#define store_gdt(dtr) native_store_gdt(dtr)
47.95 +#define store_idt(dtr) native_store_idt(dtr)
47.96 +#define store_tr(tr) (tr = native_store_tr())
47.97 +#define store_ldt(ldt) asm("sldt %0":"=m" (ldt))
47.98 +
47.99 +#define load_TLS(t, cpu) native_load_tls(t, cpu)
47.100 +#define set_ldt native_set_ldt
47.101 +
47.102 +#define write_ldt_entry(dt, entry, desc) \
47.103 + native_write_ldt_entry(dt, entry, desc)
47.104 +#define write_gdt_entry(dt, entry, desc, type) \
47.105 + native_write_gdt_entry(dt, entry, desc, type)
47.106 +#define write_idt_entry(dt, entry, g) \
47.107 + native_write_idt_entry(dt, entry, g)
47.108 +
47.109 +static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries)
47.110 +{
47.111 +}
47.112 +
47.113 +static inline void paravirt_free_ldt(struct desc_struct *ldt, unsigned entries)
47.114 +{
47.115 +}
47.116 +#endif /* CONFIG_PARAVIRT */
47.117 +
47.118 +static inline void native_write_idt_entry(gate_desc *idt, int entry,
47.119 + const gate_desc *gate)
47.120 +{
47.121 + memcpy(&idt[entry], gate, sizeof(*gate));
47.122 +}
47.123 +
47.124 +static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
47.125 + const void *desc)
47.126 +{
47.127 + memcpy(&ldt[entry], desc, 8);
47.128 +}
47.129 +
47.130 +static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
47.131 + const void *desc, int type)
47.132 +{
47.133 + unsigned int size;
47.134 + switch (type) {
47.135 + case DESC_TSS:
47.136 + size = sizeof(tss_desc);
47.137 + break;
47.138 + case DESC_LDT:
47.139 + size = sizeof(ldt_desc);
47.140 + break;
47.141 + default:
47.142 + size = sizeof(struct desc_struct);
47.143 + break;
47.144 + }
47.145 + memcpy(&gdt[entry], desc, size);
47.146 +}
47.147 +
47.148 +static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
47.149 + unsigned long limit, unsigned char type,
47.150 + unsigned char flags)
47.151 +{
47.152 + desc->a = ((base & 0xffff) << 16) | (limit &