Merge branch 'x86/apic' into perfcounters/core
Conflicts: arch/x86/kernel/cpu/perfctr-watchdog.c
This commit is contained in:
Коммит
0b6de00922
|
@ -137,7 +137,7 @@ static void cn_test_timer_func(unsigned long __data)
|
||||||
|
|
||||||
memcpy(m + 1, data, m->len);
|
memcpy(m + 1, data, m->len);
|
||||||
|
|
||||||
cn_netlink_send(m, 0, gfp_any());
|
cn_netlink_send(m, 0, GFP_ATOMIC);
|
||||||
kfree(m);
|
kfree(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,10 +160,8 @@ static int cn_test_init(void)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_timer(&cn_test_timer);
|
setup_timer(&cn_test_timer, cn_test_timer_func, 0);
|
||||||
cn_test_timer.function = cn_test_timer_func;
|
|
||||||
cn_test_timer.expires = jiffies + HZ;
|
cn_test_timer.expires = jiffies + HZ;
|
||||||
cn_test_timer.data = 0;
|
|
||||||
add_timer(&cn_test_timer);
|
add_timer(&cn_test_timer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
PATCHLEVEL = 6
|
PATCHLEVEL = 6
|
||||||
SUBLEVEL = 29
|
SUBLEVEL = 29
|
||||||
EXTRAVERSION = -rc4
|
EXTRAVERSION = -rc5
|
||||||
NAME = Erotic Pickled Herring
|
NAME = Erotic Pickled Herring
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef _ALPHA_STATFS_H
|
#ifndef _ALPHA_STATFS_H
|
||||||
#define _ALPHA_STATFS_H
|
#define _ALPHA_STATFS_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
/* Alpha is the only 64-bit platform with 32-bit statfs. And doesn't
|
/* Alpha is the only 64-bit platform with 32-bit statfs. And doesn't
|
||||||
even seem to implement statfs64 */
|
even seem to implement statfs64 */
|
||||||
#define __statfs_word __u32
|
#define __statfs_word __u32
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef _ALPHA_SWAB_H
|
#ifndef _ALPHA_SWAB_H
|
||||||
#define _ALPHA_SWAB_H
|
#define _ALPHA_SWAB_H
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <asm/compiler.h>
|
#include <asm/compiler.h>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define __ARM_A_OUT_H__
|
#define __ARM_A_OUT_H__
|
||||||
|
|
||||||
#include <linux/personality.h>
|
#include <linux/personality.h>
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
struct exec
|
struct exec
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#ifndef __ASMARM_SETUP_H
|
#ifndef __ASMARM_SETUP_H
|
||||||
#define __ASMARM_SETUP_H
|
#define __ASMARM_SETUP_H
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#define COMMAND_LINE_SIZE 1024
|
#define COMMAND_LINE_SIZE 1024
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#define __ASM_ARM_SWAB_H
|
#define __ASM_ARM_SWAB_H
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
||||||
# define __SWAB_64_THRU_32__
|
# define __SWAB_64_THRU_32__
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#ifndef __ASM_AVR32_SWAB_H
|
#ifndef __ASM_AVR32_SWAB_H
|
||||||
#define __ASM_AVR32_SWAB_H
|
#define __ASM_AVR32_SWAB_H
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
#define __SWAB_64_THRU_32__
|
#define __SWAB_64_THRU_32__
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef _BLACKFIN_SWAB_H
|
#ifndef _BLACKFIN_SWAB_H
|
||||||
#define _BLACKFIN_SWAB_H
|
#define _BLACKFIN_SWAB_H
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef _H8300_SWAB_H
|
#ifndef _H8300_SWAB_H
|
||||||
#define _H8300_SWAB_H
|
#define _H8300_SWAB_H
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
|
||||||
# define __SWAB_64_THRU_32__
|
# define __SWAB_64_THRU_32__
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
* David Mosberger-Tang <davidm@hpl.hp.com>
|
* David Mosberger-Tang <davidm@hpl.hp.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm/types.h>
|
|
||||||
|
|
||||||
/* floating point status register: */
|
/* floating point status register: */
|
||||||
#define FPSR_TRAP_VD (1 << 0) /* invalid op trap disabled */
|
#define FPSR_TRAP_VD (1 << 0) /* invalid op trap disabled */
|
||||||
#define FPSR_TRAP_DD (1 << 1) /* denormal trap disabled */
|
#define FPSR_TRAP_DD (1 << 1) /* denormal trap disabled */
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
|
* Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
/* define this macro to get some asm stmts included in 'c' files */
|
/* define this macro to get some asm stmts included in 'c' files */
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
/* include compiler specific intrinsics */
|
/* include compiler specific intrinsics */
|
||||||
#include <asm/ia64regs.h>
|
#include <asm/ia64regs.h>
|
||||||
#ifdef __INTEL_COMPILER
|
#ifdef __INTEL_COMPILER
|
||||||
|
|
|
@ -21,8 +21,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
|
|
||||||
/* Architectural interrupt line count. */
|
/* Architectural interrupt line count. */
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co.
|
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
#include <asm/intrinsics.h>
|
#include <asm/intrinsics.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,7 @@ char *__init __acpi_map_table(unsigned long phys_addr, unsigned long size)
|
||||||
return __va(phys_addr);
|
return __va(phys_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *__init __acpi_unmap_table(unsigned long virt_addr, unsigned long size)
|
void __init __acpi_unmap_table(char *map, unsigned long size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#ifndef _ASM_SIGCONTEXT_H
|
#ifndef _ASM_SIGCONTEXT_H
|
||||||
#define _ASM_SIGCONTEXT_H
|
#define _ASM_SIGCONTEXT_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
#include <asm/sgidefs.h>
|
#include <asm/sgidefs.h>
|
||||||
|
|
||||||
#if _MIPS_SIM == _MIPS_SIM_ABI32
|
#if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#define _ASM_SWAB_H
|
#define _ASM_SWAB_H
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#define __SWAB_64_THRU_32__
|
#define __SWAB_64_THRU_32__
|
||||||
|
|
||||||
|
|
|
@ -336,10 +336,11 @@
|
||||||
#define NUM_PDC_RESULT 32
|
#define NUM_PDC_RESULT 32
|
||||||
|
|
||||||
#if !defined(__ASSEMBLY__)
|
#if !defined(__ASSEMBLY__)
|
||||||
#ifdef __KERNEL__
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
extern int pdc_type;
|
extern int pdc_type;
|
||||||
|
|
||||||
/* Values for pdc_type */
|
/* Values for pdc_type */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef _PARISC_SWAB_H
|
#ifndef _PARISC_SWAB_H
|
||||||
#define _PARISC_SWAB_H
|
#define _PARISC_SWAB_H
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
#define __SWAB_64_THRU_32__
|
#define __SWAB_64_THRU_32__
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#ifndef __ASM_BOOTX_H__
|
#ifndef __ASM_BOOTX_H__
|
||||||
#define __ASM_BOOTX_H__
|
#define __ASM_BOOTX_H__
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#ifdef macintosh
|
#ifdef macintosh
|
||||||
#include <Types.h>
|
#include <Types.h>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <asm/string.h>
|
#include <asm/string.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/cputable.h>
|
#include <asm/cputable.h>
|
||||||
#include <asm/auxvec.h>
|
#include <asm/auxvec.h>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef __LINUX_KVM_POWERPC_H
|
#ifndef __LINUX_KVM_POWERPC_H
|
||||||
#define __LINUX_KVM_POWERPC_H
|
#define __LINUX_KVM_POWERPC_H
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
struct kvm_regs {
|
struct kvm_regs {
|
||||||
__u64 pc;
|
__u64 pc;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#ifndef _ASM_POWERPC_PS3FB_H_
|
#ifndef _ASM_POWERPC_PS3FB_H_
|
||||||
#define _ASM_POWERPC_PS3FB_H_
|
#define _ASM_POWERPC_PS3FB_H_
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
|
|
||||||
/* ioctl */
|
/* ioctl */
|
||||||
|
|
|
@ -23,9 +23,10 @@
|
||||||
#ifndef _SPU_INFO_H
|
#ifndef _SPU_INFO_H
|
||||||
#define _SPU_INFO_H
|
#define _SPU_INFO_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#include <asm/spu.h>
|
#include <asm/spu.h>
|
||||||
#include <linux/types.h>
|
|
||||||
#else
|
#else
|
||||||
struct mfc_cq_sr {
|
struct mfc_cq_sr {
|
||||||
__u64 mfc_cq_data0_RW;
|
__u64 mfc_cq_data0_RW;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* 2 of the License, or (at your option) any later version.
|
* 2 of the License, or (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
|
@ -235,6 +235,20 @@ config SMP
|
||||||
|
|
||||||
If you don't know what to do here, say N.
|
If you don't know what to do here, say N.
|
||||||
|
|
||||||
|
config X86_X2APIC
|
||||||
|
bool "Support x2apic"
|
||||||
|
depends on X86_LOCAL_APIC && X86_64
|
||||||
|
---help---
|
||||||
|
This enables x2apic support on CPUs that have this feature.
|
||||||
|
|
||||||
|
This allows 32-bit apic IDs (so it can support very large systems),
|
||||||
|
and accesses the local apic via MSRs not via mmio.
|
||||||
|
|
||||||
|
( On certain CPU models you may need to enable INTR_REMAP too,
|
||||||
|
to get functional x2apic mode. )
|
||||||
|
|
||||||
|
If you don't know what to do here, say N.
|
||||||
|
|
||||||
config SPARSE_IRQ
|
config SPARSE_IRQ
|
||||||
bool "Support sparse irq numbering"
|
bool "Support sparse irq numbering"
|
||||||
depends on PCI_MSI || HT_IRQ
|
depends on PCI_MSI || HT_IRQ
|
||||||
|
@ -302,6 +316,7 @@ config X86_UV
|
||||||
bool "SGI Ultraviolet"
|
bool "SGI Ultraviolet"
|
||||||
depends on X86_64
|
depends on X86_64
|
||||||
depends on X86_EXTENDED_PLATFORM
|
depends on X86_EXTENDED_PLATFORM
|
||||||
|
select X86_X2APIC
|
||||||
---help---
|
---help---
|
||||||
This option is needed in order to support SGI Ultraviolet systems.
|
This option is needed in order to support SGI Ultraviolet systems.
|
||||||
If you don't have one of these, you should say N here.
|
If you don't have one of these, you should say N here.
|
||||||
|
@ -1829,6 +1844,7 @@ config DMAR_FLOPPY_WA
|
||||||
config INTR_REMAP
|
config INTR_REMAP
|
||||||
bool "Support for Interrupt Remapping (EXPERIMENTAL)"
|
bool "Support for Interrupt Remapping (EXPERIMENTAL)"
|
||||||
depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
|
depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
|
||||||
|
select X86_X2APIC
|
||||||
---help---
|
---help---
|
||||||
Supports Interrupt remapping for IO-APIC and MSI devices.
|
Supports Interrupt remapping for IO-APIC and MSI devices.
|
||||||
To use x2apic mode in the CPU's which support x2APIC enhancements or
|
To use x2apic mode in the CPU's which support x2APIC enhancements or
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
#ifndef _ASM_X86_APIC_H
|
#ifndef _ASM_X86_APIC_H
|
||||||
#define _ASM_X86_APIC_H
|
#define _ASM_X86_APIC_H
|
||||||
|
|
||||||
#include <linux/pm.h>
|
#include <linux/cpumask.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/pm.h>
|
||||||
|
|
||||||
#include <asm/alternative.h>
|
#include <asm/alternative.h>
|
||||||
#include <asm/fixmap.h>
|
|
||||||
#include <asm/apicdef.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
#include <asm/system.h>
|
|
||||||
#include <asm/cpufeature.h>
|
#include <asm/cpufeature.h>
|
||||||
|
#include <asm/processor.h>
|
||||||
|
#include <asm/apicdef.h>
|
||||||
|
#include <asm/atomic.h>
|
||||||
|
#include <asm/fixmap.h>
|
||||||
|
#include <asm/mpspec.h>
|
||||||
|
#include <asm/system.h>
|
||||||
#include <asm/msr.h>
|
#include <asm/msr.h>
|
||||||
|
|
||||||
#define ARCH_APICTIMER_STOPS_ON_C3 1
|
#define ARCH_APICTIMER_STOPS_ON_C3 1
|
||||||
|
@ -92,6 +95,12 @@ static inline u32 native_apic_mem_read(u32 reg)
|
||||||
return *((volatile u32 *)(APIC_BASE + reg));
|
return *((volatile u32 *)(APIC_BASE + reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void native_apic_wait_icr_idle(void);
|
||||||
|
extern u32 native_safe_apic_wait_icr_idle(void);
|
||||||
|
extern void native_apic_icr_write(u32 low, u32 id);
|
||||||
|
extern u64 native_apic_icr_read(void);
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_X2APIC
|
||||||
static inline void native_apic_msr_write(u32 reg, u32 v)
|
static inline void native_apic_msr_write(u32 reg, u32 v)
|
||||||
{
|
{
|
||||||
if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
|
if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
|
||||||
|
@ -112,7 +121,31 @@ static inline u32 native_apic_msr_read(u32 reg)
|
||||||
return low;
|
return low;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_X86_32
|
static inline void native_x2apic_wait_icr_idle(void)
|
||||||
|
{
|
||||||
|
/* no need to wait for icr idle in x2apic */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 native_safe_x2apic_wait_icr_idle(void)
|
||||||
|
{
|
||||||
|
/* no need to wait for icr idle in x2apic */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void native_x2apic_icr_write(u32 low, u32 id)
|
||||||
|
{
|
||||||
|
wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u64 native_x2apic_icr_read(void)
|
||||||
|
{
|
||||||
|
unsigned long val;
|
||||||
|
|
||||||
|
rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
extern int x2apic;
|
extern int x2apic;
|
||||||
extern void check_x2apic(void);
|
extern void check_x2apic(void);
|
||||||
extern void enable_x2apic(void);
|
extern void enable_x2apic(void);
|
||||||
|
@ -131,53 +164,24 @@ static inline int x2apic_enabled(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define x2apic_enabled() 0
|
static inline void check_x2apic(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline void enable_x2apic(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline void enable_IR_x2apic(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline int x2apic_enabled(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct apic_ops {
|
|
||||||
u32 (*read)(u32 reg);
|
|
||||||
void (*write)(u32 reg, u32 v);
|
|
||||||
u64 (*icr_read)(void);
|
|
||||||
void (*icr_write)(u32 low, u32 high);
|
|
||||||
void (*wait_icr_idle)(void);
|
|
||||||
u32 (*safe_wait_icr_idle)(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct apic_ops *apic_ops;
|
|
||||||
|
|
||||||
static inline u32 apic_read(u32 reg)
|
|
||||||
{
|
|
||||||
return apic_ops->read(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void apic_write(u32 reg, u32 val)
|
|
||||||
{
|
|
||||||
apic_ops->write(reg, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u64 apic_icr_read(void)
|
|
||||||
{
|
|
||||||
return apic_ops->icr_read();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void apic_icr_write(u32 low, u32 high)
|
|
||||||
{
|
|
||||||
apic_ops->icr_write(low, high);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void apic_wait_icr_idle(void)
|
|
||||||
{
|
|
||||||
apic_ops->wait_icr_idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 safe_apic_wait_icr_idle(void)
|
|
||||||
{
|
|
||||||
return apic_ops->safe_wait_icr_idle();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int get_physical_broadcast(void);
|
extern int get_physical_broadcast(void);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_X2APIC
|
||||||
static inline void ack_x2APIC_irq(void)
|
static inline void ack_x2APIC_irq(void)
|
||||||
{
|
{
|
||||||
/* Docs say use 0 for future compatibility */
|
/* Docs say use 0 for future compatibility */
|
||||||
|
@ -185,18 +189,6 @@ static inline void ack_x2APIC_irq(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static inline void ack_APIC_irq(void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* ack_APIC_irq() actually gets compiled as a single instruction
|
|
||||||
* ... yummie.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Docs say use 0 for future compatibility */
|
|
||||||
apic_write(APIC_EOI, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int lapic_get_maxlvt(void);
|
extern int lapic_get_maxlvt(void);
|
||||||
extern void clear_local_APIC(void);
|
extern void clear_local_APIC(void);
|
||||||
extern void connect_bsp_APIC(void);
|
extern void connect_bsp_APIC(void);
|
||||||
|
@ -244,7 +236,138 @@ static inline void disable_local_APIC(void) { }
|
||||||
#define SET_APIC_ID(x) (apic->set_apic_id(x))
|
#define SET_APIC_ID(x) (apic->set_apic_id(x))
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2004 James Cleverdon, IBM.
|
||||||
|
* Subject to the GNU Public License, v.2
|
||||||
|
*
|
||||||
|
* Generic APIC sub-arch data struct.
|
||||||
|
*
|
||||||
|
* Hacked for x86-64 by James Cleverdon from i386 architecture code by
|
||||||
|
* Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
|
||||||
|
* James Cleverdon.
|
||||||
|
*/
|
||||||
|
struct apic {
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
int (*probe)(void);
|
||||||
|
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
|
||||||
|
int (*apic_id_registered)(void);
|
||||||
|
|
||||||
|
u32 irq_delivery_mode;
|
||||||
|
u32 irq_dest_mode;
|
||||||
|
|
||||||
|
const struct cpumask *(*target_cpus)(void);
|
||||||
|
|
||||||
|
int disable_esr;
|
||||||
|
|
||||||
|
int dest_logical;
|
||||||
|
unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
|
||||||
|
unsigned long (*check_apicid_present)(int apicid);
|
||||||
|
|
||||||
|
void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
|
||||||
|
void (*init_apic_ldr)(void);
|
||||||
|
|
||||||
|
physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
|
||||||
|
|
||||||
|
void (*setup_apic_routing)(void);
|
||||||
|
int (*multi_timer_check)(int apic, int irq);
|
||||||
|
int (*apicid_to_node)(int logical_apicid);
|
||||||
|
int (*cpu_to_logical_apicid)(int cpu);
|
||||||
|
int (*cpu_present_to_apicid)(int mps_cpu);
|
||||||
|
physid_mask_t (*apicid_to_cpu_present)(int phys_apicid);
|
||||||
|
void (*setup_portio_remap)(void);
|
||||||
|
int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
|
||||||
|
void (*enable_apic_mode)(void);
|
||||||
|
int (*phys_pkg_id)(int cpuid_apic, int index_msb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When one of the next two hooks returns 1 the apic
|
||||||
|
* is switched to this. Essentially they are additional
|
||||||
|
* probe functions:
|
||||||
|
*/
|
||||||
|
int (*mps_oem_check)(struct mpc_table *mpc, char *oem, char *productid);
|
||||||
|
|
||||||
|
unsigned int (*get_apic_id)(unsigned long x);
|
||||||
|
unsigned long (*set_apic_id)(unsigned int id);
|
||||||
|
unsigned long apic_id_mask;
|
||||||
|
|
||||||
|
unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask);
|
||||||
|
unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
|
||||||
|
const struct cpumask *andmask);
|
||||||
|
|
||||||
|
/* ipi */
|
||||||
|
void (*send_IPI_mask)(const struct cpumask *mask, int vector);
|
||||||
|
void (*send_IPI_mask_allbutself)(const struct cpumask *mask,
|
||||||
|
int vector);
|
||||||
|
void (*send_IPI_allbutself)(int vector);
|
||||||
|
void (*send_IPI_all)(int vector);
|
||||||
|
void (*send_IPI_self)(int vector);
|
||||||
|
|
||||||
|
/* wakeup_secondary_cpu */
|
||||||
|
int (*wakeup_cpu)(int apicid, unsigned long start_eip);
|
||||||
|
|
||||||
|
int trampoline_phys_low;
|
||||||
|
int trampoline_phys_high;
|
||||||
|
|
||||||
|
void (*wait_for_init_deassert)(atomic_t *deassert);
|
||||||
|
void (*smp_callin_clear_local_apic)(void);
|
||||||
|
void (*inquire_remote_apic)(int apicid);
|
||||||
|
|
||||||
|
/* apic ops */
|
||||||
|
u32 (*read)(u32 reg);
|
||||||
|
void (*write)(u32 reg, u32 v);
|
||||||
|
u64 (*icr_read)(void);
|
||||||
|
void (*icr_write)(u32 low, u32 high);
|
||||||
|
void (*wait_icr_idle)(void);
|
||||||
|
u32 (*safe_wait_icr_idle)(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct apic *apic;
|
||||||
|
|
||||||
|
static inline u32 apic_read(u32 reg)
|
||||||
|
{
|
||||||
|
return apic->read(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void apic_write(u32 reg, u32 val)
|
||||||
|
{
|
||||||
|
apic->write(reg, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u64 apic_icr_read(void)
|
||||||
|
{
|
||||||
|
return apic->icr_read();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void apic_icr_write(u32 low, u32 high)
|
||||||
|
{
|
||||||
|
apic->icr_write(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void apic_wait_icr_idle(void)
|
||||||
|
{
|
||||||
|
apic->wait_icr_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 safe_apic_wait_icr_idle(void)
|
||||||
|
{
|
||||||
|
return apic->safe_wait_icr_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void ack_APIC_irq(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* ack_APIC_irq() actually gets compiled as a single instruction
|
||||||
|
* ... yummie.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Docs say use 0 for future compatibility */
|
||||||
|
apic_write(APIC_EOI, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline unsigned default_get_apic_id(unsigned long x)
|
static inline unsigned default_get_apic_id(unsigned long x)
|
||||||
{
|
{
|
||||||
unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
|
unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
|
||||||
|
@ -254,8 +377,171 @@ static inline unsigned default_get_apic_id(unsigned long x)
|
||||||
else
|
else
|
||||||
return (x >> 24) & 0x0F;
|
return (x >> 24) & 0x0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Warm reset vector default position:
|
||||||
|
*/
|
||||||
|
#define DEFAULT_TRAMPOLINE_PHYS_LOW 0x467
|
||||||
|
#define DEFAULT_TRAMPOLINE_PHYS_HIGH 0x469
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
extern void es7000_update_apic_to_cluster(void);
|
||||||
|
#else
|
||||||
|
extern struct apic apic_flat;
|
||||||
|
extern struct apic apic_physflat;
|
||||||
|
extern struct apic apic_x2apic_cluster;
|
||||||
|
extern struct apic apic_x2apic_phys;
|
||||||
|
extern int default_acpi_madt_oem_check(char *, char *);
|
||||||
|
|
||||||
|
extern void apic_send_IPI_self(int vector);
|
||||||
|
|
||||||
|
extern struct apic apic_x2apic_uv_x;
|
||||||
|
DECLARE_PER_CPU(int, x2apic_extra_bits);
|
||||||
|
|
||||||
|
extern int default_cpu_present_to_apicid(int mps_cpu);
|
||||||
|
extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void default_wait_for_init_deassert(atomic_t *deassert)
|
||||||
|
{
|
||||||
|
while (!atomic_read(deassert))
|
||||||
|
cpu_relax();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void generic_bigsmp_probe(void);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
|
|
||||||
|
#include <asm/smp.h>
|
||||||
|
|
||||||
|
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
|
||||||
|
|
||||||
|
static inline const struct cpumask *default_target_cpus(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
return cpu_online_mask;
|
||||||
|
#else
|
||||||
|
return cpumask_of(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid);
|
||||||
|
|
||||||
|
|
||||||
|
static inline unsigned int read_apic_id(void)
|
||||||
|
{
|
||||||
|
unsigned int reg;
|
||||||
|
|
||||||
|
reg = apic_read(APIC_ID);
|
||||||
|
|
||||||
|
return apic->get_apic_id(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void default_setup_apic_routing(void);
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
/*
|
||||||
|
* Set up the logical destination ID.
|
||||||
|
*
|
||||||
|
* Intel recommends to set DFR, LDR and TPR before enabling
|
||||||
|
* an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
|
||||||
|
* document number 292116). So here it goes...
|
||||||
|
*/
|
||||||
|
extern void default_init_apic_ldr(void);
|
||||||
|
|
||||||
|
static inline int default_apic_id_registered(void)
|
||||||
|
{
|
||||||
|
return physid_isset(read_apic_id(), phys_cpu_present_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
default_cpu_mask_to_apicid(const struct cpumask *cpumask)
|
||||||
|
{
|
||||||
|
return cpumask_bits(cpumask)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||||
|
const struct cpumask *andmask)
|
||||||
|
{
|
||||||
|
unsigned long mask1 = cpumask_bits(cpumask)[0];
|
||||||
|
unsigned long mask2 = cpumask_bits(andmask)[0];
|
||||||
|
unsigned long mask3 = cpumask_bits(cpu_online_mask)[0];
|
||||||
|
|
||||||
|
return (unsigned int)(mask1 & mask2 & mask3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
|
||||||
|
{
|
||||||
|
return cpuid_apic >> index_msb;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int default_apicid_to_node(int logical_apicid);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid)
|
||||||
|
{
|
||||||
|
return physid_isset(apicid, bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long default_check_apicid_present(int bit)
|
||||||
|
{
|
||||||
|
return physid_isset(bit, phys_cpu_present_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline physid_mask_t default_ioapic_phys_id_map(physid_mask_t phys_map)
|
||||||
|
{
|
||||||
|
return phys_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mapping from cpu number to logical apicid */
|
||||||
|
static inline int default_cpu_to_logical_apicid(int cpu)
|
||||||
|
{
|
||||||
|
return 1 << cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int __default_cpu_present_to_apicid(int mps_cpu)
|
||||||
|
{
|
||||||
|
if (mps_cpu < nr_cpu_ids && cpu_present(mps_cpu))
|
||||||
|
return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
|
||||||
|
else
|
||||||
|
return BAD_APICID;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__default_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
||||||
|
{
|
||||||
|
return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
static inline int default_cpu_present_to_apicid(int mps_cpu)
|
||||||
|
{
|
||||||
|
return __default_cpu_present_to_apicid(mps_cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
default_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
||||||
|
{
|
||||||
|
return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern int default_cpu_present_to_apicid(int mps_cpu);
|
||||||
|
extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid)
|
||||||
|
{
|
||||||
|
return physid_mask_of_physid(phys_apicid);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_X86_LOCAL_APIC */
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
extern u8 cpu_2_logical_apicid[NR_CPUS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _ASM_X86_APIC_H */
|
#endif /* _ASM_X86_APIC_H */
|
||||||
|
|
|
@ -1,263 +1 @@
|
||||||
#ifndef _ASM_X86_GENAPIC_H
|
#include <asm/apic.h>
|
||||||
#define _ASM_X86_GENAPIC_H
|
|
||||||
|
|
||||||
#include <linux/cpumask.h>
|
|
||||||
|
|
||||||
#include <asm/mpspec.h>
|
|
||||||
#include <asm/atomic.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright 2004 James Cleverdon, IBM.
|
|
||||||
* Subject to the GNU Public License, v.2
|
|
||||||
*
|
|
||||||
* Generic APIC sub-arch data struct.
|
|
||||||
*
|
|
||||||
* Hacked for x86-64 by James Cleverdon from i386 architecture code by
|
|
||||||
* Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
|
|
||||||
* James Cleverdon.
|
|
||||||
*/
|
|
||||||
struct genapic {
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
int (*probe)(void);
|
|
||||||
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
|
|
||||||
int (*apic_id_registered)(void);
|
|
||||||
|
|
||||||
u32 irq_delivery_mode;
|
|
||||||
u32 irq_dest_mode;
|
|
||||||
|
|
||||||
const struct cpumask *(*target_cpus)(void);
|
|
||||||
|
|
||||||
int disable_esr;
|
|
||||||
|
|
||||||
int dest_logical;
|
|
||||||
unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid);
|
|
||||||
unsigned long (*check_apicid_present)(int apicid);
|
|
||||||
|
|
||||||
void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
|
|
||||||
void (*init_apic_ldr)(void);
|
|
||||||
|
|
||||||
physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map);
|
|
||||||
|
|
||||||
void (*setup_apic_routing)(void);
|
|
||||||
int (*multi_timer_check)(int apic, int irq);
|
|
||||||
int (*apicid_to_node)(int logical_apicid);
|
|
||||||
int (*cpu_to_logical_apicid)(int cpu);
|
|
||||||
int (*cpu_present_to_apicid)(int mps_cpu);
|
|
||||||
physid_mask_t (*apicid_to_cpu_present)(int phys_apicid);
|
|
||||||
void (*setup_portio_remap)(void);
|
|
||||||
int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
|
|
||||||
void (*enable_apic_mode)(void);
|
|
||||||
int (*phys_pkg_id)(int cpuid_apic, int index_msb);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When one of the next two hooks returns 1 the genapic
|
|
||||||
* is switched to this. Essentially they are additional
|
|
||||||
* probe functions:
|
|
||||||
*/
|
|
||||||
int (*mps_oem_check)(struct mpc_table *mpc, char *oem, char *productid);
|
|
||||||
|
|
||||||
unsigned int (*get_apic_id)(unsigned long x);
|
|
||||||
unsigned long (*set_apic_id)(unsigned int id);
|
|
||||||
unsigned long apic_id_mask;
|
|
||||||
|
|
||||||
unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask);
|
|
||||||
unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
|
|
||||||
const struct cpumask *andmask);
|
|
||||||
|
|
||||||
/* ipi */
|
|
||||||
void (*send_IPI_mask)(const struct cpumask *mask, int vector);
|
|
||||||
void (*send_IPI_mask_allbutself)(const struct cpumask *mask,
|
|
||||||
int vector);
|
|
||||||
void (*send_IPI_allbutself)(int vector);
|
|
||||||
void (*send_IPI_all)(int vector);
|
|
||||||
void (*send_IPI_self)(int vector);
|
|
||||||
|
|
||||||
/* wakeup_secondary_cpu */
|
|
||||||
int (*wakeup_cpu)(int apicid, unsigned long start_eip);
|
|
||||||
|
|
||||||
int trampoline_phys_low;
|
|
||||||
int trampoline_phys_high;
|
|
||||||
|
|
||||||
void (*wait_for_init_deassert)(atomic_t *deassert);
|
|
||||||
void (*smp_callin_clear_local_apic)(void);
|
|
||||||
void (*store_NMI_vector)(unsigned short *high, unsigned short *low);
|
|
||||||
void (*inquire_remote_apic)(int apicid);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct genapic *apic;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Warm reset vector default position:
|
|
||||||
*/
|
|
||||||
#define DEFAULT_TRAMPOLINE_PHYS_LOW 0x467
|
|
||||||
#define DEFAULT_TRAMPOLINE_PHYS_HIGH 0x469
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
extern void es7000_update_genapic_to_cluster(void);
|
|
||||||
#else
|
|
||||||
extern struct genapic apic_flat;
|
|
||||||
extern struct genapic apic_physflat;
|
|
||||||
extern struct genapic apic_x2apic_cluster;
|
|
||||||
extern struct genapic apic_x2apic_phys;
|
|
||||||
extern int default_acpi_madt_oem_check(char *, char *);
|
|
||||||
|
|
||||||
extern void apic_send_IPI_self(int vector);
|
|
||||||
|
|
||||||
extern struct genapic apic_x2apic_uv_x;
|
|
||||||
DECLARE_PER_CPU(int, x2apic_extra_bits);
|
|
||||||
|
|
||||||
extern void default_setup_apic_routing(void);
|
|
||||||
|
|
||||||
extern int default_cpu_present_to_apicid(int mps_cpu);
|
|
||||||
extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline void default_wait_for_init_deassert(atomic_t *deassert)
|
|
||||||
{
|
|
||||||
while (!atomic_read(deassert))
|
|
||||||
cpu_relax();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void generic_bigsmp_probe(void);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
|
||||||
|
|
||||||
#include <asm/smp.h>
|
|
||||||
|
|
||||||
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
|
|
||||||
|
|
||||||
static inline const struct cpumask *default_target_cpus(void)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
return cpu_online_mask;
|
|
||||||
#else
|
|
||||||
return cpumask_of(0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid);
|
|
||||||
|
|
||||||
|
|
||||||
static inline unsigned int read_apic_id(void)
|
|
||||||
{
|
|
||||||
unsigned int reg;
|
|
||||||
|
|
||||||
reg = apic_read(APIC_ID);
|
|
||||||
|
|
||||||
return apic->get_apic_id(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
extern void default_setup_apic_routing(void);
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up the logical destination ID.
|
|
||||||
*
|
|
||||||
* Intel recommends to set DFR, LDR and TPR before enabling
|
|
||||||
* an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
|
|
||||||
* document number 292116). So here it goes...
|
|
||||||
*/
|
|
||||||
extern void default_init_apic_ldr(void);
|
|
||||||
|
|
||||||
static inline int default_apic_id_registered(void)
|
|
||||||
{
|
|
||||||
return physid_isset(read_apic_id(), phys_cpu_present_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int
|
|
||||||
default_cpu_mask_to_apicid(const struct cpumask *cpumask)
|
|
||||||
{
|
|
||||||
return cpumask_bits(cpumask)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int
|
|
||||||
default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
|
||||||
const struct cpumask *andmask)
|
|
||||||
{
|
|
||||||
unsigned long mask1 = cpumask_bits(cpumask)[0];
|
|
||||||
unsigned long mask2 = cpumask_bits(andmask)[0];
|
|
||||||
unsigned long mask3 = cpumask_bits(cpu_online_mask)[0];
|
|
||||||
|
|
||||||
return (unsigned int)(mask1 & mask2 & mask3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
|
|
||||||
{
|
|
||||||
return cpuid_apic >> index_msb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void default_setup_apic_routing(void)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_X86_IO_APIC
|
|
||||||
printk("Enabling APIC mode: %s. Using %d I/O APICs\n",
|
|
||||||
"Flat", nr_ioapics);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int default_apicid_to_node(int logical_apicid);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid)
|
|
||||||
{
|
|
||||||
return physid_isset(apicid, bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long default_check_apicid_present(int bit)
|
|
||||||
{
|
|
||||||
return physid_isset(bit, phys_cpu_present_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline physid_mask_t default_ioapic_phys_id_map(physid_mask_t phys_map)
|
|
||||||
{
|
|
||||||
return phys_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mapping from cpu number to logical apicid */
|
|
||||||
static inline int default_cpu_to_logical_apicid(int cpu)
|
|
||||||
{
|
|
||||||
return 1 << cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int __default_cpu_present_to_apicid(int mps_cpu)
|
|
||||||
{
|
|
||||||
if (mps_cpu < nr_cpu_ids && cpu_present(mps_cpu))
|
|
||||||
return (int)per_cpu(x86_bios_cpu_apicid, mps_cpu);
|
|
||||||
else
|
|
||||||
return BAD_APICID;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
__default_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
|
||||||
{
|
|
||||||
return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
static inline int default_cpu_present_to_apicid(int mps_cpu)
|
|
||||||
{
|
|
||||||
return __default_cpu_present_to_apicid(mps_cpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
|
||||||
default_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
|
||||||
{
|
|
||||||
return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
extern int default_cpu_present_to_apicid(int mps_cpu);
|
|
||||||
extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid)
|
|
||||||
{
|
|
||||||
return physid_mask_of_physid(phys_apicid);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_X86_LOCAL_APIC */
|
|
||||||
|
|
||||||
#endif /* _ASM_X86_GENAPIC_64_H */
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ static inline void *phys_to_virt(phys_addr_t address)
|
||||||
/*
|
/*
|
||||||
* ISA I/O bus memory addresses are 1:1 with the physical address.
|
* ISA I/O bus memory addresses are 1:1 with the physical address.
|
||||||
*/
|
*/
|
||||||
#define isa_virt_to_bus virt_to_phys
|
#define isa_virt_to_bus (unsigned long)virt_to_phys
|
||||||
#define isa_page_to_bus page_to_phys
|
#define isa_page_to_bus page_to_phys
|
||||||
#define isa_bus_to_virt phys_to_virt
|
#define isa_bus_to_virt phys_to_virt
|
||||||
|
|
||||||
|
|
|
@ -123,8 +123,6 @@ extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask,
|
||||||
int vector);
|
int vector);
|
||||||
extern void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask,
|
extern void default_send_IPI_mask_allbutself_phys(const struct cpumask *mask,
|
||||||
int vector);
|
int vector);
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
extern void default_send_IPI_mask_sequence_logical(const struct cpumask *mask,
|
extern void default_send_IPI_mask_sequence_logical(const struct cpumask *mask,
|
||||||
int vector);
|
int vector);
|
||||||
extern void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask,
|
extern void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask,
|
||||||
|
|
|
@ -167,6 +167,4 @@ extern int generic_mps_oem_check(struct mpc_table *, char *, char *);
|
||||||
|
|
||||||
extern int default_acpi_madt_oem_check(char *, char *);
|
extern int default_acpi_madt_oem_check(char *, char *);
|
||||||
|
|
||||||
extern void numaq_mps_oem_check(struct mpc_table *, char *, char *);
|
|
||||||
|
|
||||||
#endif /* _ASM_X86_MPSPEC_H */
|
#endif /* _ASM_X86_MPSPEC_H */
|
||||||
|
|
|
@ -1,42 +1,11 @@
|
||||||
#ifndef _ASM_X86_PAGE_H
|
#ifndef _ASM_X86_PAGE_H
|
||||||
#define _ASM_X86_PAGE_H
|
#define _ASM_X86_PAGE_H
|
||||||
|
|
||||||
#include <linux/const.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
/* PAGE_SHIFT determines the page size */
|
|
||||||
#define PAGE_SHIFT 12
|
|
||||||
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
|
|
||||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#define __PHYSICAL_MASK ((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1)
|
#include <asm/page_types.h>
|
||||||
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
|
|
||||||
|
|
||||||
/* Cast PAGE_MASK to a signed type so that it is sign-extended if
|
|
||||||
virtual addresses are 32-bits but physical addresses are larger
|
|
||||||
(ie, 32-bit PAE). */
|
|
||||||
#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
|
|
||||||
|
|
||||||
/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
|
|
||||||
#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK)
|
|
||||||
|
|
||||||
/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */
|
|
||||||
#define PTE_FLAGS_MASK (~PTE_PFN_MASK)
|
|
||||||
|
|
||||||
#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
|
|
||||||
#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
|
|
||||||
|
|
||||||
#define HPAGE_SHIFT PMD_SHIFT
|
|
||||||
#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
|
|
||||||
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
|
|
||||||
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
|
|
||||||
|
|
||||||
#define HUGE_MAX_HSTATE 2
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
#include <linux/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
#include <asm/page_64.h>
|
#include <asm/page_64.h>
|
||||||
|
@ -44,38 +13,18 @@
|
||||||
#include <asm/page_32.h>
|
#include <asm/page_32.h>
|
||||||
#endif /* CONFIG_X86_64 */
|
#endif /* CONFIG_X86_64 */
|
||||||
|
|
||||||
#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
|
|
||||||
|
|
||||||
#define VM_DATA_DEFAULT_FLAGS \
|
|
||||||
(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
|
|
||||||
VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
typedef struct { pgdval_t pgd; } pgd_t;
|
|
||||||
typedef struct { pgprotval_t pgprot; } pgprot_t;
|
|
||||||
|
|
||||||
extern int page_is_ram(unsigned long pagenr);
|
|
||||||
extern int devmem_is_allowed(unsigned long pagenr);
|
|
||||||
extern void map_devmem(unsigned long pfn, unsigned long size,
|
|
||||||
pgprot_t vma_prot);
|
|
||||||
extern void unmap_devmem(unsigned long pfn, unsigned long size,
|
|
||||||
pgprot_t vma_prot);
|
|
||||||
|
|
||||||
extern unsigned long max_low_pfn_mapped;
|
|
||||||
extern unsigned long max_pfn_mapped;
|
|
||||||
|
|
||||||
struct page;
|
struct page;
|
||||||
|
|
||||||
static inline void clear_user_page(void *page, unsigned long vaddr,
|
static inline void clear_user_page(void *page, unsigned long vaddr,
|
||||||
struct page *pg)
|
struct page *pg)
|
||||||
{
|
{
|
||||||
clear_page(page);
|
clear_page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
|
static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
|
||||||
struct page *topage)
|
struct page *topage)
|
||||||
{
|
{
|
||||||
copy_page(to, from);
|
copy_page(to, from);
|
||||||
}
|
}
|
||||||
|
@ -84,114 +33,6 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
|
||||||
alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
|
alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
|
||||||
#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
|
#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
|
||||||
|
|
||||||
static inline pgd_t native_make_pgd(pgdval_t val)
|
|
||||||
{
|
|
||||||
return (pgd_t) { val };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pgdval_t native_pgd_val(pgd_t pgd)
|
|
||||||
{
|
|
||||||
return pgd.pgd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pgdval_t pgd_flags(pgd_t pgd)
|
|
||||||
{
|
|
||||||
return native_pgd_val(pgd) & PTE_FLAGS_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PAGETABLE_LEVELS >= 3
|
|
||||||
#if PAGETABLE_LEVELS == 4
|
|
||||||
typedef struct { pudval_t pud; } pud_t;
|
|
||||||
|
|
||||||
static inline pud_t native_make_pud(pmdval_t val)
|
|
||||||
{
|
|
||||||
return (pud_t) { val };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pudval_t native_pud_val(pud_t pud)
|
|
||||||
{
|
|
||||||
return pud.pud;
|
|
||||||
}
|
|
||||||
#else /* PAGETABLE_LEVELS == 3 */
|
|
||||||
#include <asm-generic/pgtable-nopud.h>
|
|
||||||
|
|
||||||
static inline pudval_t native_pud_val(pud_t pud)
|
|
||||||
{
|
|
||||||
return native_pgd_val(pud.pgd);
|
|
||||||
}
|
|
||||||
#endif /* PAGETABLE_LEVELS == 4 */
|
|
||||||
|
|
||||||
static inline pudval_t pud_flags(pud_t pud)
|
|
||||||
{
|
|
||||||
return native_pud_val(pud) & PTE_FLAGS_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct { pmdval_t pmd; } pmd_t;
|
|
||||||
|
|
||||||
static inline pmd_t native_make_pmd(pmdval_t val)
|
|
||||||
{
|
|
||||||
return (pmd_t) { val };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pmdval_t native_pmd_val(pmd_t pmd)
|
|
||||||
{
|
|
||||||
return pmd.pmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* PAGETABLE_LEVELS == 2 */
|
|
||||||
#include <asm-generic/pgtable-nopmd.h>
|
|
||||||
|
|
||||||
static inline pmdval_t native_pmd_val(pmd_t pmd)
|
|
||||||
{
|
|
||||||
return native_pgd_val(pmd.pud.pgd);
|
|
||||||
}
|
|
||||||
#endif /* PAGETABLE_LEVELS >= 3 */
|
|
||||||
|
|
||||||
static inline pmdval_t pmd_flags(pmd_t pmd)
|
|
||||||
{
|
|
||||||
return native_pmd_val(pmd) & PTE_FLAGS_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pte_t native_make_pte(pteval_t val)
|
|
||||||
{
|
|
||||||
return (pte_t) { .pte = val };
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pteval_t native_pte_val(pte_t pte)
|
|
||||||
{
|
|
||||||
return pte.pte;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline pteval_t pte_flags(pte_t pte)
|
|
||||||
{
|
|
||||||
return native_pte_val(pte) & PTE_FLAGS_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define pgprot_val(x) ((x).pgprot)
|
|
||||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
|
||||||
|
|
||||||
#ifdef CONFIG_PARAVIRT
|
|
||||||
#include <asm/paravirt.h>
|
|
||||||
#else /* !CONFIG_PARAVIRT */
|
|
||||||
|
|
||||||
#define pgd_val(x) native_pgd_val(x)
|
|
||||||
#define __pgd(x) native_make_pgd(x)
|
|
||||||
|
|
||||||
#ifndef __PAGETABLE_PUD_FOLDED
|
|
||||||
#define pud_val(x) native_pud_val(x)
|
|
||||||
#define __pud(x) native_make_pud(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __PAGETABLE_PMD_FOLDED
|
|
||||||
#define pmd_val(x) native_pmd_val(x)
|
|
||||||
#define __pmd(x) native_make_pmd(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define pte_val(x) native_pte_val(x)
|
|
||||||
#define __pte(x) native_make_pte(x)
|
|
||||||
|
|
||||||
#endif /* CONFIG_PARAVIRT */
|
|
||||||
|
|
||||||
#define __pa(x) __phys_addr((unsigned long)(x))
|
#define __pa(x) __phys_addr((unsigned long)(x))
|
||||||
#define __pa_nodebug(x) __phys_addr_nodebug((unsigned long)(x))
|
#define __pa_nodebug(x) __phys_addr_nodebug((unsigned long)(x))
|
||||||
/* __pa_symbol should be used for C visible symbols.
|
/* __pa_symbol should be used for C visible symbols.
|
||||||
|
|
|
@ -1,82 +1,14 @@
|
||||||
#ifndef _ASM_X86_PAGE_32_H
|
#ifndef _ASM_X86_PAGE_32_H
|
||||||
#define _ASM_X86_PAGE_32_H
|
#define _ASM_X86_PAGE_32_H
|
||||||
|
|
||||||
/*
|
#include <asm/page_32_types.h>
|
||||||
* This handles the memory map.
|
|
||||||
*
|
|
||||||
* A __PAGE_OFFSET of 0xC0000000 means that the kernel has
|
|
||||||
* a virtual address space of one gigabyte, which limits the
|
|
||||||
* amount of physical memory you can use to about 950MB.
|
|
||||||
*
|
|
||||||
* If you want more physical memory than this then see the CONFIG_HIGHMEM4G
|
|
||||||
* and CONFIG_HIGHMEM64G options in the kernel configuration.
|
|
||||||
*/
|
|
||||||
#define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
|
|
||||||
|
|
||||||
#ifdef CONFIG_4KSTACKS
|
|
||||||
#define THREAD_ORDER 0
|
|
||||||
#else
|
|
||||||
#define THREAD_ORDER 1
|
|
||||||
#endif
|
|
||||||
#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
|
|
||||||
|
|
||||||
#define STACKFAULT_STACK 0
|
|
||||||
#define DOUBLEFAULT_STACK 1
|
|
||||||
#define NMI_STACK 0
|
|
||||||
#define DEBUG_STACK 0
|
|
||||||
#define MCE_STACK 0
|
|
||||||
#define N_EXCEPTION_STACKS 1
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_PAE
|
|
||||||
/* 44=32+12, the limit we can fit into an unsigned long pfn */
|
|
||||||
#define __PHYSICAL_MASK_SHIFT 44
|
|
||||||
#define __VIRTUAL_MASK_SHIFT 32
|
|
||||||
#define PAGETABLE_LEVELS 3
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
typedef u64 pteval_t;
|
|
||||||
typedef u64 pmdval_t;
|
|
||||||
typedef u64 pudval_t;
|
|
||||||
typedef u64 pgdval_t;
|
|
||||||
typedef u64 pgprotval_t;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
unsigned long pte_low, pte_high;
|
|
||||||
};
|
|
||||||
pteval_t pte;
|
|
||||||
} pte_t;
|
|
||||||
#endif /* __ASSEMBLY__
|
|
||||||
*/
|
|
||||||
#else /* !CONFIG_X86_PAE */
|
|
||||||
#define __PHYSICAL_MASK_SHIFT 32
|
|
||||||
#define __VIRTUAL_MASK_SHIFT 32
|
|
||||||
#define PAGETABLE_LEVELS 2
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
typedef unsigned long pteval_t;
|
|
||||||
typedef unsigned long pmdval_t;
|
|
||||||
typedef unsigned long pudval_t;
|
|
||||||
typedef unsigned long pgdval_t;
|
|
||||||
typedef unsigned long pgprotval_t;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
pteval_t pte;
|
|
||||||
pteval_t pte_low;
|
|
||||||
} pte_t;
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
|
||||||
#endif /* CONFIG_X86_PAE */
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
typedef struct page *pgtable_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_HUGETLB_PAGE
|
#ifdef CONFIG_HUGETLB_PAGE
|
||||||
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
|
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
#define __phys_addr_nodebug(x) ((x) - PAGE_OFFSET)
|
#define __phys_addr_nodebug(x) ((x) - PAGE_OFFSET)
|
||||||
#ifdef CONFIG_DEBUG_VIRTUAL
|
#ifdef CONFIG_DEBUG_VIRTUAL
|
||||||
extern unsigned long __phys_addr(unsigned long);
|
extern unsigned long __phys_addr(unsigned long);
|
||||||
|
@ -89,23 +21,6 @@ extern unsigned long __phys_addr(unsigned long);
|
||||||
#define pfn_valid(pfn) ((pfn) < max_mapnr)
|
#define pfn_valid(pfn) ((pfn) < max_mapnr)
|
||||||
#endif /* CONFIG_FLATMEM */
|
#endif /* CONFIG_FLATMEM */
|
||||||
|
|
||||||
extern int nx_enabled;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This much address space is reserved for vmalloc() and iomap()
|
|
||||||
* as well as fixmap mappings.
|
|
||||||
*/
|
|
||||||
extern unsigned int __VMALLOC_RESERVE;
|
|
||||||
extern int sysctl_legacy_va_layout;
|
|
||||||
|
|
||||||
extern void find_low_pfn_range(void);
|
|
||||||
extern unsigned long init_memory_mapping(unsigned long start,
|
|
||||||
unsigned long end);
|
|
||||||
extern void initmem_init(unsigned long, unsigned long);
|
|
||||||
extern void free_initmem(void);
|
|
||||||
extern void setup_bootmem_allocator(void);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_USE_3DNOW
|
#ifdef CONFIG_X86_USE_3DNOW
|
||||||
#include <asm/mmx.h>
|
#include <asm/mmx.h>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef _ASM_X86_PAGE_32_DEFS_H
|
||||||
|
#define _ASM_X86_PAGE_32_DEFS_H
|
||||||
|
|
||||||
|
#include <linux/const.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This handles the memory map.
|
||||||
|
*
|
||||||
|
* A __PAGE_OFFSET of 0xC0000000 means that the kernel has
|
||||||
|
* a virtual address space of one gigabyte, which limits the
|
||||||
|
* amount of physical memory you can use to about 950MB.
|
||||||
|
*
|
||||||
|
* If you want more physical memory than this then see the CONFIG_HIGHMEM4G
|
||||||
|
* and CONFIG_HIGHMEM64G options in the kernel configuration.
|
||||||
|
*/
|
||||||
|
#define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
|
||||||
|
|
||||||
|
#ifdef CONFIG_4KSTACKS
|
||||||
|
#define THREAD_ORDER 0
|
||||||
|
#else
|
||||||
|
#define THREAD_ORDER 1
|
||||||
|
#endif
|
||||||
|
#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
|
||||||
|
|
||||||
|
#define STACKFAULT_STACK 0
|
||||||
|
#define DOUBLEFAULT_STACK 1
|
||||||
|
#define NMI_STACK 0
|
||||||
|
#define DEBUG_STACK 0
|
||||||
|
#define MCE_STACK 0
|
||||||
|
#define N_EXCEPTION_STACKS 1
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_PAE
|
||||||
|
/* 44=32+12, the limit we can fit into an unsigned long pfn */
|
||||||
|
#define __PHYSICAL_MASK_SHIFT 44
|
||||||
|
#define __VIRTUAL_MASK_SHIFT 32
|
||||||
|
#define PAGETABLE_LEVELS 3
|
||||||
|
|
||||||
|
#else /* !CONFIG_X86_PAE */
|
||||||
|
#define __PHYSICAL_MASK_SHIFT 32
|
||||||
|
#define __VIRTUAL_MASK_SHIFT 32
|
||||||
|
#define PAGETABLE_LEVELS 2
|
||||||
|
#endif /* CONFIG_X86_PAE */
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This much address space is reserved for vmalloc() and iomap()
|
||||||
|
* as well as fixmap mappings.
|
||||||
|
*/
|
||||||
|
extern unsigned int __VMALLOC_RESERVE;
|
||||||
|
extern int sysctl_legacy_va_layout;
|
||||||
|
|
||||||
|
extern void find_low_pfn_range(void);
|
||||||
|
extern unsigned long init_memory_mapping(unsigned long start,
|
||||||
|
unsigned long end);
|
||||||
|
extern void initmem_init(unsigned long, unsigned long);
|
||||||
|
extern void free_initmem(void);
|
||||||
|
extern void setup_bootmem_allocator(void);
|
||||||
|
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_PAGE_32_DEFS_H */
|
|
@ -1,105 +1,6 @@
|
||||||
#ifndef _ASM_X86_PAGE_64_H
|
#ifndef _ASM_X86_PAGE_64_H
|
||||||
#define _ASM_X86_PAGE_64_H
|
#define _ASM_X86_PAGE_64_H
|
||||||
|
|
||||||
#define PAGETABLE_LEVELS 4
|
#include <asm/page_64_types.h>
|
||||||
|
|
||||||
#define THREAD_ORDER 1
|
|
||||||
#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
|
|
||||||
#define CURRENT_MASK (~(THREAD_SIZE - 1))
|
|
||||||
|
|
||||||
#define EXCEPTION_STACK_ORDER 0
|
|
||||||
#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
|
|
||||||
|
|
||||||
#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1)
|
|
||||||
#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
|
|
||||||
|
|
||||||
#define IRQ_STACK_ORDER 2
|
|
||||||
#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
|
|
||||||
|
|
||||||
#define STACKFAULT_STACK 1
|
|
||||||
#define DOUBLEFAULT_STACK 2
|
|
||||||
#define NMI_STACK 3
|
|
||||||
#define DEBUG_STACK 4
|
|
||||||
#define MCE_STACK 5
|
|
||||||
#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */
|
|
||||||
|
|
||||||
#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
|
|
||||||
#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set __PAGE_OFFSET to the most negative possible address +
|
|
||||||
* PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a
|
|
||||||
* hypervisor to fit. Choosing 16 slots here is arbitrary, but it's
|
|
||||||
* what Xen requires.
|
|
||||||
*/
|
|
||||||
#define __PAGE_OFFSET _AC(0xffff880000000000, UL)
|
|
||||||
|
|
||||||
#define __PHYSICAL_START CONFIG_PHYSICAL_START
|
|
||||||
#define __KERNEL_ALIGN 0x200000
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure kernel is aligned to 2MB address. Catching it at compile
|
|
||||||
* time is better. Change your config file and compile the kernel
|
|
||||||
* for a 2MB aligned address (CONFIG_PHYSICAL_START)
|
|
||||||
*/
|
|
||||||
#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0
|
|
||||||
#error "CONFIG_PHYSICAL_START must be a multiple of 2MB"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
|
|
||||||
#define __START_KERNEL_map _AC(0xffffffff80000000, UL)
|
|
||||||
|
|
||||||
/* See Documentation/x86_64/mm.txt for a description of the memory map. */
|
|
||||||
#define __PHYSICAL_MASK_SHIFT 46
|
|
||||||
#define __VIRTUAL_MASK_SHIFT 48
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Kernel image size is limited to 512 MB (see level2_kernel_pgt in
|
|
||||||
* arch/x86/kernel/head_64.S), and it is mapped here:
|
|
||||||
*/
|
|
||||||
#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024)
|
|
||||||
#define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL)
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
void clear_page(void *page);
|
|
||||||
void copy_page(void *to, void *from);
|
|
||||||
|
|
||||||
/* duplicated to the one in bootmem.h */
|
|
||||||
extern unsigned long max_pfn;
|
|
||||||
extern unsigned long phys_base;
|
|
||||||
|
|
||||||
extern unsigned long __phys_addr(unsigned long);
|
|
||||||
#define __phys_reloc_hide(x) (x)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These are used to make use of C type-checking..
|
|
||||||
*/
|
|
||||||
typedef unsigned long pteval_t;
|
|
||||||
typedef unsigned long pmdval_t;
|
|
||||||
typedef unsigned long pudval_t;
|
|
||||||
typedef unsigned long pgdval_t;
|
|
||||||
typedef unsigned long pgprotval_t;
|
|
||||||
|
|
||||||
typedef struct page *pgtable_t;
|
|
||||||
|
|
||||||
typedef struct { pteval_t pte; } pte_t;
|
|
||||||
|
|
||||||
#define vmemmap ((struct page *)VMEMMAP_START)
|
|
||||||
|
|
||||||
extern unsigned long init_memory_mapping(unsigned long start,
|
|
||||||
unsigned long end);
|
|
||||||
|
|
||||||
extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
|
|
||||||
extern void free_initmem(void);
|
|
||||||
|
|
||||||
extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
|
|
||||||
extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
|
||||||
|
|
||||||
#ifdef CONFIG_FLATMEM
|
|
||||||
#define pfn_valid(pfn) ((pfn) < max_pfn)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _ASM_X86_PAGE_64_H */
|
#endif /* _ASM_X86_PAGE_64_H */
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
#ifndef _ASM_X86_PAGE_64_DEFS_H
|
||||||
|
#define _ASM_X86_PAGE_64_DEFS_H
|
||||||
|
|
||||||
|
#define PAGETABLE_LEVELS 4
|
||||||
|
|
||||||
|
#define THREAD_ORDER 1
|
||||||
|
#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER)
|
||||||
|
#define CURRENT_MASK (~(THREAD_SIZE - 1))
|
||||||
|
|
||||||
|
#define EXCEPTION_STACK_ORDER 0
|
||||||
|
#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
|
||||||
|
|
||||||
|
#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1)
|
||||||
|
#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
|
||||||
|
|
||||||
|
#define IRQ_STACK_ORDER 2
|
||||||
|
#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
|
||||||
|
|
||||||
|
#define STACKFAULT_STACK 1
|
||||||
|
#define DOUBLEFAULT_STACK 2
|
||||||
|
#define NMI_STACK 3
|
||||||
|
#define DEBUG_STACK 4
|
||||||
|
#define MCE_STACK 5
|
||||||
|
#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */
|
||||||
|
|
||||||
|
#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
|
||||||
|
#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set __PAGE_OFFSET to the most negative possible address +
|
||||||
|
* PGDIR_SIZE*16 (pgd slot 272). The gap is to allow a space for a
|
||||||
|
* hypervisor to fit. Choosing 16 slots here is arbitrary, but it's
|
||||||
|
* what Xen requires.
|
||||||
|
*/
|
||||||
|
#define __PAGE_OFFSET _AC(0xffff880000000000, UL)
|
||||||
|
|
||||||
|
#define __PHYSICAL_START CONFIG_PHYSICAL_START
|
||||||
|
#define __KERNEL_ALIGN 0x200000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure kernel is aligned to 2MB address. Catching it at compile
|
||||||
|
* time is better. Change your config file and compile the kernel
|
||||||
|
* for a 2MB aligned address (CONFIG_PHYSICAL_START)
|
||||||
|
*/
|
||||||
|
#if (CONFIG_PHYSICAL_START % __KERNEL_ALIGN) != 0
|
||||||
|
#error "CONFIG_PHYSICAL_START must be a multiple of 2MB"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
|
||||||
|
#define __START_KERNEL_map _AC(0xffffffff80000000, UL)
|
||||||
|
|
||||||
|
/* See Documentation/x86_64/mm.txt for a description of the memory map. */
|
||||||
|
#define __PHYSICAL_MASK_SHIFT 46
|
||||||
|
#define __VIRTUAL_MASK_SHIFT 48
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kernel image size is limited to 512 MB (see level2_kernel_pgt in
|
||||||
|
* arch/x86/kernel/head_64.S), and it is mapped here:
|
||||||
|
*/
|
||||||
|
#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024)
|
||||||
|
#define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL)
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
void clear_page(void *page);
|
||||||
|
void copy_page(void *to, void *from);
|
||||||
|
|
||||||
|
/* duplicated to the one in bootmem.h */
|
||||||
|
extern unsigned long max_pfn;
|
||||||
|
extern unsigned long phys_base;
|
||||||
|
|
||||||
|
extern unsigned long __phys_addr(unsigned long);
|
||||||
|
#define __phys_reloc_hide(x) (x)
|
||||||
|
|
||||||
|
#define vmemmap ((struct page *)VMEMMAP_START)
|
||||||
|
|
||||||
|
extern unsigned long init_memory_mapping(unsigned long start,
|
||||||
|
unsigned long end);
|
||||||
|
|
||||||
|
extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn);
|
||||||
|
extern void free_initmem(void);
|
||||||
|
|
||||||
|
extern void init_extra_mapping_uc(unsigned long phys, unsigned long size);
|
||||||
|
extern void init_extra_mapping_wb(unsigned long phys, unsigned long size);
|
||||||
|
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
#ifdef CONFIG_FLATMEM
|
||||||
|
#define pfn_valid(pfn) ((pfn) < max_pfn)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_PAGE_64_DEFS_H */
|
|
@ -0,0 +1,63 @@
|
||||||
|
#ifndef _ASM_X86_PAGE_DEFS_H
|
||||||
|
#define _ASM_X86_PAGE_DEFS_H
|
||||||
|
|
||||||
|
#include <linux/const.h>
|
||||||
|
|
||||||
|
/* PAGE_SHIFT determines the page size */
|
||||||
|
#define PAGE_SHIFT 12
|
||||||
|
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
|
||||||
|
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||||
|
|
||||||
|
#define __PHYSICAL_MASK ((phys_addr_t)(1ULL << __PHYSICAL_MASK_SHIFT) - 1)
|
||||||
|
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
|
||||||
|
|
||||||
|
/* Cast PAGE_MASK to a signed type so that it is sign-extended if
|
||||||
|
virtual addresses are 32-bits but physical addresses are larger
|
||||||
|
(ie, 32-bit PAE). */
|
||||||
|
#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
|
||||||
|
|
||||||
|
/* PTE_PFN_MASK extracts the PFN from a (pte|pmd|pud|pgd)val_t */
|
||||||
|
#define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK)
|
||||||
|
|
||||||
|
/* PTE_FLAGS_MASK extracts the flags from a (pte|pmd|pud|pgd)val_t */
|
||||||
|
#define PTE_FLAGS_MASK (~PTE_PFN_MASK)
|
||||||
|
|
||||||
|
#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
|
||||||
|
#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
|
||||||
|
|
||||||
|
#define HPAGE_SHIFT PMD_SHIFT
|
||||||
|
#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
|
||||||
|
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
|
||||||
|
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
|
||||||
|
|
||||||
|
#define HUGE_MAX_HSTATE 2
|
||||||
|
|
||||||
|
#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
|
||||||
|
|
||||||
|
#define VM_DATA_DEFAULT_FLAGS \
|
||||||
|
(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
|
||||||
|
VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
#include <asm/page_64_types.h>
|
||||||
|
#else
|
||||||
|
#include <asm/page_32_types.h>
|
||||||
|
#endif /* CONFIG_X86_64 */
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
struct pgprot;
|
||||||
|
|
||||||
|
extern int page_is_ram(unsigned long pagenr);
|
||||||
|
extern int devmem_is_allowed(unsigned long pagenr);
|
||||||
|
extern void map_devmem(unsigned long pfn, unsigned long size,
|
||||||
|
struct pgprot vma_prot);
|
||||||
|
extern void unmap_devmem(unsigned long pfn, unsigned long size,
|
||||||
|
struct pgprot vma_prot);
|
||||||
|
|
||||||
|
extern unsigned long max_low_pfn_mapped;
|
||||||
|
extern unsigned long max_pfn_mapped;
|
||||||
|
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_PAGE_DEFS_H */
|
|
@ -4,7 +4,7 @@
|
||||||
* para-virtualization: those hooks are defined here. */
|
* para-virtualization: those hooks are defined here. */
|
||||||
|
|
||||||
#ifdef CONFIG_PARAVIRT
|
#ifdef CONFIG_PARAVIRT
|
||||||
#include <asm/page.h>
|
#include <asm/pgtable_types.h>
|
||||||
#include <asm/asm.h>
|
#include <asm/asm.h>
|
||||||
|
|
||||||
/* Bitmask of what can be clobbered: usually at least eax. */
|
/* Bitmask of what can be clobbered: usually at least eax. */
|
||||||
|
|
|
@ -1,6 +1,21 @@
|
||||||
#ifndef _ASM_X86_PGTABLE_2LEVEL_DEFS_H
|
#ifndef _ASM_X86_PGTABLE_2LEVEL_DEFS_H
|
||||||
#define _ASM_X86_PGTABLE_2LEVEL_DEFS_H
|
#define _ASM_X86_PGTABLE_2LEVEL_DEFS_H
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
typedef unsigned long pteval_t;
|
||||||
|
typedef unsigned long pmdval_t;
|
||||||
|
typedef unsigned long pudval_t;
|
||||||
|
typedef unsigned long pgdval_t;
|
||||||
|
typedef unsigned long pgprotval_t;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
pteval_t pte;
|
||||||
|
pteval_t pte_low;
|
||||||
|
} pte_t;
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
#define SHARED_KERNEL_PMD 0
|
#define SHARED_KERNEL_PMD 0
|
||||||
|
|
||||||
/*
|
/*
|
|
@ -1,6 +1,23 @@
|
||||||
#ifndef _ASM_X86_PGTABLE_3LEVEL_DEFS_H
|
#ifndef _ASM_X86_PGTABLE_3LEVEL_DEFS_H
|
||||||
#define _ASM_X86_PGTABLE_3LEVEL_DEFS_H
|
#define _ASM_X86_PGTABLE_3LEVEL_DEFS_H
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
typedef u64 pteval_t;
|
||||||
|
typedef u64 pmdval_t;
|
||||||
|
typedef u64 pudval_t;
|
||||||
|
typedef u64 pgdval_t;
|
||||||
|
typedef u64 pgprotval_t;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
unsigned long pte_low, pte_high;
|
||||||
|
};
|
||||||
|
pteval_t pte;
|
||||||
|
} pte_t;
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
#ifdef CONFIG_PARAVIRT
|
#ifdef CONFIG_PARAVIRT
|
||||||
#define SHARED_KERNEL_PMD (pv_info.shared_kernel_pmd)
|
#define SHARED_KERNEL_PMD (pv_info.shared_kernel_pmd)
|
||||||
#else
|
#else
|
||||||
|
@ -25,4 +42,5 @@
|
||||||
*/
|
*/
|
||||||
#define PTRS_PER_PTE 512
|
#define PTRS_PER_PTE 512
|
||||||
|
|
||||||
|
|
||||||
#endif /* _ASM_X86_PGTABLE_3LEVEL_DEFS_H */
|
#endif /* _ASM_X86_PGTABLE_3LEVEL_DEFS_H */
|
|
@ -3,164 +3,7 @@
|
||||||
|
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
|
|
||||||
#define FIRST_USER_ADDRESS 0
|
#include <asm/pgtable_types.h>
|
||||||
|
|
||||||
#define _PAGE_BIT_PRESENT 0 /* is present */
|
|
||||||
#define _PAGE_BIT_RW 1 /* writeable */
|
|
||||||
#define _PAGE_BIT_USER 2 /* userspace addressable */
|
|
||||||
#define _PAGE_BIT_PWT 3 /* page write through */
|
|
||||||
#define _PAGE_BIT_PCD 4 /* page cache disabled */
|
|
||||||
#define _PAGE_BIT_ACCESSED 5 /* was accessed (raised by CPU) */
|
|
||||||
#define _PAGE_BIT_DIRTY 6 /* was written to (raised by CPU) */
|
|
||||||
#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
|
|
||||||
#define _PAGE_BIT_PAT 7 /* on 4KB pages */
|
|
||||||
#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
|
|
||||||
#define _PAGE_BIT_UNUSED1 9 /* available for programmer */
|
|
||||||
#define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */
|
|
||||||
#define _PAGE_BIT_UNUSED3 11
|
|
||||||
#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
|
|
||||||
#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1
|
|
||||||
#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1
|
|
||||||
#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
|
|
||||||
|
|
||||||
/* If _PAGE_BIT_PRESENT is clear, we use these: */
|
|
||||||
/* - if the user mapped it with PROT_NONE; pte_present gives true */
|
|
||||||
#define _PAGE_BIT_PROTNONE _PAGE_BIT_GLOBAL
|
|
||||||
/* - set: nonlinear file mapping, saved PTE; unset:swap */
|
|
||||||
#define _PAGE_BIT_FILE _PAGE_BIT_DIRTY
|
|
||||||
|
|
||||||
#define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)
|
|
||||||
#define _PAGE_RW (_AT(pteval_t, 1) << _PAGE_BIT_RW)
|
|
||||||
#define _PAGE_USER (_AT(pteval_t, 1) << _PAGE_BIT_USER)
|
|
||||||
#define _PAGE_PWT (_AT(pteval_t, 1) << _PAGE_BIT_PWT)
|
|
||||||
#define _PAGE_PCD (_AT(pteval_t, 1) << _PAGE_BIT_PCD)
|
|
||||||
#define _PAGE_ACCESSED (_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED)
|
|
||||||
#define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
|
|
||||||
#define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
|
|
||||||
#define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
|
|
||||||
#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
|
|
||||||
#define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
|
|
||||||
#define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
|
|
||||||
#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
|
|
||||||
#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
|
|
||||||
#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
|
|
||||||
#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
|
|
||||||
#define __HAVE_ARCH_PTE_SPECIAL
|
|
||||||
|
|
||||||
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
|
|
||||||
#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
|
|
||||||
#else
|
|
||||||
#define _PAGE_NX (_AT(pteval_t, 0))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE)
|
|
||||||
#define _PAGE_PROTNONE (_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE)
|
|
||||||
|
|
||||||
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
|
|
||||||
_PAGE_ACCESSED | _PAGE_DIRTY)
|
|
||||||
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \
|
|
||||||
_PAGE_DIRTY)
|
|
||||||
|
|
||||||
/* Set of bits not changed in pte_modify */
|
|
||||||
#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
|
|
||||||
_PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY)
|
|
||||||
|
|
||||||
#define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT)
|
|
||||||
#define _PAGE_CACHE_WB (0)
|
|
||||||
#define _PAGE_CACHE_WC (_PAGE_PWT)
|
|
||||||
#define _PAGE_CACHE_UC_MINUS (_PAGE_PCD)
|
|
||||||
#define _PAGE_CACHE_UC (_PAGE_PCD | _PAGE_PWT)
|
|
||||||
|
|
||||||
#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
|
|
||||||
#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
|
|
||||||
_PAGE_ACCESSED | _PAGE_NX)
|
|
||||||
|
|
||||||
#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | \
|
|
||||||
_PAGE_USER | _PAGE_ACCESSED)
|
|
||||||
#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
|
|
||||||
_PAGE_ACCESSED | _PAGE_NX)
|
|
||||||
#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
|
|
||||||
_PAGE_ACCESSED)
|
|
||||||
#define PAGE_COPY PAGE_COPY_NOEXEC
|
|
||||||
#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | \
|
|
||||||
_PAGE_ACCESSED | _PAGE_NX)
|
|
||||||
#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
|
|
||||||
_PAGE_ACCESSED)
|
|
||||||
|
|
||||||
#define __PAGE_KERNEL_EXEC \
|
|
||||||
(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
|
|
||||||
#define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
|
|
||||||
|
|
||||||
#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW)
|
|
||||||
#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
|
|
||||||
#define __PAGE_KERNEL_EXEC_NOCACHE (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT)
|
|
||||||
#define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC)
|
|
||||||
#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
|
|
||||||
#define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
|
|
||||||
#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
|
|
||||||
#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
|
|
||||||
#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
|
|
||||||
#define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
|
|
||||||
#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
|
|
||||||
|
|
||||||
#define __PAGE_KERNEL_IO (__PAGE_KERNEL | _PAGE_IOMAP)
|
|
||||||
#define __PAGE_KERNEL_IO_NOCACHE (__PAGE_KERNEL_NOCACHE | _PAGE_IOMAP)
|
|
||||||
#define __PAGE_KERNEL_IO_UC_MINUS (__PAGE_KERNEL_UC_MINUS | _PAGE_IOMAP)
|
|
||||||
#define __PAGE_KERNEL_IO_WC (__PAGE_KERNEL_WC | _PAGE_IOMAP)
|
|
||||||
|
|
||||||
#define PAGE_KERNEL __pgprot(__PAGE_KERNEL)
|
|
||||||
#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO)
|
|
||||||
#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC)
|
|
||||||
#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX)
|
|
||||||
#define PAGE_KERNEL_WC __pgprot(__PAGE_KERNEL_WC)
|
|
||||||
#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE)
|
|
||||||
#define PAGE_KERNEL_UC_MINUS __pgprot(__PAGE_KERNEL_UC_MINUS)
|
|
||||||
#define PAGE_KERNEL_EXEC_NOCACHE __pgprot(__PAGE_KERNEL_EXEC_NOCACHE)
|
|
||||||
#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE)
|
|
||||||
#define PAGE_KERNEL_LARGE_NOCACHE __pgprot(__PAGE_KERNEL_LARGE_NOCACHE)
|
|
||||||
#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC)
|
|
||||||
#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL)
|
|
||||||
#define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE)
|
|
||||||
|
|
||||||
#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO)
|
|
||||||
#define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE)
|
|
||||||
#define PAGE_KERNEL_IO_UC_MINUS __pgprot(__PAGE_KERNEL_IO_UC_MINUS)
|
|
||||||
#define PAGE_KERNEL_IO_WC __pgprot(__PAGE_KERNEL_IO_WC)
|
|
||||||
|
|
||||||
/* xwr */
|
|
||||||
#define __P000 PAGE_NONE
|
|
||||||
#define __P001 PAGE_READONLY
|
|
||||||
#define __P010 PAGE_COPY
|
|
||||||
#define __P011 PAGE_COPY
|
|
||||||
#define __P100 PAGE_READONLY_EXEC
|
|
||||||
#define __P101 PAGE_READONLY_EXEC
|
|
||||||
#define __P110 PAGE_COPY_EXEC
|
|
||||||
#define __P111 PAGE_COPY_EXEC
|
|
||||||
|
|
||||||
#define __S000 PAGE_NONE
|
|
||||||
#define __S001 PAGE_READONLY
|
|
||||||
#define __S010 PAGE_SHARED
|
|
||||||
#define __S011 PAGE_SHARED
|
|
||||||
#define __S100 PAGE_READONLY_EXEC
|
|
||||||
#define __S101 PAGE_READONLY_EXEC
|
|
||||||
#define __S110 PAGE_SHARED_EXEC
|
|
||||||
#define __S111 PAGE_SHARED_EXEC
|
|
||||||
|
|
||||||
/*
|
|
||||||
* early identity mapping pte attrib macros.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
#define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection
|
|
||||||
* bits are combined, this will alow user to access the high address mapped
|
|
||||||
* VDSO in the presence of CONFIG_COMPAT_VDSO
|
|
||||||
*/
|
|
||||||
#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
|
|
||||||
#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
|
|
||||||
#define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro to mark a page protection value as UC-
|
* Macro to mark a page protection value as UC-
|
||||||
|
@ -172,9 +15,6 @@
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#define pgprot_writecombine pgprot_writecombine
|
|
||||||
extern pgprot_t pgprot_writecombine(pgprot_t prot);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ZERO_PAGE is a global shared page that is always zero: used
|
* ZERO_PAGE is a global shared page that is always zero: used
|
||||||
* for zero-mapped memory areas etc..
|
* for zero-mapped memory areas etc..
|
||||||
|
@ -185,6 +25,66 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
|
||||||
extern spinlock_t pgd_lock;
|
extern spinlock_t pgd_lock;
|
||||||
extern struct list_head pgd_list;
|
extern struct list_head pgd_list;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PARAVIRT
|
||||||
|
#include <asm/paravirt.h>
|
||||||
|
#else /* !CONFIG_PARAVIRT */
|
||||||
|
#define set_pte(ptep, pte) native_set_pte(ptep, pte)
|
||||||
|
#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte)
|
||||||
|
|
||||||
|
#define set_pte_present(mm, addr, ptep, pte) \
|
||||||
|
native_set_pte_present(mm, addr, ptep, pte)
|
||||||
|
#define set_pte_atomic(ptep, pte) \
|
||||||
|
native_set_pte_atomic(ptep, pte)
|
||||||
|
|
||||||
|
#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd)
|
||||||
|
|
||||||
|
#ifndef __PAGETABLE_PUD_FOLDED
|
||||||
|
#define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd)
|
||||||
|
#define pgd_clear(pgd) native_pgd_clear(pgd)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef set_pud
|
||||||
|
# define set_pud(pudp, pud) native_set_pud(pudp, pud)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __PAGETABLE_PMD_FOLDED
|
||||||
|
#define pud_clear(pud) native_pud_clear(pud)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep)
|
||||||
|
#define pmd_clear(pmd) native_pmd_clear(pmd)
|
||||||
|
|
||||||
|
#define pte_update(mm, addr, ptep) do { } while (0)
|
||||||
|
#define pte_update_defer(mm, addr, ptep) do { } while (0)
|
||||||
|
|
||||||
|
static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
|
||||||
|
{
|
||||||
|
native_pagetable_setup_start(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
|
||||||
|
{
|
||||||
|
native_pagetable_setup_done(base);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pgd_val(x) native_pgd_val(x)
|
||||||
|
#define __pgd(x) native_make_pgd(x)
|
||||||
|
|
||||||
|
#ifndef __PAGETABLE_PUD_FOLDED
|
||||||
|
#define pud_val(x) native_pud_val(x)
|
||||||
|
#define __pud(x) native_make_pud(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __PAGETABLE_PMD_FOLDED
|
||||||
|
#define pmd_val(x) native_pmd_val(x)
|
||||||
|
#define __pmd(x) native_make_pmd(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define pte_val(x) native_pte_val(x)
|
||||||
|
#define __pte(x) native_make_pte(x)
|
||||||
|
|
||||||
|
#endif /* CONFIG_PARAVIRT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following only work if pte_present() is true.
|
* The following only work if pte_present() is true.
|
||||||
* Undefined behaviour if not..
|
* Undefined behaviour if not..
|
||||||
|
@ -316,8 +216,6 @@ static inline pte_t pte_mkspecial(pte_t pte)
|
||||||
return pte_set_flags(pte, _PAGE_SPECIAL);
|
return pte_set_flags(pte, _PAGE_SPECIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern pteval_t __supported_pte_mask;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mask out unsupported bits in a present pgprot. Non-present pgprots
|
* Mask out unsupported bits in a present pgprot. Non-present pgprots
|
||||||
* can use those bits for other purposes, so leave them be.
|
* can use those bits for other purposes, so leave them be.
|
||||||
|
@ -390,75 +288,6 @@ static inline int is_new_memtype_allowed(unsigned long flags,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
/* Indicate that x86 has its own track and untrack pfn vma functions */
|
|
||||||
#define __HAVE_PFNMAP_TRACKING
|
|
||||||
|
|
||||||
#define __HAVE_PHYS_MEM_ACCESS_PROT
|
|
||||||
struct file;
|
|
||||||
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
|
||||||
unsigned long size, pgprot_t vma_prot);
|
|
||||||
int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
|
|
||||||
unsigned long size, pgprot_t *vma_prot);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Install a pte for a particular vaddr in kernel space. */
|
|
||||||
void set_pte_vaddr(unsigned long vaddr, pte_t pte);
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
extern void native_pagetable_setup_start(pgd_t *base);
|
|
||||||
extern void native_pagetable_setup_done(pgd_t *base);
|
|
||||||
#else
|
|
||||||
static inline void native_pagetable_setup_start(pgd_t *base) {}
|
|
||||||
static inline void native_pagetable_setup_done(pgd_t *base) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct seq_file;
|
|
||||||
extern void arch_report_meminfo(struct seq_file *m);
|
|
||||||
|
|
||||||
#ifdef CONFIG_PARAVIRT
|
|
||||||
#include <asm/paravirt.h>
|
|
||||||
#else /* !CONFIG_PARAVIRT */
|
|
||||||
#define set_pte(ptep, pte) native_set_pte(ptep, pte)
|
|
||||||
#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte)
|
|
||||||
|
|
||||||
#define set_pte_present(mm, addr, ptep, pte) \
|
|
||||||
native_set_pte_present(mm, addr, ptep, pte)
|
|
||||||
#define set_pte_atomic(ptep, pte) \
|
|
||||||
native_set_pte_atomic(ptep, pte)
|
|
||||||
|
|
||||||
#define set_pmd(pmdp, pmd) native_set_pmd(pmdp, pmd)
|
|
||||||
|
|
||||||
#ifndef __PAGETABLE_PUD_FOLDED
|
|
||||||
#define set_pgd(pgdp, pgd) native_set_pgd(pgdp, pgd)
|
|
||||||
#define pgd_clear(pgd) native_pgd_clear(pgd)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef set_pud
|
|
||||||
# define set_pud(pudp, pud) native_set_pud(pudp, pud)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __PAGETABLE_PMD_FOLDED
|
|
||||||
#define pud_clear(pud) native_pud_clear(pud)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep)
|
|
||||||
#define pmd_clear(pmd) native_pmd_clear(pmd)
|
|
||||||
|
|
||||||
#define pte_update(mm, addr, ptep) do { } while (0)
|
|
||||||
#define pte_update_defer(mm, addr, ptep) do { } while (0)
|
|
||||||
|
|
||||||
static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
|
|
||||||
{
|
|
||||||
native_pagetable_setup_start(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
|
|
||||||
{
|
|
||||||
native_pagetable_setup_done(base);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_PARAVIRT */
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
|
@ -558,13 +387,6 @@ static inline unsigned long pages_to_mb(unsigned long npg)
|
||||||
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
|
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
|
||||||
remap_pfn_range(vma, vaddr, pfn, size, prot)
|
remap_pfn_range(vma, vaddr, pfn, size, prot)
|
||||||
|
|
||||||
#if PAGETABLE_LEVELS == 2
|
|
||||||
static inline int pud_large(pud_t pud)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PAGETABLE_LEVELS > 2
|
#if PAGETABLE_LEVELS > 2
|
||||||
static inline int pud_none(pud_t pud)
|
static inline int pud_none(pud_t pud)
|
||||||
{
|
{
|
||||||
|
@ -600,7 +422,7 @@ static inline unsigned long pmd_pfn(pmd_t pmd)
|
||||||
|
|
||||||
static inline int pud_large(pud_t pud)
|
static inline int pud_large(pud_t pud)
|
||||||
{
|
{
|
||||||
return (pud_flags(pud) & (_PAGE_PSE | _PAGE_PRESENT)) ==
|
return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) ==
|
||||||
(_PAGE_PSE | _PAGE_PRESENT);
|
(_PAGE_PSE | _PAGE_PRESENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,6 +430,11 @@ static inline int pud_bad(pud_t pud)
|
||||||
{
|
{
|
||||||
return (pud_flags(pud) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
|
return (pud_flags(pud) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static inline int pud_large(pud_t pud)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /* PAGETABLE_LEVELS > 2 */
|
#endif /* PAGETABLE_LEVELS > 2 */
|
||||||
|
|
||||||
#if PAGETABLE_LEVELS > 3
|
#if PAGETABLE_LEVELS > 3
|
||||||
|
@ -676,28 +503,6 @@ static inline int pgd_none(pgd_t pgd)
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
enum {
|
|
||||||
PG_LEVEL_NONE,
|
|
||||||
PG_LEVEL_4K,
|
|
||||||
PG_LEVEL_2M,
|
|
||||||
PG_LEVEL_1G,
|
|
||||||
PG_LEVEL_NUM
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
|
||||||
extern void update_page_count(int level, unsigned long pages);
|
|
||||||
#else
|
|
||||||
static inline void update_page_count(int level, unsigned long pages) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper function that returns the kernel pagetable entry controlling
|
|
||||||
* the virtual address 'address'. NULL means no pagetable entry present.
|
|
||||||
* NOTE: the return type is pte_t but if the pmd is PSE then we return it
|
|
||||||
* as a pte too.
|
|
||||||
*/
|
|
||||||
extern pte_t *lookup_address(unsigned long address, unsigned int *level);
|
|
||||||
|
|
||||||
/* local pte updates need not use xchg for locking */
|
/* local pte updates need not use xchg for locking */
|
||||||
static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep)
|
static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef _ASM_X86_PGTABLE_32_H
|
#ifndef _ASM_X86_PGTABLE_32_H
|
||||||
#define _ASM_X86_PGTABLE_32_H
|
#define _ASM_X86_PGTABLE_32_H
|
||||||
|
|
||||||
|
#include <asm/pgtable_32_types.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Linux memory management assumes a three-level page table setup. On
|
* The Linux memory management assumes a three-level page table setup. On
|
||||||
|
@ -33,47 +34,6 @@ void paging_init(void);
|
||||||
|
|
||||||
extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
|
extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
|
||||||
|
|
||||||
/*
|
|
||||||
* The Linux x86 paging architecture is 'compile-time dual-mode', it
|
|
||||||
* implements both the traditional 2-level x86 page tables and the
|
|
||||||
* newer 3-level PAE-mode page tables.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_X86_PAE
|
|
||||||
# include <asm/pgtable-3level-defs.h>
|
|
||||||
# define PMD_SIZE (1UL << PMD_SHIFT)
|
|
||||||
# define PMD_MASK (~(PMD_SIZE - 1))
|
|
||||||
#else
|
|
||||||
# include <asm/pgtable-2level-defs.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
|
||||||
#define PGDIR_MASK (~(PGDIR_SIZE - 1))
|
|
||||||
|
|
||||||
/* Just any arbitrary offset to the start of the vmalloc VM area: the
|
|
||||||
* current 8MB value just means that there will be a 8MB "hole" after the
|
|
||||||
* physical memory until the kernel virtual memory starts. That means that
|
|
||||||
* any out-of-bounds memory accesses will hopefully be caught.
|
|
||||||
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
|
|
||||||
* area for the same reason. ;)
|
|
||||||
*/
|
|
||||||
#define VMALLOC_OFFSET (8 * 1024 * 1024)
|
|
||||||
#define VMALLOC_START ((unsigned long)high_memory + VMALLOC_OFFSET)
|
|
||||||
#ifdef CONFIG_X86_PAE
|
|
||||||
#define LAST_PKMAP 512
|
|
||||||
#else
|
|
||||||
#define LAST_PKMAP 1024
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE * (LAST_PKMAP + 1)) \
|
|
||||||
& PMD_MASK)
|
|
||||||
|
|
||||||
#ifdef CONFIG_HIGHMEM
|
|
||||||
# define VMALLOC_END (PKMAP_BASE - 2 * PAGE_SIZE)
|
|
||||||
#else
|
|
||||||
# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAXMEM (VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define this if things work differently on an i386 and an i486:
|
* Define this if things work differently on an i386 and an i486:
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef _ASM_X86_PGTABLE_32_DEFS_H
|
||||||
|
#define _ASM_X86_PGTABLE_32_DEFS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Linux x86 paging architecture is 'compile-time dual-mode', it
|
||||||
|
* implements both the traditional 2-level x86 page tables and the
|
||||||
|
* newer 3-level PAE-mode page tables.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_X86_PAE
|
||||||
|
# include <asm/pgtable-3level_types.h>
|
||||||
|
# define PMD_SIZE (1UL << PMD_SHIFT)
|
||||||
|
# define PMD_MASK (~(PMD_SIZE - 1))
|
||||||
|
#else
|
||||||
|
# include <asm/pgtable-2level_types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
||||||
|
#define PGDIR_MASK (~(PGDIR_SIZE - 1))
|
||||||
|
|
||||||
|
/* Just any arbitrary offset to the start of the vmalloc VM area: the
|
||||||
|
* current 8MB value just means that there will be a 8MB "hole" after the
|
||||||
|
* physical memory until the kernel virtual memory starts. That means that
|
||||||
|
* any out-of-bounds memory accesses will hopefully be caught.
|
||||||
|
* The vmalloc() routines leaves a hole of 4kB between each vmalloced
|
||||||
|
* area for the same reason. ;)
|
||||||
|
*/
|
||||||
|
#define VMALLOC_OFFSET (8 * 1024 * 1024)
|
||||||
|
#define VMALLOC_START ((unsigned long)high_memory + VMALLOC_OFFSET)
|
||||||
|
#ifdef CONFIG_X86_PAE
|
||||||
|
#define LAST_PKMAP 512
|
||||||
|
#else
|
||||||
|
#define LAST_PKMAP 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE * (LAST_PKMAP + 1)) \
|
||||||
|
& PMD_MASK)
|
||||||
|
|
||||||
|
#ifdef CONFIG_HIGHMEM
|
||||||
|
# define VMALLOC_END (PKMAP_BASE - 2 * PAGE_SIZE)
|
||||||
|
#else
|
||||||
|
# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAXMEM (VMALLOC_END - PAGE_OFFSET - __VMALLOC_RESERVE)
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_PGTABLE_32_DEFS_H */
|
|
@ -2,6 +2,8 @@
|
||||||
#define _ASM_X86_PGTABLE_64_H
|
#define _ASM_X86_PGTABLE_64_H
|
||||||
|
|
||||||
#include <linux/const.h>
|
#include <linux/const.h>
|
||||||
|
#include <asm/pgtable_64_types.h>
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -25,32 +27,6 @@ extern void paging_init(void);
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
#define SHARED_KERNEL_PMD 0
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PGDIR_SHIFT determines what a top-level page table entry can map
|
|
||||||
*/
|
|
||||||
#define PGDIR_SHIFT 39
|
|
||||||
#define PTRS_PER_PGD 512
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 3rd level page
|
|
||||||
*/
|
|
||||||
#define PUD_SHIFT 30
|
|
||||||
#define PTRS_PER_PUD 512
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PMD_SHIFT determines the size of the area a middle-level
|
|
||||||
* page table can map
|
|
||||||
*/
|
|
||||||
#define PMD_SHIFT 21
|
|
||||||
#define PTRS_PER_PMD 512
|
|
||||||
|
|
||||||
/*
|
|
||||||
* entries per page directory level
|
|
||||||
*/
|
|
||||||
#define PTRS_PER_PTE 512
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#define pte_ERROR(e) \
|
#define pte_ERROR(e) \
|
||||||
|
@ -130,26 +106,6 @@ static inline void native_pgd_clear(pgd_t *pgd)
|
||||||
native_set_pgd(pgd, native_make_pgd(0));
|
native_set_pgd(pgd, native_make_pgd(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
|
||||||
|
|
||||||
#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
|
|
||||||
#define PMD_MASK (~(PMD_SIZE - 1))
|
|
||||||
#define PUD_SIZE (_AC(1, UL) << PUD_SHIFT)
|
|
||||||
#define PUD_MASK (~(PUD_SIZE - 1))
|
|
||||||
#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
|
|
||||||
#define PGDIR_MASK (~(PGDIR_SIZE - 1))
|
|
||||||
|
|
||||||
|
|
||||||
#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL)
|
|
||||||
#define VMALLOC_START _AC(0xffffc20000000000, UL)
|
|
||||||
#define VMALLOC_END _AC(0xffffe1ffffffffff, UL)
|
|
||||||
#define VMEMMAP_START _AC(0xffffe20000000000, UL)
|
|
||||||
#define MODULES_VADDR _AC(0xffffffffa0000000, UL)
|
|
||||||
#define MODULES_END _AC(0xffffffffff000000, UL)
|
|
||||||
#define MODULES_LEN (MODULES_END - MODULES_VADDR)
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Conversion functions: convert a page and protection to a page entry,
|
* Conversion functions: convert a page and protection to a page entry,
|
||||||
* and a page entry and page directory to the page they refer to.
|
* and a page entry and page directory to the page they refer to.
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef _ASM_X86_PGTABLE_64_DEFS_H
|
||||||
|
#define _ASM_X86_PGTABLE_64_DEFS_H
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are used to make use of C type-checking..
|
||||||
|
*/
|
||||||
|
typedef unsigned long pteval_t;
|
||||||
|
typedef unsigned long pmdval_t;
|
||||||
|
typedef unsigned long pudval_t;
|
||||||
|
typedef unsigned long pgdval_t;
|
||||||
|
typedef unsigned long pgprotval_t;
|
||||||
|
|
||||||
|
typedef struct { pteval_t pte; } pte_t;
|
||||||
|
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
#define SHARED_KERNEL_PMD 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PGDIR_SHIFT determines what a top-level page table entry can map
|
||||||
|
*/
|
||||||
|
#define PGDIR_SHIFT 39
|
||||||
|
#define PTRS_PER_PGD 512
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 3rd level page
|
||||||
|
*/
|
||||||
|
#define PUD_SHIFT 30
|
||||||
|
#define PTRS_PER_PUD 512
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PMD_SHIFT determines the size of the area a middle-level
|
||||||
|
* page table can map
|
||||||
|
*/
|
||||||
|
#define PMD_SHIFT 21
|
||||||
|
#define PTRS_PER_PMD 512
|
||||||
|
|
||||||
|
/*
|
||||||
|
* entries per page directory level
|
||||||
|
*/
|
||||||
|
#define PTRS_PER_PTE 512
|
||||||
|
|
||||||
|
#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
|
||||||
|
#define PMD_MASK (~(PMD_SIZE - 1))
|
||||||
|
#define PUD_SIZE (_AC(1, UL) << PUD_SHIFT)
|
||||||
|
#define PUD_MASK (~(PUD_SIZE - 1))
|
||||||
|
#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
|
||||||
|
#define PGDIR_MASK (~(PGDIR_SIZE - 1))
|
||||||
|
|
||||||
|
|
||||||
|
#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL)
|
||||||
|
#define VMALLOC_START _AC(0xffffc20000000000, UL)
|
||||||
|
#define VMALLOC_END _AC(0xffffe1ffffffffff, UL)
|
||||||
|
#define VMEMMAP_START _AC(0xffffe20000000000, UL)
|
||||||
|
#define MODULES_VADDR _AC(0xffffffffa0000000, UL)
|
||||||
|
#define MODULES_END _AC(0xffffffffff000000, UL)
|
||||||
|
#define MODULES_LEN (MODULES_END - MODULES_VADDR)
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_PGTABLE_64_DEFS_H */
|
|
@ -0,0 +1,322 @@
|
||||||
|
#ifndef _ASM_X86_PGTABLE_DEFS_H
|
||||||
|
#define _ASM_X86_PGTABLE_DEFS_H
|
||||||
|
|
||||||
|
#include <linux/const.h>
|
||||||
|
#include <asm/page_types.h>
|
||||||
|
|
||||||
|
#define FIRST_USER_ADDRESS 0
|
||||||
|
|
||||||
|
#define _PAGE_BIT_PRESENT 0 /* is present */
|
||||||
|
#define _PAGE_BIT_RW 1 /* writeable */
|
||||||
|
#define _PAGE_BIT_USER 2 /* userspace addressable */
|
||||||
|
#define _PAGE_BIT_PWT 3 /* page write through */
|
||||||
|
#define _PAGE_BIT_PCD 4 /* page cache disabled */
|
||||||
|
#define _PAGE_BIT_ACCESSED 5 /* was accessed (raised by CPU) */
|
||||||
|
#define _PAGE_BIT_DIRTY 6 /* was written to (raised by CPU) */
|
||||||
|
#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */
|
||||||
|
#define _PAGE_BIT_PAT 7 /* on 4KB pages */
|
||||||
|
#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */
|
||||||
|
#define _PAGE_BIT_UNUSED1 9 /* available for programmer */
|
||||||
|
#define _PAGE_BIT_IOMAP 10 /* flag used to indicate IO mapping */
|
||||||
|
#define _PAGE_BIT_UNUSED3 11
|
||||||
|
#define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */
|
||||||
|
#define _PAGE_BIT_SPECIAL _PAGE_BIT_UNUSED1
|
||||||
|
#define _PAGE_BIT_CPA_TEST _PAGE_BIT_UNUSED1
|
||||||
|
#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */
|
||||||
|
|
||||||
|
/* If _PAGE_BIT_PRESENT is clear, we use these: */
|
||||||
|
/* - if the user mapped it with PROT_NONE; pte_present gives true */
|
||||||
|
#define _PAGE_BIT_PROTNONE _PAGE_BIT_GLOBAL
|
||||||
|
/* - set: nonlinear file mapping, saved PTE; unset:swap */
|
||||||
|
#define _PAGE_BIT_FILE _PAGE_BIT_DIRTY
|
||||||
|
|
||||||
|
#define _PAGE_PRESENT (_AT(pteval_t, 1) << _PAGE_BIT_PRESENT)
|
||||||
|
#define _PAGE_RW (_AT(pteval_t, 1) << _PAGE_BIT_RW)
|
||||||
|
#define _PAGE_USER (_AT(pteval_t, 1) << _PAGE_BIT_USER)
|
||||||
|
#define _PAGE_PWT (_AT(pteval_t, 1) << _PAGE_BIT_PWT)
|
||||||
|
#define _PAGE_PCD (_AT(pteval_t, 1) << _PAGE_BIT_PCD)
|
||||||
|
#define _PAGE_ACCESSED (_AT(pteval_t, 1) << _PAGE_BIT_ACCESSED)
|
||||||
|
#define _PAGE_DIRTY (_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
|
||||||
|
#define _PAGE_PSE (_AT(pteval_t, 1) << _PAGE_BIT_PSE)
|
||||||
|
#define _PAGE_GLOBAL (_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
|
||||||
|
#define _PAGE_UNUSED1 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
|
||||||
|
#define _PAGE_IOMAP (_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
|
||||||
|
#define _PAGE_UNUSED3 (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
|
||||||
|
#define _PAGE_PAT (_AT(pteval_t, 1) << _PAGE_BIT_PAT)
|
||||||
|
#define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
|
||||||
|
#define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL)
|
||||||
|
#define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST)
|
||||||
|
#define __HAVE_ARCH_PTE_SPECIAL
|
||||||
|
|
||||||
|
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
|
||||||
|
#define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX)
|
||||||
|
#else
|
||||||
|
#define _PAGE_NX (_AT(pteval_t, 0))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _PAGE_FILE (_AT(pteval_t, 1) << _PAGE_BIT_FILE)
|
||||||
|
#define _PAGE_PROTNONE (_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE)
|
||||||
|
|
||||||
|
#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
|
||||||
|
_PAGE_ACCESSED | _PAGE_DIRTY)
|
||||||
|
#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \
|
||||||
|
_PAGE_DIRTY)
|
||||||
|
|
||||||
|
/* Set of bits not changed in pte_modify */
|
||||||
|
#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
|
||||||
|
_PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY)
|
||||||
|
|
||||||
|
#define _PAGE_CACHE_MASK (_PAGE_PCD | _PAGE_PWT)
|
||||||
|
#define _PAGE_CACHE_WB (0)
|
||||||
|
#define _PAGE_CACHE_WC (_PAGE_PWT)
|
||||||
|
#define _PAGE_CACHE_UC_MINUS (_PAGE_PCD)
|
||||||
|
#define _PAGE_CACHE_UC (_PAGE_PCD | _PAGE_PWT)
|
||||||
|
|
||||||
|
#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
|
||||||
|
#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
|
||||||
|
_PAGE_ACCESSED | _PAGE_NX)
|
||||||
|
|
||||||
|
#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | \
|
||||||
|
_PAGE_USER | _PAGE_ACCESSED)
|
||||||
|
#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
|
||||||
|
_PAGE_ACCESSED | _PAGE_NX)
|
||||||
|
#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
|
||||||
|
_PAGE_ACCESSED)
|
||||||
|
#define PAGE_COPY PAGE_COPY_NOEXEC
|
||||||
|
#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | \
|
||||||
|
_PAGE_ACCESSED | _PAGE_NX)
|
||||||
|
#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
|
||||||
|
_PAGE_ACCESSED)
|
||||||
|
|
||||||
|
#define __PAGE_KERNEL_EXEC \
|
||||||
|
(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
|
||||||
|
#define __PAGE_KERNEL (__PAGE_KERNEL_EXEC | _PAGE_NX)
|
||||||
|
|
||||||
|
#define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW)
|
||||||
|
#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
|
||||||
|
#define __PAGE_KERNEL_EXEC_NOCACHE (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT)
|
||||||
|
#define __PAGE_KERNEL_WC (__PAGE_KERNEL | _PAGE_CACHE_WC)
|
||||||
|
#define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
|
||||||
|
#define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
|
||||||
|
#define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
|
||||||
|
#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
|
||||||
|
#define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
|
||||||
|
#define __PAGE_KERNEL_LARGE_NOCACHE (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
|
||||||
|
#define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
|
||||||
|
|
||||||
|
#define __PAGE_KERNEL_IO (__PAGE_KERNEL | _PAGE_IOMAP)
|
||||||
|
#define __PAGE_KERNEL_IO_NOCACHE (__PAGE_KERNEL_NOCACHE | _PAGE_IOMAP)
|
||||||
|
#define __PAGE_KERNEL_IO_UC_MINUS (__PAGE_KERNEL_UC_MINUS | _PAGE_IOMAP)
|
||||||
|
#define __PAGE_KERNEL_IO_WC (__PAGE_KERNEL_WC | _PAGE_IOMAP)
|
||||||
|
|
||||||
|
#define PAGE_KERNEL __pgprot(__PAGE_KERNEL)
|
||||||
|
#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO)
|
||||||
|
#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC)
|
||||||
|
#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX)
|
||||||
|
#define PAGE_KERNEL_WC __pgprot(__PAGE_KERNEL_WC)
|
||||||
|
#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE)
|
||||||
|
#define PAGE_KERNEL_UC_MINUS __pgprot(__PAGE_KERNEL_UC_MINUS)
|
||||||
|
#define PAGE_KERNEL_EXEC_NOCACHE __pgprot(__PAGE_KERNEL_EXEC_NOCACHE)
|
||||||
|
#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE)
|
||||||
|
#define PAGE_KERNEL_LARGE_NOCACHE __pgprot(__PAGE_KERNEL_LARGE_NOCACHE)
|
||||||
|
#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC)
|
||||||
|
#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL)
|
||||||
|
#define PAGE_KERNEL_VSYSCALL_NOCACHE __pgprot(__PAGE_KERNEL_VSYSCALL_NOCACHE)
|
||||||
|
|
||||||
|
#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO)
|
||||||
|
#define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE)
|
||||||
|
#define PAGE_KERNEL_IO_UC_MINUS __pgprot(__PAGE_KERNEL_IO_UC_MINUS)
|
||||||
|
#define PAGE_KERNEL_IO_WC __pgprot(__PAGE_KERNEL_IO_WC)
|
||||||
|
|
||||||
|
/* xwr */
|
||||||
|
#define __P000 PAGE_NONE
|
||||||
|
#define __P001 PAGE_READONLY
|
||||||
|
#define __P010 PAGE_COPY
|
||||||
|
#define __P011 PAGE_COPY
|
||||||
|
#define __P100 PAGE_READONLY_EXEC
|
||||||
|
#define __P101 PAGE_READONLY_EXEC
|
||||||
|
#define __P110 PAGE_COPY_EXEC
|
||||||
|
#define __P111 PAGE_COPY_EXEC
|
||||||
|
|
||||||
|
#define __S000 PAGE_NONE
|
||||||
|
#define __S001 PAGE_READONLY
|
||||||
|
#define __S010 PAGE_SHARED
|
||||||
|
#define __S011 PAGE_SHARED
|
||||||
|
#define __S100 PAGE_READONLY_EXEC
|
||||||
|
#define __S101 PAGE_READONLY_EXEC
|
||||||
|
#define __S110 PAGE_SHARED_EXEC
|
||||||
|
#define __S111 PAGE_SHARED_EXEC
|
||||||
|
|
||||||
|
/*
|
||||||
|
* early identity mapping pte attrib macros.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
#define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection
|
||||||
|
* bits are combined, this will alow user to access the high address mapped
|
||||||
|
* VDSO in the presence of CONFIG_COMPAT_VDSO
|
||||||
|
*/
|
||||||
|
#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
|
||||||
|
#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
|
||||||
|
#define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
# include "pgtable_32_types.h"
|
||||||
|
#else
|
||||||
|
# include "pgtable_64_types.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
typedef struct pgprot { pgprotval_t pgprot; } pgprot_t;
|
||||||
|
|
||||||
|
typedef struct { pgdval_t pgd; } pgd_t;
|
||||||
|
|
||||||
|
static inline pgd_t native_make_pgd(pgdval_t val)
|
||||||
|
{
|
||||||
|
return (pgd_t) { val };
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pgdval_t native_pgd_val(pgd_t pgd)
|
||||||
|
{
|
||||||
|
return pgd.pgd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pgdval_t pgd_flags(pgd_t pgd)
|
||||||
|
{
|
||||||
|
return native_pgd_val(pgd) & PTE_FLAGS_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PAGETABLE_LEVELS > 3
|
||||||
|
typedef struct { pudval_t pud; } pud_t;
|
||||||
|
|
||||||
|
static inline pud_t native_make_pud(pmdval_t val)
|
||||||
|
{
|
||||||
|
return (pud_t) { val };
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pudval_t native_pud_val(pud_t pud)
|
||||||
|
{
|
||||||
|
return pud.pud;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#include <asm-generic/pgtable-nopud.h>
|
||||||
|
|
||||||
|
static inline pudval_t native_pud_val(pud_t pud)
|
||||||
|
{
|
||||||
|
return native_pgd_val(pud.pgd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PAGETABLE_LEVELS > 2
|
||||||
|
typedef struct { pmdval_t pmd; } pmd_t;
|
||||||
|
|
||||||
|
static inline pmd_t native_make_pmd(pmdval_t val)
|
||||||
|
{
|
||||||
|
return (pmd_t) { val };
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pmdval_t native_pmd_val(pmd_t pmd)
|
||||||
|
{
|
||||||
|
return pmd.pmd;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#include <asm-generic/pgtable-nopmd.h>
|
||||||
|
|
||||||
|
static inline pmdval_t native_pmd_val(pmd_t pmd)
|
||||||
|
{
|
||||||
|
return native_pgd_val(pmd.pud.pgd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline pudval_t pud_flags(pud_t pud)
|
||||||
|
{
|
||||||
|
return native_pud_val(pud) & PTE_FLAGS_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pmdval_t pmd_flags(pmd_t pmd)
|
||||||
|
{
|
||||||
|
return native_pmd_val(pmd) & PTE_FLAGS_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pte_t native_make_pte(pteval_t val)
|
||||||
|
{
|
||||||
|
return (pte_t) { .pte = val };
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pteval_t native_pte_val(pte_t pte)
|
||||||
|
{
|
||||||
|
return pte.pte;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline pteval_t pte_flags(pte_t pte)
|
||||||
|
{
|
||||||
|
return native_pte_val(pte) & PTE_FLAGS_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pgprot_val(x) ((x).pgprot)
|
||||||
|
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct page *pgtable_t;
|
||||||
|
|
||||||
|
extern pteval_t __supported_pte_mask;
|
||||||
|
extern int nx_enabled;
|
||||||
|
|
||||||
|
#define pgprot_writecombine pgprot_writecombine
|
||||||
|
extern pgprot_t pgprot_writecombine(pgprot_t prot);
|
||||||
|
|
||||||
|
/* Indicate that x86 has its own track and untrack pfn vma functions */
|
||||||
|
#define __HAVE_PFNMAP_TRACKING
|
||||||
|
|
||||||
|
#define __HAVE_PHYS_MEM_ACCESS_PROT
|
||||||
|
struct file;
|
||||||
|
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||||
|
unsigned long size, pgprot_t vma_prot);
|
||||||
|
int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
|
||||||
|
unsigned long size, pgprot_t *vma_prot);
|
||||||
|
|
||||||
|
/* Install a pte for a particular vaddr in kernel space. */
|
||||||
|
void set_pte_vaddr(unsigned long vaddr, pte_t pte);
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_32
|
||||||
|
extern void native_pagetable_setup_start(pgd_t *base);
|
||||||
|
extern void native_pagetable_setup_done(pgd_t *base);
|
||||||
|
#else
|
||||||
|
static inline void native_pagetable_setup_start(pgd_t *base) {}
|
||||||
|
static inline void native_pagetable_setup_done(pgd_t *base) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct seq_file;
|
||||||
|
extern void arch_report_meminfo(struct seq_file *m);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PG_LEVEL_NONE,
|
||||||
|
PG_LEVEL_4K,
|
||||||
|
PG_LEVEL_2M,
|
||||||
|
PG_LEVEL_1G,
|
||||||
|
PG_LEVEL_NUM
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_PROC_FS
|
||||||
|
extern void update_page_count(int level, unsigned long pages);
|
||||||
|
#else
|
||||||
|
static inline void update_page_count(int level, unsigned long pages) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function that returns the kernel pagetable entry controlling
|
||||||
|
* the virtual address 'address'. NULL means no pagetable entry present.
|
||||||
|
* NOTE: the return type is pte_t but if the pmd is PSE then we return it
|
||||||
|
* as a pte too.
|
||||||
|
*/
|
||||||
|
extern pte_t *lookup_address(unsigned long address, unsigned int *level);
|
||||||
|
|
||||||
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* _ASM_X86_PGTABLE_DEFS_H */
|
|
@ -16,6 +16,7 @@ struct mm_struct;
|
||||||
#include <asm/cpufeature.h>
|
#include <asm/cpufeature.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
|
#include <asm/pgtable_types.h>
|
||||||
#include <asm/percpu.h>
|
#include <asm/percpu.h>
|
||||||
#include <asm/msr.h>
|
#include <asm/msr.h>
|
||||||
#include <asm/desc_defs.h>
|
#include <asm/desc_defs.h>
|
||||||
|
|
|
@ -7,21 +7,6 @@
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
/* Interrupt control for vSMPowered x86_64 systems */
|
|
||||||
void vsmp_init(void);
|
|
||||||
|
|
||||||
void setup_bios_corruption_check(void);
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_VISWS
|
|
||||||
extern void visws_early_detect(void);
|
|
||||||
extern int is_visws_box(void);
|
|
||||||
#else
|
|
||||||
static inline void visws_early_detect(void) { }
|
|
||||||
static inline int is_visws_box(void) { return 0; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
|
|
||||||
extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip);
|
|
||||||
/*
|
/*
|
||||||
* Any setup quirks to be performed?
|
* Any setup quirks to be performed?
|
||||||
*/
|
*/
|
||||||
|
@ -45,15 +30,9 @@ struct x86_quirks {
|
||||||
void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable,
|
void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable,
|
||||||
unsigned short oemsize);
|
unsigned short oemsize);
|
||||||
int (*setup_ioapic_ids)(void);
|
int (*setup_ioapic_ids)(void);
|
||||||
int (*update_genapic)(void);
|
int (*update_apic)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct x86_quirks *x86_quirks;
|
|
||||||
extern unsigned long saved_video_mode;
|
|
||||||
|
|
||||||
#ifndef CONFIG_PARAVIRT
|
|
||||||
#define paravirt_post_allocator_init() do {} while (0)
|
|
||||||
#endif
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
|
@ -76,6 +55,28 @@ extern unsigned long saved_video_mode;
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
#include <asm/bootparam.h>
|
#include <asm/bootparam.h>
|
||||||
|
|
||||||
|
/* Interrupt control for vSMPowered x86_64 systems */
|
||||||
|
void vsmp_init(void);
|
||||||
|
|
||||||
|
void setup_bios_corruption_check(void);
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_VISWS
|
||||||
|
extern void visws_early_detect(void);
|
||||||
|
extern int is_visws_box(void);
|
||||||
|
#else
|
||||||
|
static inline void visws_early_detect(void) { }
|
||||||
|
static inline int is_visws_box(void) { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
|
||||||
|
extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip);
|
||||||
|
extern struct x86_quirks *x86_quirks;
|
||||||
|
extern unsigned long saved_video_mode;
|
||||||
|
|
||||||
|
#ifndef CONFIG_PARAVIRT
|
||||||
|
#define paravirt_post_allocator_init() do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef _SETUP
|
#ifndef _SETUP
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -74,6 +74,7 @@ asmlinkage long sys_vfork(struct pt_regs *);
|
||||||
asmlinkage long sys_execve(char __user *, char __user * __user *,
|
asmlinkage long sys_execve(char __user *, char __user * __user *,
|
||||||
char __user * __user *,
|
char __user * __user *,
|
||||||
struct pt_regs *);
|
struct pt_regs *);
|
||||||
|
long sys_arch_prctl(int, unsigned long);
|
||||||
|
|
||||||
/* kernel/ioport.c */
|
/* kernel/ioport.c */
|
||||||
asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
|
asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
|
||||||
|
|
|
@ -38,22 +38,30 @@ extern struct shared_info *HYPERVISOR_shared_info;
|
||||||
extern struct start_info *xen_start_info;
|
extern struct start_info *xen_start_info;
|
||||||
|
|
||||||
enum xen_domain_type {
|
enum xen_domain_type {
|
||||||
XEN_NATIVE,
|
XEN_NATIVE, /* running on bare hardware */
|
||||||
XEN_PV_DOMAIN,
|
XEN_PV_DOMAIN, /* running in a PV domain */
|
||||||
XEN_HVM_DOMAIN,
|
XEN_HVM_DOMAIN, /* running in a Xen hvm domain */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum xen_domain_type xen_domain_type;
|
|
||||||
|
|
||||||
#ifdef CONFIG_XEN
|
#ifdef CONFIG_XEN
|
||||||
#define xen_domain() (xen_domain_type != XEN_NATIVE)
|
extern enum xen_domain_type xen_domain_type;
|
||||||
#else
|
#else
|
||||||
#define xen_domain() (0)
|
#define xen_domain_type XEN_NATIVE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define xen_pv_domain() (xen_domain() && xen_domain_type == XEN_PV_DOMAIN)
|
#define xen_domain() (xen_domain_type != XEN_NATIVE)
|
||||||
#define xen_hvm_domain() (xen_domain() && xen_domain_type == XEN_HVM_DOMAIN)
|
#define xen_pv_domain() (xen_domain() && \
|
||||||
|
xen_domain_type == XEN_PV_DOMAIN)
|
||||||
|
#define xen_hvm_domain() (xen_domain() && \
|
||||||
|
xen_domain_type == XEN_HVM_DOMAIN)
|
||||||
|
|
||||||
#define xen_initial_domain() (xen_pv_domain() && xen_start_info->flags & SIF_INITDOMAIN)
|
#ifdef CONFIG_XEN_DOM0
|
||||||
|
#include <xen/interface/xen.h>
|
||||||
|
|
||||||
|
#define xen_initial_domain() (xen_pv_domain() && \
|
||||||
|
xen_start_info->flags & SIF_INITDOMAIN)
|
||||||
|
#else /* !CONFIG_XEN_DOM0 */
|
||||||
|
#define xen_initial_domain() (0)
|
||||||
|
#endif /* CONFIG_XEN_DOM0 */
|
||||||
|
|
||||||
#endif /* _ASM_X86_XEN_HYPERVISOR_H */
|
#endif /* _ASM_X86_XEN_HYPERVISOR_H */
|
||||||
|
|
|
@ -58,13 +58,12 @@ obj-$(CONFIG_PCI) += early-quirks.o
|
||||||
apm-y := apm_32.o
|
apm-y := apm_32.o
|
||||||
obj-$(CONFIG_APM) += apm.o
|
obj-$(CONFIG_APM) += apm.o
|
||||||
obj-$(CONFIG_SMP) += smp.o
|
obj-$(CONFIG_SMP) += smp.o
|
||||||
obj-$(CONFIG_SMP) += smpboot.o tsc_sync.o ipi.o
|
obj-$(CONFIG_SMP) += smpboot.o tsc_sync.o
|
||||||
obj-$(CONFIG_SMP) += setup_percpu.o
|
obj-$(CONFIG_SMP) += setup_percpu.o
|
||||||
obj-$(CONFIG_X86_64_SMP) += tsc_sync.o
|
obj-$(CONFIG_X86_64_SMP) += tsc_sync.o
|
||||||
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o
|
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o
|
||||||
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
|
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
|
||||||
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o ipi.o
|
obj-$(CONFIG_X86_LOCAL_APIC) += apic/
|
||||||
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
|
|
||||||
obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
|
obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
|
||||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
||||||
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
|
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
|
||||||
|
@ -116,17 +115,13 @@ obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64
|
||||||
###
|
###
|
||||||
# 64 bit specific files
|
# 64 bit specific files
|
||||||
ifeq ($(CONFIG_X86_64),y)
|
ifeq ($(CONFIG_X86_64),y)
|
||||||
obj-y += genapic_64.o genapic_flat_64.o
|
obj-$(CONFIG_X86_UV) += tlb_uv.o bios_uv.o uv_irq.o uv_sysfs.o
|
||||||
obj-y += genx2apic_cluster.o
|
obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
|
||||||
obj-y += genx2apic_phys.o
|
obj-$(CONFIG_AUDIT) += audit_64.o
|
||||||
obj-$(CONFIG_X86_UV) += genx2apic_uv_x.o tlb_uv.o
|
|
||||||
obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o
|
|
||||||
obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
|
|
||||||
obj-$(CONFIG_AUDIT) += audit_64.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o
|
obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o
|
||||||
obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o
|
obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o
|
||||||
obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o
|
obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o
|
||||||
|
|
||||||
obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o
|
obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/io_apic.h>
|
#include <asm/io_apic.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#
|
||||||
|
# Makefile for local APIC drivers and for the IO-APIC code
|
||||||
|
#
|
||||||
|
|
||||||
|
obj-y := apic.o ipi.o nmi.o
|
||||||
|
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
|
||||||
|
obj-$(CONFIG_SMP) += ipi.o
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_X86_64),y)
|
||||||
|
obj-y += apic_64.o apic_flat_64.o
|
||||||
|
obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o
|
||||||
|
obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o
|
||||||
|
obj-$(CONFIG_X86_UV) += x2apic_uv_x.o
|
||||||
|
endif
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include <asm/perf_counter.h>
|
#include <asm/perf_counter.h>
|
||||||
#include <asm/arch_hooks.h>
|
#include <asm/arch_hooks.h>
|
||||||
#include <asm/pgalloc.h>
|
#include <asm/pgalloc.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/i8253.h>
|
#include <asm/i8253.h>
|
||||||
|
@ -113,11 +112,7 @@ static __init int setup_apicpmtimer(char *s)
|
||||||
__setup("apicpmtimer", setup_apicpmtimer);
|
__setup("apicpmtimer", setup_apicpmtimer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_X2APIC
|
||||||
#define HAVE_X2APIC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
|
||||||
int x2apic;
|
int x2apic;
|
||||||
/* x2apic enabled before OS handover */
|
/* x2apic enabled before OS handover */
|
||||||
static int x2apic_preenabled;
|
static int x2apic_preenabled;
|
||||||
|
@ -215,18 +210,13 @@ static int modern_apic(void)
|
||||||
return lapic_get_version() >= 0x14;
|
return lapic_get_version() >= 0x14;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void native_apic_wait_icr_idle(void)
|
||||||
* Paravirt kernels also might be using these below ops. So we still
|
|
||||||
* use generic apic_read()/apic_write(), which might be pointing to different
|
|
||||||
* ops in PARAVIRT case.
|
|
||||||
*/
|
|
||||||
void xapic_wait_icr_idle(void)
|
|
||||||
{
|
{
|
||||||
while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
|
while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 safe_xapic_wait_icr_idle(void)
|
u32 native_safe_apic_wait_icr_idle(void)
|
||||||
{
|
{
|
||||||
u32 send_status;
|
u32 send_status;
|
||||||
int timeout;
|
int timeout;
|
||||||
|
@ -242,13 +232,13 @@ u32 safe_xapic_wait_icr_idle(void)
|
||||||
return send_status;
|
return send_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xapic_icr_write(u32 low, u32 id)
|
void native_apic_icr_write(u32 low, u32 id)
|
||||||
{
|
{
|
||||||
apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id));
|
apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id));
|
||||||
apic_write(APIC_ICR, low);
|
apic_write(APIC_ICR, low);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 xapic_icr_read(void)
|
u64 native_apic_icr_read(void)
|
||||||
{
|
{
|
||||||
u32 icr1, icr2;
|
u32 icr1, icr2;
|
||||||
|
|
||||||
|
@ -258,54 +248,6 @@ static u64 xapic_icr_read(void)
|
||||||
return icr1 | ((u64)icr2 << 32);
|
return icr1 | ((u64)icr2 << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct apic_ops xapic_ops = {
|
|
||||||
.read = native_apic_mem_read,
|
|
||||||
.write = native_apic_mem_write,
|
|
||||||
.icr_read = xapic_icr_read,
|
|
||||||
.icr_write = xapic_icr_write,
|
|
||||||
.wait_icr_idle = xapic_wait_icr_idle,
|
|
||||||
.safe_wait_icr_idle = safe_xapic_wait_icr_idle,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct apic_ops __read_mostly *apic_ops = &xapic_ops;
|
|
||||||
EXPORT_SYMBOL_GPL(apic_ops);
|
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
|
||||||
static void x2apic_wait_icr_idle(void)
|
|
||||||
{
|
|
||||||
/* no need to wait for icr idle in x2apic */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 safe_x2apic_wait_icr_idle(void)
|
|
||||||
{
|
|
||||||
/* no need to wait for icr idle in x2apic */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void x2apic_icr_write(u32 low, u32 id)
|
|
||||||
{
|
|
||||||
wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
|
|
||||||
}
|
|
||||||
|
|
||||||
static u64 x2apic_icr_read(void)
|
|
||||||
{
|
|
||||||
unsigned long val;
|
|
||||||
|
|
||||||
rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct apic_ops x2apic_ops = {
|
|
||||||
.read = native_apic_msr_read,
|
|
||||||
.write = native_apic_msr_write,
|
|
||||||
.icr_read = x2apic_icr_read,
|
|
||||||
.icr_write = x2apic_icr_write,
|
|
||||||
.wait_icr_idle = x2apic_wait_icr_idle,
|
|
||||||
.safe_wait_icr_idle = safe_x2apic_wait_icr_idle,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enable_NMI_through_LVT0 - enable NMI through local vector table 0
|
* enable_NMI_through_LVT0 - enable NMI through local vector table 0
|
||||||
*/
|
*/
|
||||||
|
@ -1324,17 +1266,19 @@ void __cpuinit end_local_APIC_setup(void)
|
||||||
apic_pm_activate();
|
apic_pm_activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
#ifdef CONFIG_X86_X2APIC
|
||||||
void check_x2apic(void)
|
void check_x2apic(void)
|
||||||
{
|
{
|
||||||
int msr, msr2;
|
int msr, msr2;
|
||||||
|
|
||||||
|
if (!cpu_has_x2apic)
|
||||||
|
return;
|
||||||
|
|
||||||
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
||||||
|
|
||||||
if (msr & X2APIC_ENABLE) {
|
if (msr & X2APIC_ENABLE) {
|
||||||
pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
|
pr_info("x2apic enabled by BIOS, switching to x2apic ops\n");
|
||||||
x2apic_preenabled = x2apic = 1;
|
x2apic_preenabled = x2apic = 1;
|
||||||
apic_ops = &x2apic_ops;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1342,6 +1286,9 @@ void enable_x2apic(void)
|
||||||
{
|
{
|
||||||
int msr, msr2;
|
int msr, msr2;
|
||||||
|
|
||||||
|
if (!x2apic)
|
||||||
|
return;
|
||||||
|
|
||||||
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
rdmsr(MSR_IA32_APICBASE, msr, msr2);
|
||||||
if (!(msr & X2APIC_ENABLE)) {
|
if (!(msr & X2APIC_ENABLE)) {
|
||||||
pr_info("Enabling x2apic\n");
|
pr_info("Enabling x2apic\n");
|
||||||
|
@ -1405,7 +1352,6 @@ void __init enable_IR_x2apic(void)
|
||||||
|
|
||||||
if (!x2apic) {
|
if (!x2apic) {
|
||||||
x2apic = 1;
|
x2apic = 1;
|
||||||
apic_ops = &x2apic_ops;
|
|
||||||
enable_x2apic();
|
enable_x2apic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1443,7 +1389,7 @@ end:
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_X2APIC */
|
#endif /* CONFIG_X86_X2APIC */
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
/*
|
/*
|
||||||
|
@ -1574,7 +1520,7 @@ void __init early_init_lapic_mapping(void)
|
||||||
*/
|
*/
|
||||||
void __init init_apic_mappings(void)
|
void __init init_apic_mappings(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_X2APIC
|
#ifdef CONFIG_X86_X2APIC
|
||||||
if (x2apic) {
|
if (x2apic) {
|
||||||
boot_cpu_physical_apicid = read_apic_id();
|
boot_cpu_physical_apicid = read_apic_id();
|
||||||
return;
|
return;
|
||||||
|
@ -1638,9 +1584,7 @@ int __init APIC_init_uniprocessor(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
|
||||||
enable_IR_x2apic();
|
enable_IR_x2apic();
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
default_setup_apic_routing();
|
default_setup_apic_routing();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1663,35 +1607,31 @@ int __init APIC_init_uniprocessor(void)
|
||||||
physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
|
physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
|
||||||
setup_local_APIC();
|
setup_local_APIC();
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
/*
|
/*
|
||||||
* Now enable IO-APICs, actually call clear_IO_APIC
|
* Now enable IO-APICs, actually call clear_IO_APIC
|
||||||
* We need clear_IO_APIC before enabling vector on BP
|
* We need clear_IO_APIC before enabling error vector
|
||||||
*/
|
*/
|
||||||
if (!skip_ioapic_setup && nr_ioapics)
|
if (!skip_ioapic_setup && nr_ioapics)
|
||||||
enable_IO_APIC();
|
enable_IO_APIC();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_IO_APIC
|
|
||||||
if (!smp_found_config || skip_ioapic_setup || !nr_ioapics)
|
|
||||||
#endif
|
|
||||||
localise_nmi_watchdog();
|
|
||||||
end_local_APIC_setup();
|
end_local_APIC_setup();
|
||||||
|
|
||||||
#ifdef CONFIG_X86_IO_APIC
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
|
if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
|
||||||
setup_IO_APIC();
|
setup_IO_APIC();
|
||||||
# ifdef CONFIG_X86_64
|
else {
|
||||||
else
|
|
||||||
nr_ioapics = 0;
|
nr_ioapics = 0;
|
||||||
# endif
|
localise_nmi_watchdog();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
localise_nmi_watchdog();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
setup_boot_APIC_clock();
|
|
||||||
check_nmi_watchdog();
|
|
||||||
#else
|
|
||||||
setup_boot_clock();
|
setup_boot_clock();
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
check_nmi_watchdog();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2029,7 +1969,7 @@ static int lapic_resume(struct sys_device *dev)
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
|
||||||
#ifdef HAVE_X2APIC
|
#ifdef CONFIG_X86_X2APIC
|
||||||
if (x2apic)
|
if (x2apic)
|
||||||
enable_x2apic();
|
enable_x2apic();
|
||||||
else
|
else
|
|
@ -19,24 +19,27 @@
|
||||||
#include <linux/dmar.h>
|
#include <linux/dmar.h>
|
||||||
|
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
#include <asm/ipi.h>
|
#include <asm/ipi.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
|
||||||
extern struct genapic apic_flat;
|
extern struct apic apic_flat;
|
||||||
extern struct genapic apic_physflat;
|
extern struct apic apic_physflat;
|
||||||
extern struct genapic apic_x2xpic_uv_x;
|
extern struct apic apic_x2xpic_uv_x;
|
||||||
extern struct genapic apic_x2apic_phys;
|
extern struct apic apic_x2apic_phys;
|
||||||
extern struct genapic apic_x2apic_cluster;
|
extern struct apic apic_x2apic_cluster;
|
||||||
|
|
||||||
struct genapic __read_mostly *apic = &apic_flat;
|
struct apic __read_mostly *apic = &apic_flat;
|
||||||
|
EXPORT_SYMBOL_GPL(apic);
|
||||||
|
|
||||||
static struct genapic *apic_probe[] __initdata = {
|
static struct apic *apic_probe[] __initdata = {
|
||||||
#ifdef CONFIG_X86_UV
|
#ifdef CONFIG_X86_UV
|
||||||
&apic_x2apic_uv_x,
|
&apic_x2apic_uv_x,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_X86_X2APIC
|
||||||
&apic_x2apic_phys,
|
&apic_x2apic_phys,
|
||||||
&apic_x2apic_cluster,
|
&apic_x2apic_cluster,
|
||||||
|
#endif
|
||||||
&apic_physflat,
|
&apic_physflat,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
@ -46,10 +49,12 @@ static struct genapic *apic_probe[] __initdata = {
|
||||||
*/
|
*/
|
||||||
void __init default_setup_apic_routing(void)
|
void __init default_setup_apic_routing(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_X86_X2APIC
|
||||||
if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
|
if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
|
||||||
if (!intr_remapping_enabled)
|
if (!intr_remapping_enabled)
|
||||||
apic = &apic_flat;
|
apic = &apic_flat;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (apic == &apic_flat) {
|
if (apic == &apic_flat) {
|
||||||
if (max_physical_apicid >= 8)
|
if (max_physical_apicid >= 8)
|
||||||
|
@ -57,8 +62,8 @@ void __init default_setup_apic_routing(void)
|
||||||
printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
|
printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x86_quirks->update_genapic)
|
if (x86_quirks->update_apic)
|
||||||
x86_quirks->update_genapic();
|
x86_quirks->update_apic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same for both flat and physical. */
|
/* Same for both flat and physical. */
|
|
@ -17,8 +17,8 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/hardirq.h>
|
#include <linux/hardirq.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
#include <asm/ipi.h>
|
#include <asm/ipi.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
#include <acpi/acpi_bus.h>
|
#include <acpi/acpi_bus.h>
|
||||||
|
@ -178,7 +178,7 @@ static int flat_phys_pkg_id(int initial_apic_id, int index_msb)
|
||||||
return hard_smp_processor_id() >> index_msb;
|
return hard_smp_processor_id() >> index_msb;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct genapic apic_flat = {
|
struct apic apic_flat = {
|
||||||
.name = "flat",
|
.name = "flat",
|
||||||
.probe = NULL,
|
.probe = NULL,
|
||||||
.acpi_madt_oem_check = flat_acpi_madt_oem_check,
|
.acpi_madt_oem_check = flat_acpi_madt_oem_check,
|
||||||
|
@ -227,8 +227,14 @@ struct genapic apic_flat = {
|
||||||
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
||||||
.wait_for_init_deassert = NULL,
|
.wait_for_init_deassert = NULL,
|
||||||
.smp_callin_clear_local_apic = NULL,
|
.smp_callin_clear_local_apic = NULL,
|
||||||
.store_NMI_vector = NULL,
|
|
||||||
.inquire_remote_apic = NULL,
|
.inquire_remote_apic = NULL,
|
||||||
|
|
||||||
|
.read = native_apic_mem_read,
|
||||||
|
.write = native_apic_mem_write,
|
||||||
|
.icr_read = native_apic_icr_read,
|
||||||
|
.icr_write = native_apic_icr_write,
|
||||||
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -321,7 +327,7 @@ physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||||
return BAD_APICID;
|
return BAD_APICID;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct genapic apic_physflat = {
|
struct apic apic_physflat = {
|
||||||
|
|
||||||
.name = "physical flat",
|
.name = "physical flat",
|
||||||
.probe = NULL,
|
.probe = NULL,
|
||||||
|
@ -372,6 +378,12 @@ struct genapic apic_physflat = {
|
||||||
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
||||||
.wait_for_init_deassert = NULL,
|
.wait_for_init_deassert = NULL,
|
||||||
.smp_callin_clear_local_apic = NULL,
|
.smp_callin_clear_local_apic = NULL,
|
||||||
.store_NMI_vector = NULL,
|
|
||||||
.inquire_remote_apic = NULL,
|
.inquire_remote_apic = NULL,
|
||||||
|
|
||||||
|
.read = native_apic_mem_read,
|
||||||
|
.write = native_apic_mem_write,
|
||||||
|
.icr_read = native_apic_icr_read,
|
||||||
|
.icr_write = native_apic_icr_write,
|
||||||
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||||
};
|
};
|
|
@ -62,7 +62,7 @@
|
||||||
#include <asm/uv/uv_hub.h>
|
#include <asm/uv/uv_hub.h>
|
||||||
#include <asm/uv/uv_irq.h>
|
#include <asm/uv/uv_irq.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
|
|
||||||
#define __apicdebuginit(type) static type __init
|
#define __apicdebuginit(type) static type __init
|
||||||
|
|
||||||
|
@ -813,8 +813,9 @@ static void clear_IO_APIC (void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_PIRQS 8
|
#define MAX_PIRQS 8
|
||||||
static int pirq_entries [MAX_PIRQS];
|
static int pirq_entries[MAX_PIRQS] = {
|
||||||
static int pirqs_enabled;
|
[0 ... MAX_PIRQS - 1] = -1
|
||||||
|
};
|
||||||
|
|
||||||
static int __init ioapic_pirq_setup(char *str)
|
static int __init ioapic_pirq_setup(char *str)
|
||||||
{
|
{
|
||||||
|
@ -823,10 +824,6 @@ static int __init ioapic_pirq_setup(char *str)
|
||||||
|
|
||||||
get_options(str, ARRAY_SIZE(ints), ints);
|
get_options(str, ARRAY_SIZE(ints), ints);
|
||||||
|
|
||||||
for (i = 0; i < MAX_PIRQS; i++)
|
|
||||||
pirq_entries[i] = -1;
|
|
||||||
|
|
||||||
pirqs_enabled = 1;
|
|
||||||
apic_printk(APIC_VERBOSE, KERN_INFO
|
apic_printk(APIC_VERBOSE, KERN_INFO
|
||||||
"PIRQ redirection, working around broken MP-BIOS.\n");
|
"PIRQ redirection, working around broken MP-BIOS.\n");
|
||||||
max = MAX_PIRQS;
|
max = MAX_PIRQS;
|
||||||
|
@ -1976,13 +1973,6 @@ void __init enable_IO_APIC(void)
|
||||||
int apic;
|
int apic;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
int i;
|
|
||||||
if (!pirqs_enabled)
|
|
||||||
for (i = 0; i < MAX_PIRQS; i++)
|
|
||||||
pirq_entries[i] = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of IO-APIC IRQ registers (== #pins):
|
* The number of IO-APIC IRQ registers (== #pins):
|
||||||
*/
|
*/
|
||||||
|
@ -3057,13 +3047,9 @@ out:
|
||||||
void __init setup_IO_APIC(void)
|
void __init setup_IO_APIC(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
enable_IO_APIC();
|
|
||||||
#else
|
|
||||||
/*
|
/*
|
||||||
* calling enable_IO_APIC() is moved to setup_local_APIC for BP
|
* calling enable_IO_APIC() is moved to setup_local_APIC for BP
|
||||||
*/
|
*/
|
||||||
#endif
|
|
||||||
|
|
||||||
io_apic_irqs = ~PIC_IRQS;
|
io_apic_irqs = ~PIC_IRQS;
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include <linux/dmar.h>
|
#include <linux/dmar.h>
|
||||||
|
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
#include <asm/ipi.h>
|
#include <asm/ipi.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
|
DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ static void
|
||||||
/*
|
/*
|
||||||
* send the IPI.
|
* send the IPI.
|
||||||
*/
|
*/
|
||||||
x2apic_icr_write(cfg, apicid);
|
native_x2apic_icr_write(cfg, apicid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -182,7 +182,7 @@ static void init_x2apic_ldr(void)
|
||||||
per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR);
|
per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct genapic apic_x2apic_cluster = {
|
struct apic apic_x2apic_cluster = {
|
||||||
|
|
||||||
.name = "cluster x2apic",
|
.name = "cluster x2apic",
|
||||||
.probe = NULL,
|
.probe = NULL,
|
||||||
|
@ -232,6 +232,12 @@ struct genapic apic_x2apic_cluster = {
|
||||||
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
||||||
.wait_for_init_deassert = NULL,
|
.wait_for_init_deassert = NULL,
|
||||||
.smp_callin_clear_local_apic = NULL,
|
.smp_callin_clear_local_apic = NULL,
|
||||||
.store_NMI_vector = NULL,
|
|
||||||
.inquire_remote_apic = NULL,
|
.inquire_remote_apic = NULL,
|
||||||
|
|
||||||
|
.read = native_apic_msr_read,
|
||||||
|
.write = native_apic_msr_write,
|
||||||
|
.icr_read = native_x2apic_icr_read,
|
||||||
|
.icr_write = native_x2apic_icr_write,
|
||||||
|
.wait_icr_idle = native_x2apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle,
|
||||||
};
|
};
|
|
@ -7,8 +7,8 @@
|
||||||
#include <linux/dmar.h>
|
#include <linux/dmar.h>
|
||||||
|
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
#include <asm/ipi.h>
|
#include <asm/ipi.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
static int x2apic_phys;
|
static int x2apic_phys;
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ static void __x2apic_send_IPI_dest(unsigned int apicid, int vector,
|
||||||
/*
|
/*
|
||||||
* send the IPI.
|
* send the IPI.
|
||||||
*/
|
*/
|
||||||
x2apic_icr_write(cfg, apicid);
|
native_x2apic_icr_write(cfg, apicid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
|
static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
|
||||||
|
@ -168,7 +168,7 @@ static void init_x2apic_ldr(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
struct genapic apic_x2apic_phys = {
|
struct apic apic_x2apic_phys = {
|
||||||
|
|
||||||
.name = "physical x2apic",
|
.name = "physical x2apic",
|
||||||
.probe = NULL,
|
.probe = NULL,
|
||||||
|
@ -218,6 +218,12 @@ struct genapic apic_x2apic_phys = {
|
||||||
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
||||||
.wait_for_init_deassert = NULL,
|
.wait_for_init_deassert = NULL,
|
||||||
.smp_callin_clear_local_apic = NULL,
|
.smp_callin_clear_local_apic = NULL,
|
||||||
.store_NMI_vector = NULL,
|
|
||||||
.inquire_remote_apic = NULL,
|
.inquire_remote_apic = NULL,
|
||||||
|
|
||||||
|
.read = native_apic_msr_read,
|
||||||
|
.write = native_apic_msr_write,
|
||||||
|
.icr_read = native_x2apic_icr_read,
|
||||||
|
.icr_write = native_x2apic_icr_write,
|
||||||
|
.wait_icr_idle = native_x2apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle,
|
||||||
};
|
};
|
|
@ -22,8 +22,8 @@
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <asm/current.h>
|
#include <asm/current.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
#include <asm/ipi.h>
|
#include <asm/ipi.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/uv/uv.h>
|
#include <asm/uv/uv.h>
|
||||||
#include <asm/uv/uv_mmrs.h>
|
#include <asm/uv/uv_mmrs.h>
|
||||||
|
@ -114,16 +114,15 @@ int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip)
|
||||||
|
|
||||||
static void uv_send_IPI_one(int cpu, int vector)
|
static void uv_send_IPI_one(int cpu, int vector)
|
||||||
{
|
{
|
||||||
unsigned long val, apicid, lapicid;
|
unsigned long val, apicid;
|
||||||
int pnode;
|
int pnode;
|
||||||
|
|
||||||
apicid = per_cpu(x86_cpu_to_apicid, cpu);
|
apicid = per_cpu(x86_cpu_to_apicid, cpu);
|
||||||
lapicid = apicid & 0x3f; /* ZZZ macro needed */
|
|
||||||
pnode = uv_apicid_to_pnode(apicid);
|
pnode = uv_apicid_to_pnode(apicid);
|
||||||
|
|
||||||
val = ( 1UL << UVH_IPI_INT_SEND_SHFT ) |
|
val = (1UL << UVH_IPI_INT_SEND_SHFT) |
|
||||||
( lapicid << UVH_IPI_INT_APIC_ID_SHFT ) |
|
(apicid << UVH_IPI_INT_APIC_ID_SHFT) |
|
||||||
( vector << UVH_IPI_INT_VECTOR_SHFT );
|
(vector << UVH_IPI_INT_VECTOR_SHFT);
|
||||||
|
|
||||||
uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
|
uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
|
||||||
}
|
}
|
||||||
|
@ -241,7 +240,7 @@ static void uv_send_IPI_self(int vector)
|
||||||
apic_write(APIC_SELF_IPI, vector);
|
apic_write(APIC_SELF_IPI, vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct genapic apic_x2apic_uv_x = {
|
struct apic apic_x2apic_uv_x = {
|
||||||
|
|
||||||
.name = "UV large system",
|
.name = "UV large system",
|
||||||
.probe = NULL,
|
.probe = NULL,
|
||||||
|
@ -291,8 +290,14 @@ struct genapic apic_x2apic_uv_x = {
|
||||||
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
.trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH,
|
||||||
.wait_for_init_deassert = NULL,
|
.wait_for_init_deassert = NULL,
|
||||||
.smp_callin_clear_local_apic = NULL,
|
.smp_callin_clear_local_apic = NULL,
|
||||||
.store_NMI_vector = NULL,
|
|
||||||
.inquire_remote_apic = NULL,
|
.inquire_remote_apic = NULL,
|
||||||
|
|
||||||
|
.read = native_apic_msr_read,
|
||||||
|
.write = native_apic_msr_write,
|
||||||
|
.icr_read = native_x2apic_icr_read,
|
||||||
|
.icr_write = native_x2apic_icr_write,
|
||||||
|
.wait_icr_idle = native_x2apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle,
|
||||||
};
|
};
|
||||||
|
|
||||||
static __cpuinit void set_x2apic_extra_bits(int pnode)
|
static __cpuinit void set_x2apic_extra_bits(int pnode)
|
|
@ -1,28 +1,26 @@
|
||||||
/*
|
/*
|
||||||
* APIC driver for "bigsmp" XAPIC machines with more than 8 virtual CPUs.
|
* APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs.
|
||||||
|
*
|
||||||
* Drives the local APIC in "clustered mode".
|
* Drives the local APIC in "clustered mode".
|
||||||
*/
|
*/
|
||||||
#define APIC_DEFINITION 1
|
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
#include <asm/mpspec.h>
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/fixmap.h>
|
|
||||||
#include <asm/apicdef.h>
|
|
||||||
#include <asm/ipi.h>
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
|
|
||||||
|
#include <asm/apicdef.h>
|
||||||
|
#include <asm/fixmap.h>
|
||||||
|
#include <asm/mpspec.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
|
#include <asm/ipi.h>
|
||||||
|
|
||||||
static inline unsigned bigsmp_get_apic_id(unsigned long x)
|
static inline unsigned bigsmp_get_apic_id(unsigned long x)
|
||||||
{
|
{
|
||||||
return (x >> 24) & 0xFF;
|
return (x >> 24) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define xapic_phys_to_log_apicid(cpu) (per_cpu(x86_bios_cpu_apicid, cpu))
|
|
||||||
|
|
||||||
static inline int bigsmp_apic_id_registered(void)
|
static inline int bigsmp_apic_id_registered(void)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -37,8 +35,6 @@ static inline const cpumask_t *bigsmp_target_cpus(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
|
|
||||||
|
|
||||||
static inline unsigned long
|
static inline unsigned long
|
||||||
bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid)
|
bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid)
|
||||||
{
|
{
|
||||||
|
@ -53,9 +49,11 @@ static inline unsigned long bigsmp_check_apicid_present(int bit)
|
||||||
static inline unsigned long calculate_ldr(int cpu)
|
static inline unsigned long calculate_ldr(int cpu)
|
||||||
{
|
{
|
||||||
unsigned long val, id;
|
unsigned long val, id;
|
||||||
|
|
||||||
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
|
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
|
||||||
id = xapic_phys_to_log_apicid(cpu);
|
id = per_cpu(x86_bios_cpu_apicid, cpu);
|
||||||
val |= SET_APIC_LOGICAL_ID(id);
|
val |= SET_APIC_LOGICAL_ID(id);
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,15 +69,16 @@ static inline void bigsmp_init_apic_ldr(void)
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
apic_write(APIC_DFR, APIC_DFR_FLAT);
|
||||||
val = calculate_ldr(cpu);
|
val = calculate_ldr(cpu);
|
||||||
apic_write(APIC_LDR, val);
|
apic_write(APIC_LDR, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bigsmp_setup_apic_routing(void)
|
static inline void bigsmp_setup_apic_routing(void)
|
||||||
{
|
{
|
||||||
printk("Enabling APIC mode: %s. Using %d I/O APICs\n",
|
printk(KERN_INFO
|
||||||
"Physflat", nr_ioapics);
|
"Enabling APIC mode: Physflat. Using %d I/O APICs\n",
|
||||||
|
nr_ioapics);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int bigsmp_apicid_to_node(int logical_apicid)
|
static inline int bigsmp_apicid_to_node(int logical_apicid)
|
||||||
|
@ -100,7 +99,6 @@ static inline physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid)
|
||||||
return physid_mask_of_physid(phys_apicid);
|
return physid_mask_of_physid(phys_apicid);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern u8 cpu_2_logical_apicid[];
|
|
||||||
/* Mapping from cpu number to logical apicid */
|
/* Mapping from cpu number to logical apicid */
|
||||||
static inline int bigsmp_cpu_to_logical_apicid(int cpu)
|
static inline int bigsmp_cpu_to_logical_apicid(int cpu)
|
||||||
{
|
{
|
||||||
|
@ -176,21 +174,24 @@ static int hp_ht_bigsmp(const struct dmi_system_id *d)
|
||||||
{
|
{
|
||||||
printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
|
printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
|
||||||
dmi_bigsmp = 1;
|
dmi_bigsmp = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const struct dmi_system_id bigsmp_dmi_table[] = {
|
static const struct dmi_system_id bigsmp_dmi_table[] = {
|
||||||
{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
|
{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
|
||||||
{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
|
{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
|
||||||
DMI_MATCH(DMI_BIOS_VERSION, "P44-"),}
|
DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{ hp_ht_bigsmp, "HP ProLiant DL740",
|
{ hp_ht_bigsmp, "HP ProLiant DL740",
|
||||||
{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
|
{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
|
||||||
DMI_MATCH(DMI_BIOS_VERSION, "P47-"),}
|
DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ }
|
{ } /* NULL entry stops DMI scanning */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask)
|
static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask)
|
||||||
|
@ -205,10 +206,11 @@ static int probe_bigsmp(void)
|
||||||
dmi_bigsmp = 1;
|
dmi_bigsmp = 1;
|
||||||
else
|
else
|
||||||
dmi_check_system(bigsmp_dmi_table);
|
dmi_check_system(bigsmp_dmi_table);
|
||||||
|
|
||||||
return dmi_bigsmp;
|
return dmi_bigsmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct genapic apic_bigsmp = {
|
struct apic apic_bigsmp = {
|
||||||
|
|
||||||
.name = "bigsmp",
|
.name = "bigsmp",
|
||||||
.probe = probe_bigsmp,
|
.probe = probe_bigsmp,
|
||||||
|
@ -261,6 +263,12 @@ struct genapic apic_bigsmp = {
|
||||||
.wait_for_init_deassert = default_wait_for_init_deassert,
|
.wait_for_init_deassert = default_wait_for_init_deassert,
|
||||||
|
|
||||||
.smp_callin_clear_local_apic = NULL,
|
.smp_callin_clear_local_apic = NULL,
|
||||||
.store_NMI_vector = NULL,
|
|
||||||
.inquire_remote_apic = default_inquire_remote_apic,
|
.inquire_remote_apic = default_inquire_remote_apic,
|
||||||
|
|
||||||
|
.read = native_apic_mem_read,
|
||||||
|
.write = native_apic_mem_write,
|
||||||
|
.icr_read = native_apic_icr_read,
|
||||||
|
.icr_write = native_apic_icr_write,
|
||||||
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <asm/pat.h>
|
#include <asm/pat.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
|
|
||||||
struct cpuid_bit {
|
struct cpuid_bit {
|
||||||
u16 feature;
|
u16 feature;
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
# include <asm/cacheflush.h>
|
# include <asm/cacheflush.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
|
|
|
@ -24,11 +24,9 @@
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
#include <asm/cpumask.h>
|
#include <asm/cpumask.h>
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
|
||||||
#include <asm/mpspec.h>
|
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/genapic.h>
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
#include <asm/uv/uv.h>
|
#include <asm/uv/uv.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -255,9 +253,9 @@ static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
|
||||||
* signs here...
|
* signs here...
|
||||||
*/
|
*/
|
||||||
if (cpu_has(c, df->feature) &&
|
if (cpu_has(c, df->feature) &&
|
||||||
((s32)df->feature < 0 ?
|
((s32)df->level < 0 ?
|
||||||
(u32)df->feature > (u32)c->extended_cpuid_level :
|
(u32)df->level > (u32)c->extended_cpuid_level :
|
||||||
(s32)df->feature > (s32)c->cpuid_level)) {
|
(s32)df->level > (s32)c->cpuid_level)) {
|
||||||
clear_cpu_cap(c, df->feature);
|
clear_cpu_cap(c, df->feature);
|
||||||
if (warn)
|
if (warn)
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
|
@ -267,7 +265,7 @@ static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
|
||||||
df->level);
|
df->level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Naming convention should be: <Name> [(<Codename>)]
|
* Naming convention should be: <Name> [(<Codename>)]
|
||||||
|
@ -1053,7 +1051,7 @@ void __cpuinit cpu_init(void)
|
||||||
barrier();
|
barrier();
|
||||||
|
|
||||||
check_efer();
|
check_efer();
|
||||||
if (cpu != 0 && x2apic)
|
if (cpu != 0)
|
||||||
enable_x2apic();
|
enable_x2apic();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
|
static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include <asm/reboot.h>
|
#include <asm/reboot.h>
|
||||||
#include <asm/virtext.h>
|
#include <asm/virtext.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
|
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
/*
|
/*
|
||||||
* Written by: Garry Forsgren, Unisys Corporation
|
* Written by: Garry Forsgren, Unisys Corporation
|
||||||
* Natalie Protasevich, Unisys Corporation
|
* Natalie Protasevich, Unisys Corporation
|
||||||
|
*
|
||||||
* This file contains the code to configure and interface
|
* This file contains the code to configure and interface
|
||||||
* with Unisys ES7000 series hardware system manager.
|
* with Unisys ES7000 series hardware system manager.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003 Unisys Corporation. All Rights Reserved.
|
* Copyright (c) 2003 Unisys Corporation.
|
||||||
|
* Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
|
||||||
|
*
|
||||||
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of version 2 of the GNU General Public License as
|
* under the terms of version 2 of the GNU General Public License as
|
||||||
|
@ -23,128 +27,105 @@
|
||||||
*
|
*
|
||||||
* http://www.unisys.com
|
* http://www.unisys.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/errno.h>
|
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/threads.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
#include <linux/init.h>
|
#include <linux/string.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
#include <asm/io.h>
|
#include <linux/init.h>
|
||||||
#include <asm/nmi.h>
|
#include <linux/nmi.h>
|
||||||
#include <asm/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <asm/atomic.h>
|
#include <linux/io.h>
|
||||||
|
|
||||||
#include <asm/apicdef.h>
|
#include <asm/apicdef.h>
|
||||||
#include <asm/genapic.h>
|
#include <asm/atomic.h>
|
||||||
|
#include <asm/fixmap.h>
|
||||||
|
#include <asm/mpspec.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
|
#include <asm/ipi.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ES7000 chipsets
|
* ES7000 chipsets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NON_UNISYS 0
|
#define NON_UNISYS 0
|
||||||
#define ES7000_CLASSIC 1
|
#define ES7000_CLASSIC 1
|
||||||
#define ES7000_ZORRO 2
|
#define ES7000_ZORRO 2
|
||||||
|
|
||||||
|
#define MIP_REG 1
|
||||||
|
#define MIP_PSAI_REG 4
|
||||||
|
|
||||||
#define MIP_REG 1
|
#define MIP_BUSY 1
|
||||||
#define MIP_PSAI_REG 4
|
#define MIP_SPIN 0xf0000
|
||||||
|
#define MIP_VALID 0x0100000000000000ULL
|
||||||
|
#define MIP_SW_APIC 0x1020b
|
||||||
|
|
||||||
#define MIP_BUSY 1
|
#define MIP_PORT(val) ((val >> 32) & 0xffff)
|
||||||
#define MIP_SPIN 0xf0000
|
|
||||||
#define MIP_VALID 0x0100000000000000ULL
|
|
||||||
#define MIP_PORT(VALUE) ((VALUE >> 32) & 0xffff)
|
|
||||||
|
|
||||||
#define MIP_RD_LO(VALUE) (VALUE & 0xffffffff)
|
#define MIP_RD_LO(val) (val & 0xffffffff)
|
||||||
|
|
||||||
struct mip_reg_info {
|
struct mip_reg {
|
||||||
unsigned long long mip_info;
|
unsigned long long off_0x00;
|
||||||
unsigned long long delivery_info;
|
unsigned long long off_0x08;
|
||||||
unsigned long long host_reg;
|
unsigned long long off_0x10;
|
||||||
unsigned long long mip_reg;
|
unsigned long long off_0x18;
|
||||||
|
unsigned long long off_0x20;
|
||||||
|
unsigned long long off_0x28;
|
||||||
|
unsigned long long off_0x30;
|
||||||
|
unsigned long long off_0x38;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct part_info {
|
struct mip_reg_info {
|
||||||
unsigned char type;
|
unsigned long long mip_info;
|
||||||
unsigned char length;
|
unsigned long long delivery_info;
|
||||||
unsigned char part_id;
|
unsigned long long host_reg;
|
||||||
unsigned char apic_mode;
|
unsigned long long mip_reg;
|
||||||
unsigned long snum;
|
|
||||||
char ptype[16];
|
|
||||||
char sname[64];
|
|
||||||
char pname[64];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct psai {
|
struct psai {
|
||||||
unsigned long long entry_type;
|
unsigned long long entry_type;
|
||||||
unsigned long long addr;
|
unsigned long long addr;
|
||||||
unsigned long long bep_addr;
|
unsigned long long bep_addr;
|
||||||
};
|
|
||||||
|
|
||||||
struct es7000_mem_info {
|
|
||||||
unsigned char type;
|
|
||||||
unsigned char length;
|
|
||||||
unsigned char resv[6];
|
|
||||||
unsigned long long start;
|
|
||||||
unsigned long long size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct es7000_oem_table {
|
|
||||||
unsigned long long hdr;
|
|
||||||
struct mip_reg_info mip;
|
|
||||||
struct part_info pif;
|
|
||||||
struct es7000_mem_info shm;
|
|
||||||
struct psai psai;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
|
|
||||||
struct oem_table {
|
struct es7000_oem_table {
|
||||||
struct acpi_table_header Header;
|
struct acpi_table_header Header;
|
||||||
u32 OEMTableAddr;
|
u32 OEMTableAddr;
|
||||||
u32 OEMTableSize;
|
u32 OEMTableSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
|
static unsigned long oem_addrX;
|
||||||
extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr);
|
static unsigned long oem_size;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct mip_reg {
|
|
||||||
unsigned long long off_0;
|
|
||||||
unsigned long long off_8;
|
|
||||||
unsigned long long off_10;
|
|
||||||
unsigned long long off_18;
|
|
||||||
unsigned long long off_20;
|
|
||||||
unsigned long long off_28;
|
|
||||||
unsigned long long off_30;
|
|
||||||
unsigned long long off_38;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MIP_SW_APIC 0x1020b
|
|
||||||
#define MIP_FUNC(VALUE) (VALUE & 0xff)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ES7000 Globals
|
* ES7000 Globals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static volatile unsigned long *psai = NULL;
|
static volatile unsigned long *psai;
|
||||||
static struct mip_reg *mip_reg;
|
static struct mip_reg *mip_reg;
|
||||||
static struct mip_reg *host_reg;
|
static struct mip_reg *host_reg;
|
||||||
static int mip_port;
|
static int mip_port;
|
||||||
static unsigned long mip_addr, host_addr;
|
static unsigned long mip_addr;
|
||||||
|
static unsigned long host_addr;
|
||||||
|
|
||||||
int es7000_plat;
|
int es7000_plat;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GSI override for ES7000 platforms.
|
* GSI override for ES7000 platforms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned int base;
|
static unsigned int base;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
es7000_rename_gsi(int ioapic, int gsi)
|
es7000_rename_gsi(int ioapic, int gsi)
|
||||||
|
@ -160,6 +141,7 @@ es7000_rename_gsi(int ioapic, int gsi)
|
||||||
|
|
||||||
if (!ioapic && (gsi < 16))
|
if (!ioapic && (gsi < 16))
|
||||||
gsi += base;
|
gsi += base;
|
||||||
|
|
||||||
return gsi;
|
return gsi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,14 +163,14 @@ static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init es7000_update_genapic(void)
|
static int __init es7000_update_apic(void)
|
||||||
{
|
{
|
||||||
apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
|
apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
|
||||||
|
|
||||||
/* MPENTIUMIII */
|
/* MPENTIUMIII */
|
||||||
if (boot_cpu_data.x86 == 6 &&
|
if (boot_cpu_data.x86 == 6 &&
|
||||||
(boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) {
|
(boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11)) {
|
||||||
es7000_update_genapic_to_cluster();
|
es7000_update_apic_to_cluster();
|
||||||
apic->wait_for_init_deassert = NULL;
|
apic->wait_for_init_deassert = NULL;
|
||||||
apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
|
apic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
|
||||||
}
|
}
|
||||||
|
@ -196,8 +178,7 @@ static int __init es7000_update_genapic(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init
|
static void __init setup_unisys(void)
|
||||||
setup_unisys(void)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Determine the generation of the ES7000 currently running.
|
* Determine the generation of the ES7000 currently running.
|
||||||
|
@ -212,22 +193,20 @@ setup_unisys(void)
|
||||||
es7000_plat = ES7000_CLASSIC;
|
es7000_plat = ES7000_CLASSIC;
|
||||||
ioapic_renumber_irq = es7000_rename_gsi;
|
ioapic_renumber_irq = es7000_rename_gsi;
|
||||||
|
|
||||||
x86_quirks->update_genapic = es7000_update_genapic;
|
x86_quirks->update_apic = es7000_update_apic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the OEM Table
|
* Parse the OEM Table:
|
||||||
*/
|
*/
|
||||||
|
static int __init parse_unisys_oem(char *oemptr)
|
||||||
int __init
|
|
||||||
parse_unisys_oem (char *oemptr)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int success = 0;
|
int success = 0;
|
||||||
unsigned char type, size;
|
unsigned char type, size;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
char *tp = NULL;
|
char *tp = NULL;
|
||||||
struct psai *psaip = NULL;
|
struct psai *psaip = NULL;
|
||||||
struct mip_reg_info *mi;
|
struct mip_reg_info *mi;
|
||||||
struct mip_reg *host, *mip;
|
struct mip_reg *host, *mip;
|
||||||
|
|
||||||
|
@ -235,7 +214,7 @@ parse_unisys_oem (char *oemptr)
|
||||||
|
|
||||||
tp += 8;
|
tp += 8;
|
||||||
|
|
||||||
for (i=0; i <= 6; i++) {
|
for (i = 0; i <= 6; i++) {
|
||||||
type = *tp++;
|
type = *tp++;
|
||||||
size = *tp++;
|
size = *tp++;
|
||||||
tp -= 2;
|
tp -= 2;
|
||||||
|
@ -273,50 +252,96 @@ parse_unisys_oem (char *oemptr)
|
||||||
tp += size;
|
tp += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success < 2) {
|
if (success < 2)
|
||||||
es7000_plat = NON_UNISYS;
|
es7000_plat = NON_UNISYS;
|
||||||
} else
|
else
|
||||||
setup_unisys();
|
setup_unisys();
|
||||||
|
|
||||||
return es7000_plat;
|
return es7000_plat;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
static unsigned long oem_addrX;
|
static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
|
||||||
static unsigned long oem_size;
|
|
||||||
int __init find_unisys_acpi_oem_table(unsigned long *oem_addr)
|
|
||||||
{
|
{
|
||||||
struct acpi_table_header *header = NULL;
|
struct acpi_table_header *header = NULL;
|
||||||
int i = 0;
|
struct es7000_oem_table *table;
|
||||||
acpi_size tbl_size;
|
acpi_size tbl_size;
|
||||||
|
acpi_status ret;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
while (ACPI_SUCCESS(acpi_get_table_with_size("OEM1", i++, &header, &tbl_size))) {
|
for (;;) {
|
||||||
if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) {
|
ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size);
|
||||||
struct oem_table *t = (struct oem_table *)header;
|
if (!ACPI_SUCCESS(ret))
|
||||||
|
return -1;
|
||||||
|
|
||||||
oem_addrX = t->OEMTableAddr;
|
if (!memcmp((char *) &header->oem_id, "UNISYS", 6))
|
||||||
oem_size = t->OEMTableSize;
|
break;
|
||||||
early_acpi_os_unmap_memory(header, tbl_size);
|
|
||||||
|
|
||||||
*oem_addr = (unsigned long)__acpi_map_table(oem_addrX,
|
|
||||||
oem_size);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
early_acpi_os_unmap_memory(header, tbl_size);
|
early_acpi_os_unmap_memory(header, tbl_size);
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
|
table = (void *)header;
|
||||||
|
|
||||||
|
oem_addrX = table->OEMTableAddr;
|
||||||
|
oem_size = table->OEMTableSize;
|
||||||
|
|
||||||
|
early_acpi_os_unmap_memory(header, tbl_size);
|
||||||
|
|
||||||
|
*oem_addr = (unsigned long)__acpi_map_table(oem_addrX, oem_size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
|
static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr)
|
||||||
{
|
{
|
||||||
if (!oem_addr)
|
if (!oem_addr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
__acpi_unmap_table((char *)oem_addr, oem_size);
|
__acpi_unmap_table((char *)oem_addr, oem_size);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static int es7000_check_dsdt(void)
|
||||||
es7000_spin(int n)
|
{
|
||||||
|
struct acpi_table_header header;
|
||||||
|
|
||||||
|
if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
|
||||||
|
!strncmp(header.oem_id, "UNISYS", 6))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hook from generic ACPI tables.c */
|
||||||
|
static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
||||||
|
{
|
||||||
|
unsigned long oem_addr = 0;
|
||||||
|
int check_dsdt;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/* check dsdt at first to avoid clear fix_map for oem_addr */
|
||||||
|
check_dsdt = es7000_check_dsdt();
|
||||||
|
|
||||||
|
if (!find_unisys_acpi_oem_table(&oem_addr)) {
|
||||||
|
if (check_dsdt) {
|
||||||
|
ret = parse_unisys_oem((char *)oem_addr);
|
||||||
|
} else {
|
||||||
|
setup_unisys();
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* we need to unmap it
|
||||||
|
*/
|
||||||
|
unmap_unisys_acpi_oem_table(oem_addr);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else /* !CONFIG_ACPI: */
|
||||||
|
static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_ACPI */
|
||||||
|
|
||||||
|
static void es7000_spin(int n)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
@ -327,16 +352,15 @@ es7000_spin(int n)
|
||||||
static int __init
|
static int __init
|
||||||
es7000_mip_write(struct mip_reg *mip_reg)
|
es7000_mip_write(struct mip_reg *mip_reg)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
int spin;
|
int spin;
|
||||||
|
|
||||||
spin = MIP_SPIN;
|
spin = MIP_SPIN;
|
||||||
while (((unsigned long long)host_reg->off_38 &
|
while ((host_reg->off_0x38 & MIP_VALID) != 0) {
|
||||||
(unsigned long long)MIP_VALID) != 0) {
|
if (--spin <= 0) {
|
||||||
if (--spin <= 0) {
|
WARN(1, "Timeout waiting for Host Valid Flag\n");
|
||||||
printk("es7000_mip_write: Timeout waiting for Host Valid Flag");
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
es7000_spin(MIP_SPIN);
|
es7000_spin(MIP_SPIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,23 +369,21 @@ es7000_mip_write(struct mip_reg *mip_reg)
|
||||||
|
|
||||||
spin = MIP_SPIN;
|
spin = MIP_SPIN;
|
||||||
|
|
||||||
while (((unsigned long long)mip_reg->off_38 &
|
while ((mip_reg->off_0x38 & MIP_VALID) == 0) {
|
||||||
(unsigned long long)MIP_VALID) == 0) {
|
|
||||||
if (--spin <= 0) {
|
if (--spin <= 0) {
|
||||||
printk("es7000_mip_write: Timeout waiting for MIP Valid Flag");
|
WARN(1, "Timeout waiting for MIP Valid Flag\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
es7000_spin(MIP_SPIN);
|
es7000_spin(MIP_SPIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ((unsigned long long)mip_reg->off_0 &
|
status = (mip_reg->off_0x00 & 0xffff0000000000ULL) >> 48;
|
||||||
(unsigned long long)0xffff0000000000ULL) >> 48;
|
mip_reg->off_0x38 &= ~MIP_VALID;
|
||||||
mip_reg->off_38 = ((unsigned long long)mip_reg->off_38 &
|
|
||||||
(unsigned long long)~MIP_VALID);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init es7000_enable_apic_mode(void)
|
static void __init es7000_enable_apic_mode(void)
|
||||||
{
|
{
|
||||||
struct mip_reg es7000_mip_reg;
|
struct mip_reg es7000_mip_reg;
|
||||||
int mip_status;
|
int mip_status;
|
||||||
|
@ -369,53 +391,15 @@ void __init es7000_enable_apic_mode(void)
|
||||||
if (!es7000_plat)
|
if (!es7000_plat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
printk("ES7000: Enabling APIC mode.\n");
|
printk(KERN_INFO "ES7000: Enabling APIC mode.\n");
|
||||||
memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
|
memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
|
||||||
es7000_mip_reg.off_0 = MIP_SW_APIC;
|
es7000_mip_reg.off_0x00 = MIP_SW_APIC;
|
||||||
es7000_mip_reg.off_38 = MIP_VALID;
|
es7000_mip_reg.off_0x38 = MIP_VALID;
|
||||||
|
|
||||||
while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0) {
|
while ((mip_status = es7000_mip_write(&es7000_mip_reg)) != 0)
|
||||||
printk("es7000_enable_apic_mode: command failed, status = %x\n",
|
WARN(1, "Command failed, status = %x\n", mip_status);
|
||||||
mip_status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* APIC driver for the Unisys ES7000 chipset.
|
|
||||||
*/
|
|
||||||
#define APIC_DEFINITION 1
|
|
||||||
#include <linux/threads.h>
|
|
||||||
#include <linux/cpumask.h>
|
|
||||||
#include <asm/mpspec.h>
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/fixmap.h>
|
|
||||||
#include <asm/apicdef.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/acpi.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <asm/ipi.h>
|
|
||||||
|
|
||||||
#define APIC_DFR_VALUE_CLUSTER (APIC_DFR_CLUSTER)
|
|
||||||
#define INT_DELIVERY_MODE_CLUSTER (dest_LowestPrio)
|
|
||||||
#define INT_DEST_MODE_CLUSTER (1) /* logical delivery broadcast to all procs */
|
|
||||||
|
|
||||||
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
|
|
||||||
|
|
||||||
extern void es7000_enable_apic_mode(void);
|
|
||||||
extern int apic_version [MAX_APICS];
|
|
||||||
extern u8 cpu_2_logical_apicid[];
|
|
||||||
extern unsigned int boot_cpu_physical_apicid;
|
|
||||||
|
|
||||||
extern int parse_unisys_oem (char *oemptr);
|
|
||||||
extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
|
|
||||||
extern void unmap_unisys_acpi_oem_table(unsigned long oem_addr);
|
|
||||||
extern void setup_unisys(void);
|
|
||||||
|
|
||||||
#define apicid_cluster(apicid) (apicid & 0xF0)
|
|
||||||
#define xapic_phys_to_log_apicid(cpu) per_cpu(x86_bios_cpu_apicid, cpu)
|
|
||||||
|
|
||||||
static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
|
static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
|
||||||
{
|
{
|
||||||
/* Careful. Some cpus do not strictly honor the set of cpus
|
/* Careful. Some cpus do not strictly honor the set of cpus
|
||||||
|
@ -444,18 +428,6 @@ static unsigned int es7000_get_apic_id(unsigned long x)
|
||||||
return (x >> 24) & 0xFF;
|
return (x >> 24) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
|
||||||
static int es7000_check_dsdt(void)
|
|
||||||
{
|
|
||||||
struct acpi_table_header header;
|
|
||||||
|
|
||||||
if (ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_DSDT, 0, &header)) &&
|
|
||||||
!strncmp(header.oem_id, "UNISYS", 6))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
|
static void es7000_send_IPI_mask(const struct cpumask *mask, int vector)
|
||||||
{
|
{
|
||||||
default_send_IPI_mask_sequence_phys(mask, vector);
|
default_send_IPI_mask_sequence_phys(mask, vector);
|
||||||
|
@ -473,7 +445,7 @@ static void es7000_send_IPI_all(int vector)
|
||||||
|
|
||||||
static int es7000_apic_id_registered(void)
|
static int es7000_apic_id_registered(void)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const cpumask_t *target_cpus_cluster(void)
|
static const cpumask_t *target_cpus_cluster(void)
|
||||||
|
@ -498,9 +470,9 @@ static unsigned long es7000_check_apicid_present(int bit)
|
||||||
|
|
||||||
static unsigned long calculate_ldr(int cpu)
|
static unsigned long calculate_ldr(int cpu)
|
||||||
{
|
{
|
||||||
unsigned long id = xapic_phys_to_log_apicid(cpu);
|
unsigned long id = per_cpu(x86_bios_cpu_apicid, cpu);
|
||||||
|
|
||||||
return (SET_APIC_LOGICAL_ID(id));
|
return SET_APIC_LOGICAL_ID(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -515,7 +487,7 @@ static void es7000_init_apic_ldr_cluster(void)
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
apic_write(APIC_DFR, APIC_DFR_VALUE_CLUSTER);
|
apic_write(APIC_DFR, APIC_DFR_CLUSTER);
|
||||||
val = calculate_ldr(cpu);
|
val = calculate_ldr(cpu);
|
||||||
apic_write(APIC_LDR, val);
|
apic_write(APIC_LDR, val);
|
||||||
}
|
}
|
||||||
|
@ -525,7 +497,7 @@ static void es7000_init_apic_ldr(void)
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
|
|
||||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
apic_write(APIC_DFR, APIC_DFR_FLAT);
|
||||||
val = calculate_ldr(cpu);
|
val = calculate_ldr(cpu);
|
||||||
apic_write(APIC_LDR, val);
|
apic_write(APIC_LDR, val);
|
||||||
}
|
}
|
||||||
|
@ -533,10 +505,12 @@ static void es7000_init_apic_ldr(void)
|
||||||
static void es7000_setup_apic_routing(void)
|
static void es7000_setup_apic_routing(void)
|
||||||
{
|
{
|
||||||
int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
|
int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
|
||||||
printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
|
|
||||||
|
printk(KERN_INFO
|
||||||
|
"Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
|
||||||
(apic_version[apic] == 0x14) ?
|
(apic_version[apic] == 0x14) ?
|
||||||
"Physical Cluster" : "Logical Cluster",
|
"Physical Cluster" : "Logical Cluster",
|
||||||
nr_ioapics, cpus_addr(*es7000_target_cpus())[0]);
|
nr_ioapics, cpus_addr(*es7000_target_cpus())[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int es7000_apicid_to_node(int logical_apicid)
|
static int es7000_apicid_to_node(int logical_apicid)
|
||||||
|
@ -550,18 +524,19 @@ static int es7000_cpu_present_to_apicid(int mps_cpu)
|
||||||
if (!mps_cpu)
|
if (!mps_cpu)
|
||||||
return boot_cpu_physical_apicid;
|
return boot_cpu_physical_apicid;
|
||||||
else if (mps_cpu < nr_cpu_ids)
|
else if (mps_cpu < nr_cpu_ids)
|
||||||
return (int) per_cpu(x86_bios_cpu_apicid, mps_cpu);
|
return per_cpu(x86_bios_cpu_apicid, mps_cpu);
|
||||||
else
|
else
|
||||||
return BAD_APICID;
|
return BAD_APICID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cpu_id;
|
||||||
|
|
||||||
static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid)
|
static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid)
|
||||||
{
|
{
|
||||||
static int id = 0;
|
|
||||||
physid_mask_t mask;
|
physid_mask_t mask;
|
||||||
|
|
||||||
mask = physid_mask_of_physid(id);
|
mask = physid_mask_of_physid(cpu_id);
|
||||||
++id;
|
++cpu_id;
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
@ -572,7 +547,7 @@ static int es7000_cpu_to_logical_apicid(int cpu)
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
if (cpu >= nr_cpu_ids)
|
if (cpu >= nr_cpu_ids)
|
||||||
return BAD_APICID;
|
return BAD_APICID;
|
||||||
return (int)cpu_2_logical_apicid[cpu];
|
return cpu_2_logical_apicid[cpu];
|
||||||
#else
|
#else
|
||||||
return logical_smp_processor_id();
|
return logical_smp_processor_id();
|
||||||
#endif
|
#endif
|
||||||
|
@ -587,7 +562,7 @@ static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map)
|
||||||
static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
|
static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
|
||||||
{
|
{
|
||||||
boot_cpu_physical_apicid = read_apic_id();
|
boot_cpu_physical_apicid = read_apic_id();
|
||||||
return (1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
|
@ -613,9 +588,8 @@ es7000_cpu_mask_to_apicid_cluster(const struct cpumask *cpumask)
|
||||||
if (cpumask_test_cpu(cpu, cpumask)) {
|
if (cpumask_test_cpu(cpu, cpumask)) {
|
||||||
int new_apicid = es7000_cpu_to_logical_apicid(cpu);
|
int new_apicid = es7000_cpu_to_logical_apicid(cpu);
|
||||||
|
|
||||||
if (apicid_cluster(apicid) !=
|
if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
|
||||||
apicid_cluster(new_apicid)) {
|
WARN(1, "Not a valid mask!");
|
||||||
printk ("%s: Not a valid mask!\n", __func__);
|
|
||||||
|
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
@ -648,9 +622,8 @@ static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask)
|
||||||
if (cpu_isset(cpu, *cpumask)) {
|
if (cpu_isset(cpu, *cpumask)) {
|
||||||
int new_apicid = es7000_cpu_to_logical_apicid(cpu);
|
int new_apicid = es7000_cpu_to_logical_apicid(cpu);
|
||||||
|
|
||||||
if (apicid_cluster(apicid) !=
|
if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
|
||||||
apicid_cluster(new_apicid)) {
|
printk("%s: Not a valid mask!\n", __func__);
|
||||||
printk ("%s: Not a valid mask!\n", __func__);
|
|
||||||
|
|
||||||
return es7000_cpu_to_logical_apicid(0);
|
return es7000_cpu_to_logical_apicid(0);
|
||||||
}
|
}
|
||||||
|
@ -686,11 +659,12 @@ static int es7000_phys_pkg_id(int cpuid_apic, int index_msb)
|
||||||
return cpuid_apic >> index_msb;
|
return cpuid_apic >> index_msb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init es7000_update_genapic_to_cluster(void)
|
void __init es7000_update_apic_to_cluster(void)
|
||||||
{
|
{
|
||||||
apic->target_cpus = target_cpus_cluster;
|
apic->target_cpus = target_cpus_cluster;
|
||||||
apic->irq_delivery_mode = INT_DELIVERY_MODE_CLUSTER;
|
apic->irq_delivery_mode = dest_LowestPrio;
|
||||||
apic->irq_dest_mode = INT_DEST_MODE_CLUSTER;
|
/* logical delivery broadcast to all procs: */
|
||||||
|
apic->irq_dest_mode = 1;
|
||||||
|
|
||||||
apic->init_apic_ldr = es7000_init_apic_ldr_cluster;
|
apic->init_apic_ldr = es7000_init_apic_ldr_cluster;
|
||||||
|
|
||||||
|
@ -716,40 +690,8 @@ es7000_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
|
||||||
/* Hook from generic ACPI tables.c */
|
|
||||||
static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
|
||||||
{
|
|
||||||
unsigned long oem_addr = 0;
|
|
||||||
int check_dsdt;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
/* check dsdt at first to avoid clear fix_map for oem_addr */
|
struct apic apic_es7000 = {
|
||||||
check_dsdt = es7000_check_dsdt();
|
|
||||||
|
|
||||||
if (!find_unisys_acpi_oem_table(&oem_addr)) {
|
|
||||||
if (check_dsdt)
|
|
||||||
ret = parse_unisys_oem((char *)oem_addr);
|
|
||||||
else {
|
|
||||||
setup_unisys();
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* we need to unmap it
|
|
||||||
*/
|
|
||||||
unmap_unisys_acpi_oem_table(oem_addr);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
struct genapic apic_es7000 = {
|
|
||||||
|
|
||||||
.name = "es7000",
|
.name = "es7000",
|
||||||
.probe = probe_es7000,
|
.probe = probe_es7000,
|
||||||
|
@ -804,6 +746,12 @@ struct genapic apic_es7000 = {
|
||||||
|
|
||||||
/* Nothing to do for most platforms, since cleared by the INIT cycle: */
|
/* Nothing to do for most platforms, since cleared by the INIT cycle: */
|
||||||
.smp_callin_clear_local_apic = NULL,
|
.smp_callin_clear_local_apic = NULL,
|
||||||
.store_NMI_vector = NULL,
|
|
||||||
.inquire_remote_apic = default_inquire_remote_apic,
|
.inquire_remote_apic = default_inquire_remote_apic,
|
||||||
|
|
||||||
|
.read = native_apic_mem_read,
|
||||||
|
.write = native_apic_mem_write,
|
||||||
|
.icr_read = native_apic_icr_read,
|
||||||
|
.icr_write = native_apic_icr_write,
|
||||||
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||||
};
|
};
|
||||||
|
|
|
@ -212,7 +212,6 @@ bool handle_irq(unsigned irq, struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
|
/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
|
||||||
void fixup_irqs(void)
|
void fixup_irqs(void)
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
#include <asm/apicdef.h>
|
#include <asm/apicdef.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Put the error code here just in case the user cares:
|
* Put the error code here just in case the user cares:
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
/*
|
/*
|
||||||
* Checksum an MP configuration block.
|
* Checksum an MP configuration block.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* Written by: Patricia Gaughen, IBM Corporation
|
* Written by: Patricia Gaughen, IBM Corporation
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002, IBM Corp.
|
* Copyright (C) 2002, IBM Corp.
|
||||||
|
* Copyright (C) 2009, Red Hat, Inc., Ingo Molnar
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -22,21 +23,81 @@
|
||||||
*
|
*
|
||||||
* Send feedback to <gone@us.ibm.com>
|
* Send feedback to <gone@us.ibm.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/nodemask.h>
|
#include <linux/nodemask.h>
|
||||||
|
#include <linux/topology.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
|
#include <linux/threads.h>
|
||||||
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
#include <linux/mmzone.h>
|
#include <linux/mmzone.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/numa.h>
|
||||||
|
#include <linux/smp.h>
|
||||||
|
#include <linux/io.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/topology.h>
|
#include <asm/fixmap.h>
|
||||||
#include <asm/genapic.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/numaq.h>
|
#include <asm/numaq.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
#include <asm/e820.h>
|
#include <asm/e820.h>
|
||||||
|
#include <asm/ipi.h>
|
||||||
|
|
||||||
#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT))
|
#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT))
|
||||||
|
|
||||||
|
int found_numaq;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Have to match translation table entries to main table entries by counter
|
||||||
|
* hence the mpc_record variable .... can't see a less disgusting way of
|
||||||
|
* doing this ....
|
||||||
|
*/
|
||||||
|
struct mpc_trans {
|
||||||
|
unsigned char mpc_type;
|
||||||
|
unsigned char trans_len;
|
||||||
|
unsigned char trans_type;
|
||||||
|
unsigned char trans_quad;
|
||||||
|
unsigned char trans_global;
|
||||||
|
unsigned char trans_local;
|
||||||
|
unsigned short trans_reserved;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* x86_quirks member */
|
||||||
|
static int mpc_record;
|
||||||
|
|
||||||
|
static __cpuinitdata struct mpc_trans *translation_table[MAX_MPC_ENTRY];
|
||||||
|
|
||||||
|
int mp_bus_id_to_node[MAX_MP_BUSSES];
|
||||||
|
int mp_bus_id_to_local[MAX_MP_BUSSES];
|
||||||
|
int quad_local_to_mp_bus_id[NR_CPUS/4][4];
|
||||||
|
|
||||||
|
|
||||||
|
static inline void numaq_register_node(int node, struct sys_cfg_data *scd)
|
||||||
|
{
|
||||||
|
struct eachquadmem *eq = scd->eq + node;
|
||||||
|
|
||||||
|
node_set_online(node);
|
||||||
|
|
||||||
|
/* Convert to pages */
|
||||||
|
node_start_pfn[node] =
|
||||||
|
MB_TO_PAGES(eq->hi_shrd_mem_start - eq->priv_mem_size);
|
||||||
|
|
||||||
|
node_end_pfn[node] =
|
||||||
|
MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
|
||||||
|
|
||||||
|
e820_register_active_regions(node, node_start_pfn[node],
|
||||||
|
node_end_pfn[node]);
|
||||||
|
|
||||||
|
memory_present(node, node_start_pfn[node], node_end_pfn[node]);
|
||||||
|
|
||||||
|
node_remap_size[node] = node_memmap_size_bytes(node,
|
||||||
|
node_start_pfn[node],
|
||||||
|
node_end_pfn[node]);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: smp_dump_qct()
|
* Function: smp_dump_qct()
|
||||||
|
@ -46,34 +107,18 @@
|
||||||
*/
|
*/
|
||||||
static void __init smp_dump_qct(void)
|
static void __init smp_dump_qct(void)
|
||||||
{
|
{
|
||||||
|
struct sys_cfg_data *scd;
|
||||||
int node;
|
int node;
|
||||||
struct eachquadmem *eq;
|
|
||||||
struct sys_cfg_data *scd =
|
scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR);
|
||||||
(struct sys_cfg_data *)__va(SYS_CFG_DATA_PRIV_ADDR);
|
|
||||||
|
|
||||||
nodes_clear(node_online_map);
|
nodes_clear(node_online_map);
|
||||||
for_each_node(node) {
|
for_each_node(node) {
|
||||||
if (scd->quads_present31_0 & (1 << node)) {
|
if (scd->quads_present31_0 & (1 << node))
|
||||||
node_set_online(node);
|
numaq_register_node(node, scd);
|
||||||
eq = &scd->eq[node];
|
|
||||||
/* Convert to pages */
|
|
||||||
node_start_pfn[node] = MB_TO_PAGES(
|
|
||||||
eq->hi_shrd_mem_start - eq->priv_mem_size);
|
|
||||||
node_end_pfn[node] = MB_TO_PAGES(
|
|
||||||
eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
|
|
||||||
|
|
||||||
e820_register_active_regions(node, node_start_pfn[node],
|
|
||||||
node_end_pfn[node]);
|
|
||||||
memory_present(node,
|
|
||||||
node_start_pfn[node], node_end_pfn[node]);
|
|
||||||
node_remap_size[node] = node_memmap_size_bytes(node,
|
|
||||||
node_start_pfn[node],
|
|
||||||
node_end_pfn[node]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void __cpuinit numaq_tsc_disable(void)
|
void __cpuinit numaq_tsc_disable(void)
|
||||||
{
|
{
|
||||||
if (!found_numaq)
|
if (!found_numaq)
|
||||||
|
@ -91,28 +136,6 @@ static int __init numaq_pre_time_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int found_numaq;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Have to match translation table entries to main table entries by counter
|
|
||||||
* hence the mpc_record variable .... can't see a less disgusting way of
|
|
||||||
* doing this ....
|
|
||||||
*/
|
|
||||||
struct mpc_config_translation {
|
|
||||||
unsigned char mpc_type;
|
|
||||||
unsigned char trans_len;
|
|
||||||
unsigned char trans_type;
|
|
||||||
unsigned char trans_quad;
|
|
||||||
unsigned char trans_global;
|
|
||||||
unsigned char trans_local;
|
|
||||||
unsigned short trans_reserved;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* x86_quirks member */
|
|
||||||
static int mpc_record;
|
|
||||||
static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY]
|
|
||||||
__cpuinitdata;
|
|
||||||
|
|
||||||
static inline int generate_logical_apicid(int quad, int phys_apicid)
|
static inline int generate_logical_apicid(int quad, int phys_apicid)
|
||||||
{
|
{
|
||||||
return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
|
return (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1);
|
||||||
|
@ -124,17 +147,15 @@ static int mpc_apic_id(struct mpc_cpu *m)
|
||||||
int quad = translation_table[mpc_record]->trans_quad;
|
int quad = translation_table[mpc_record]->trans_quad;
|
||||||
int logical_apicid = generate_logical_apicid(quad, m->apicid);
|
int logical_apicid = generate_logical_apicid(quad, m->apicid);
|
||||||
|
|
||||||
printk(KERN_DEBUG "Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
|
printk(KERN_DEBUG
|
||||||
m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
|
"Processor #%d %u:%u APIC version %d (quad %d, apic %d)\n",
|
||||||
(m->cpufeature & CPU_MODEL_MASK) >> 4,
|
m->apicid, (m->cpufeature & CPU_FAMILY_MASK) >> 8,
|
||||||
m->apicver, quad, logical_apicid);
|
(m->cpufeature & CPU_MODEL_MASK) >> 4,
|
||||||
|
m->apicver, quad, logical_apicid);
|
||||||
|
|
||||||
return logical_apicid;
|
return logical_apicid;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mp_bus_id_to_node[MAX_MP_BUSSES];
|
|
||||||
|
|
||||||
int mp_bus_id_to_local[MAX_MP_BUSSES];
|
|
||||||
|
|
||||||
/* x86_quirks member */
|
/* x86_quirks member */
|
||||||
static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
|
static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
|
||||||
{
|
{
|
||||||
|
@ -143,11 +164,9 @@ static void mpc_oem_bus_info(struct mpc_bus *m, char *name)
|
||||||
|
|
||||||
mp_bus_id_to_node[m->busid] = quad;
|
mp_bus_id_to_node[m->busid] = quad;
|
||||||
mp_bus_id_to_local[m->busid] = local;
|
mp_bus_id_to_local[m->busid] = local;
|
||||||
printk(KERN_INFO "Bus #%d is %s (node %d)\n",
|
|
||||||
m->busid, name, quad);
|
|
||||||
}
|
|
||||||
|
|
||||||
int quad_local_to_mp_bus_id [NR_CPUS/4][4];
|
printk(KERN_INFO "Bus #%d is %s (node %d)\n", m->busid, name, quad);
|
||||||
|
}
|
||||||
|
|
||||||
/* x86_quirks member */
|
/* x86_quirks member */
|
||||||
static void mpc_oem_pci_bus(struct mpc_bus *m)
|
static void mpc_oem_pci_bus(struct mpc_bus *m)
|
||||||
|
@ -158,17 +177,18 @@ static void mpc_oem_pci_bus(struct mpc_bus *m)
|
||||||
quad_local_to_mp_bus_id[quad][local] = m->busid;
|
quad_local_to_mp_bus_id[quad][local] = m->busid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init MP_translation_info(struct mpc_config_translation *m)
|
static void __init MP_translation_info(struct mpc_trans *m)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO
|
printk(KERN_INFO
|
||||||
"Translation: record %d, type %d, quad %d, global %d, local %d\n",
|
"Translation: record %d, type %d, quad %d, global %d, local %d\n",
|
||||||
mpc_record, m->trans_type, m->trans_quad, m->trans_global,
|
mpc_record, m->trans_type, m->trans_quad, m->trans_global,
|
||||||
m->trans_local);
|
m->trans_local);
|
||||||
|
|
||||||
if (mpc_record >= MAX_MPC_ENTRY)
|
if (mpc_record >= MAX_MPC_ENTRY)
|
||||||
printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
|
printk(KERN_ERR "MAX_MPC_ENTRY exceeded!\n");
|
||||||
else
|
else
|
||||||
translation_table[mpc_record] = m; /* stash this for later */
|
translation_table[mpc_record] = m; /* stash this for later */
|
||||||
|
|
||||||
if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
|
if (m->trans_quad < MAX_NUMNODES && !node_online(m->trans_quad))
|
||||||
node_set_online(m->trans_quad);
|
node_set_online(m->trans_quad);
|
||||||
}
|
}
|
||||||
|
@ -186,16 +206,16 @@ static int __init mpf_checksum(unsigned char *mp, int len)
|
||||||
/*
|
/*
|
||||||
* Read/parse the MPC oem tables
|
* Read/parse the MPC oem tables
|
||||||
*/
|
*/
|
||||||
|
static void __init
|
||||||
static void __init smp_read_mpc_oem(struct mpc_oemtable *oemtable,
|
smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize)
|
||||||
unsigned short oemsize)
|
|
||||||
{
|
{
|
||||||
int count = sizeof(*oemtable); /* the header size */
|
int count = sizeof(*oemtable); /* the header size */
|
||||||
unsigned char *oemptr = ((unsigned char *)oemtable) + count;
|
unsigned char *oemptr = ((unsigned char *)oemtable) + count;
|
||||||
|
|
||||||
mpc_record = 0;
|
mpc_record = 0;
|
||||||
printk(KERN_INFO "Found an OEM MPC table at %8p - parsing it ... \n",
|
printk(KERN_INFO
|
||||||
oemtable);
|
"Found an OEM MPC table at %8p - parsing it ... \n", oemtable);
|
||||||
|
|
||||||
if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
|
if (memcmp(oemtable->signature, MPC_OEM_SIGNATURE, 4)) {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
|
"SMP mpc oemtable: bad signature [%c%c%c%c]!\n",
|
||||||
|
@ -203,16 +223,18 @@ static void __init smp_read_mpc_oem(struct mpc_oemtable *oemtable,
|
||||||
oemtable->signature[2], oemtable->signature[3]);
|
oemtable->signature[2], oemtable->signature[3]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) {
|
if (mpf_checksum((unsigned char *)oemtable, oemtable->length)) {
|
||||||
printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
|
printk(KERN_WARNING "SMP oem mptable: checksum error!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count < oemtable->length) {
|
while (count < oemtable->length) {
|
||||||
switch (*oemptr) {
|
switch (*oemptr) {
|
||||||
case MP_TRANSLATION:
|
case MP_TRANSLATION:
|
||||||
{
|
{
|
||||||
struct mpc_config_translation *m =
|
struct mpc_trans *m = (void *)oemptr;
|
||||||
(struct mpc_config_translation *)oemptr;
|
|
||||||
MP_translation_info(m);
|
MP_translation_info(m);
|
||||||
oemptr += sizeof(*m);
|
oemptr += sizeof(*m);
|
||||||
count += sizeof(*m);
|
count += sizeof(*m);
|
||||||
|
@ -220,12 +242,10 @@ static void __init smp_read_mpc_oem(struct mpc_oemtable *oemtable,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
printk(KERN_WARNING
|
||||||
printk(KERN_WARNING
|
"Unrecognised OEM table entry type! - %d\n",
|
||||||
"Unrecognised OEM table entry type! - %d\n",
|
(int)*oemptr);
|
||||||
(int)*oemptr);
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +256,7 @@ static int __init numaq_setup_ioapic_ids(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init numaq_update_genapic(void)
|
static int __init numaq_update_apic(void)
|
||||||
{
|
{
|
||||||
apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
|
apic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
|
||||||
|
|
||||||
|
@ -244,37 +264,30 @@ static int __init numaq_update_genapic(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct x86_quirks numaq_x86_quirks __initdata = {
|
static struct x86_quirks numaq_x86_quirks __initdata = {
|
||||||
.arch_pre_time_init = numaq_pre_time_init,
|
.arch_pre_time_init = numaq_pre_time_init,
|
||||||
.arch_time_init = NULL,
|
.arch_time_init = NULL,
|
||||||
.arch_pre_intr_init = NULL,
|
.arch_pre_intr_init = NULL,
|
||||||
.arch_memory_setup = NULL,
|
.arch_memory_setup = NULL,
|
||||||
.arch_intr_init = NULL,
|
.arch_intr_init = NULL,
|
||||||
.arch_trap_init = NULL,
|
.arch_trap_init = NULL,
|
||||||
.mach_get_smp_config = NULL,
|
.mach_get_smp_config = NULL,
|
||||||
.mach_find_smp_config = NULL,
|
.mach_find_smp_config = NULL,
|
||||||
.mpc_record = &mpc_record,
|
.mpc_record = &mpc_record,
|
||||||
.mpc_apic_id = mpc_apic_id,
|
.mpc_apic_id = mpc_apic_id,
|
||||||
.mpc_oem_bus_info = mpc_oem_bus_info,
|
.mpc_oem_bus_info = mpc_oem_bus_info,
|
||||||
.mpc_oem_pci_bus = mpc_oem_pci_bus,
|
.mpc_oem_pci_bus = mpc_oem_pci_bus,
|
||||||
.smp_read_mpc_oem = smp_read_mpc_oem,
|
.smp_read_mpc_oem = smp_read_mpc_oem,
|
||||||
.setup_ioapic_ids = numaq_setup_ioapic_ids,
|
.setup_ioapic_ids = numaq_setup_ioapic_ids,
|
||||||
.update_genapic = numaq_update_genapic,
|
.update_apic = numaq_update_apic,
|
||||||
};
|
};
|
||||||
|
|
||||||
void numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
|
|
||||||
{
|
|
||||||
if (strncmp(oem, "IBM NUMA", 8))
|
|
||||||
printk("Warning! Not a NUMA-Q system!\n");
|
|
||||||
else
|
|
||||||
found_numaq = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __init void early_check_numaq(void)
|
static __init void early_check_numaq(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Find possible boot-time SMP configuration:
|
* Find possible boot-time SMP configuration:
|
||||||
*/
|
*/
|
||||||
early_find_smp_config();
|
early_find_smp_config();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get boot-time SMP configuration:
|
* get boot-time SMP configuration:
|
||||||
*/
|
*/
|
||||||
|
@ -291,30 +304,10 @@ int __init get_memcfg_numaq(void)
|
||||||
if (!found_numaq)
|
if (!found_numaq)
|
||||||
return 0;
|
return 0;
|
||||||
smp_dump_qct();
|
smp_dump_qct();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* APIC driver for the IBM NUMAQ chipset.
|
|
||||||
*/
|
|
||||||
#define APIC_DEFINITION 1
|
|
||||||
#include <linux/threads.h>
|
|
||||||
#include <linux/cpumask.h>
|
|
||||||
#include <asm/mpspec.h>
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/fixmap.h>
|
|
||||||
#include <asm/apicdef.h>
|
|
||||||
#include <asm/ipi.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/numa.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
#include <asm/numaq.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include <linux/mmzone.h>
|
|
||||||
#include <linux/nodemask.h>
|
|
||||||
|
|
||||||
#define NUMAQ_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
|
#define NUMAQ_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
|
||||||
|
|
||||||
static inline unsigned int numaq_get_apic_id(unsigned long x)
|
static inline unsigned int numaq_get_apic_id(unsigned long x)
|
||||||
|
@ -337,10 +330,8 @@ static inline void numaq_send_IPI_all(int vector)
|
||||||
numaq_send_IPI_mask(cpu_online_mask, vector);
|
numaq_send_IPI_mask(cpu_online_mask, vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void numaq_mps_oem_check(struct mpc_table *, char *, char *);
|
#define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8)
|
||||||
|
#define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa)
|
||||||
#define NUMAQ_TRAMPOLINE_PHYS_LOW (0x8)
|
|
||||||
#define NUMAQ_TRAMPOLINE_PHYS_HIGH (0xa)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Because we use NMIs rather than the INIT-STARTUP sequence to
|
* Because we use NMIs rather than the INIT-STARTUP sequence to
|
||||||
|
@ -351,16 +342,6 @@ static inline void numaq_smp_callin_clear_local_apic(void)
|
||||||
clear_local_APIC();
|
clear_local_APIC();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
numaq_store_NMI_vector(unsigned short *high, unsigned short *low)
|
|
||||||
{
|
|
||||||
printk("Storing NMI vector\n");
|
|
||||||
*high =
|
|
||||||
*((volatile unsigned short *)phys_to_virt(NUMAQ_TRAMPOLINE_PHYS_HIGH));
|
|
||||||
*low =
|
|
||||||
*((volatile unsigned short *)phys_to_virt(NUMAQ_TRAMPOLINE_PHYS_LOW));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const cpumask_t *numaq_target_cpus(void)
|
static inline const cpumask_t *numaq_target_cpus(void)
|
||||||
{
|
{
|
||||||
return &CPU_MASK_ALL;
|
return &CPU_MASK_ALL;
|
||||||
|
@ -377,8 +358,6 @@ static inline unsigned long numaq_check_apicid_present(int bit)
|
||||||
return physid_isset(bit, phys_cpu_present_map);
|
return physid_isset(bit, phys_cpu_present_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define apicid_cluster(apicid) (apicid & 0xF0)
|
|
||||||
|
|
||||||
static inline int numaq_apic_id_registered(void)
|
static inline int numaq_apic_id_registered(void)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -391,8 +370,9 @@ static inline void numaq_init_apic_ldr(void)
|
||||||
|
|
||||||
static inline void numaq_setup_apic_routing(void)
|
static inline void numaq_setup_apic_routing(void)
|
||||||
{
|
{
|
||||||
printk("Enabling APIC mode: %s. Using %d I/O APICs\n",
|
printk(KERN_INFO
|
||||||
"NUMA-Q", nr_ioapics);
|
"Enabling APIC mode: NUMA-Q. Using %d I/O APICs\n",
|
||||||
|
nr_ioapics);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -410,14 +390,11 @@ static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map)
|
||||||
return physids_promote(0xFUL);
|
return physids_promote(0xFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mapping from cpu number to logical apicid */
|
|
||||||
extern u8 cpu_2_logical_apicid[];
|
|
||||||
|
|
||||||
static inline int numaq_cpu_to_logical_apicid(int cpu)
|
static inline int numaq_cpu_to_logical_apicid(int cpu)
|
||||||
{
|
{
|
||||||
if (cpu >= nr_cpu_ids)
|
if (cpu >= nr_cpu_ids)
|
||||||
return BAD_APICID;
|
return BAD_APICID;
|
||||||
return (int)cpu_2_logical_apicid[cpu];
|
return cpu_2_logical_apicid[cpu];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -433,7 +410,7 @@ static inline int numaq_cpu_present_to_apicid(int mps_cpu)
|
||||||
return BAD_APICID;
|
return BAD_APICID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int numaq_apicid_to_node(int logical_apicid)
|
static inline int numaq_apicid_to_node(int logical_apicid)
|
||||||
{
|
{
|
||||||
return logical_apicid >> 4;
|
return logical_apicid >> 4;
|
||||||
}
|
}
|
||||||
|
@ -475,9 +452,15 @@ static inline int numaq_phys_pkg_id(int cpuid_apic, int index_msb)
|
||||||
{
|
{
|
||||||
return cpuid_apic >> index_msb;
|
return cpuid_apic >> index_msb;
|
||||||
}
|
}
|
||||||
static int __numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
|
|
||||||
|
static int
|
||||||
|
numaq_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
|
||||||
{
|
{
|
||||||
numaq_mps_oem_check(mpc, oem, productid);
|
if (strncmp(oem, "IBM NUMA", 8))
|
||||||
|
printk(KERN_ERR "Warning! Not a NUMA-Q system!\n");
|
||||||
|
else
|
||||||
|
found_numaq = 1;
|
||||||
|
|
||||||
return found_numaq;
|
return found_numaq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,13 +490,17 @@ static void numaq_setup_portio_remap(void)
|
||||||
if (num_quads <= 1)
|
if (num_quads <= 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
printk("Remapping cross-quad port I/O for %d quads\n", num_quads);
|
printk(KERN_INFO
|
||||||
|
"Remapping cross-quad port I/O for %d quads\n", num_quads);
|
||||||
|
|
||||||
xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
|
xquad_portio = ioremap(XQUAD_PORTIO_BASE, num_quads*XQUAD_PORTIO_QUAD);
|
||||||
printk("xquad_portio vaddr 0x%08lx, len %08lx\n",
|
|
||||||
|
printk(KERN_INFO
|
||||||
|
"xquad_portio vaddr 0x%08lx, len %08lx\n",
|
||||||
(u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
|
(u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct genapic apic_numaq = {
|
struct apic apic_numaq = {
|
||||||
|
|
||||||
.name = "NUMAQ",
|
.name = "NUMAQ",
|
||||||
.probe = probe_numaq,
|
.probe = probe_numaq,
|
||||||
|
@ -544,7 +531,7 @@ struct genapic apic_numaq = {
|
||||||
.check_phys_apicid_present = numaq_check_phys_apicid_present,
|
.check_phys_apicid_present = numaq_check_phys_apicid_present,
|
||||||
.enable_apic_mode = NULL,
|
.enable_apic_mode = NULL,
|
||||||
.phys_pkg_id = numaq_phys_pkg_id,
|
.phys_pkg_id = numaq_phys_pkg_id,
|
||||||
.mps_oem_check = __numaq_mps_oem_check,
|
.mps_oem_check = numaq_mps_oem_check,
|
||||||
|
|
||||||
.get_apic_id = numaq_get_apic_id,
|
.get_apic_id = numaq_get_apic_id,
|
||||||
.set_apic_id = NULL,
|
.set_apic_id = NULL,
|
||||||
|
@ -567,6 +554,12 @@ struct genapic apic_numaq = {
|
||||||
.wait_for_init_deassert = NULL,
|
.wait_for_init_deassert = NULL,
|
||||||
|
|
||||||
.smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic,
|
.smp_callin_clear_local_apic = numaq_smp_callin_clear_local_apic,
|
||||||
.store_NMI_vector = numaq_store_NMI_vector,
|
|
||||||
.inquire_remote_apic = NULL,
|
.inquire_remote_apic = NULL,
|
||||||
|
|
||||||
|
.read = native_apic_mem_read,
|
||||||
|
.write = native_apic_mem_write,
|
||||||
|
.icr_read = native_apic_icr_read,
|
||||||
|
.icr_write = native_apic_icr_write,
|
||||||
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||||
};
|
};
|
||||||
|
|
|
@ -203,7 +203,7 @@ static void __init platform_detect(void)
|
||||||
static void __init platform_detect(void)
|
static void __init platform_detect(void)
|
||||||
{
|
{
|
||||||
/* stopgap until OFW support is added to the kernel */
|
/* stopgap until OFW support is added to the kernel */
|
||||||
olpc_platform_info.boardrev = 0xc2;
|
olpc_platform_info.boardrev = olpc_board(0xc2);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
@ -16,20 +17,18 @@
|
||||||
#include <asm/fixmap.h>
|
#include <asm/fixmap.h>
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/apicdef.h>
|
#include <asm/apicdef.h>
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/fixmap.h>
|
#include <asm/fixmap.h>
|
||||||
#include <asm/apicdef.h>
|
#include <asm/apicdef.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/ipi.h>
|
#include <asm/ipi.h>
|
||||||
|
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
|
@ -40,8 +39,6 @@
|
||||||
#include <asm/e820.h>
|
#include <asm/e820.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
#define DEFAULT_SEND_IPI (1)
|
#define DEFAULT_SEND_IPI (1)
|
||||||
#else
|
#else
|
||||||
|
@ -52,6 +49,15 @@ int no_broadcast = DEFAULT_SEND_IPI;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
|
|
||||||
|
void default_setup_apic_routing(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
|
printk(KERN_INFO
|
||||||
|
"Enabling APIC mode: Flat. Using %d I/O APICs\n",
|
||||||
|
nr_ioapics);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
|
static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -72,7 +78,7 @@ static int probe_default(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct genapic apic_default = {
|
struct apic apic_default = {
|
||||||
|
|
||||||
.name = "default",
|
.name = "default",
|
||||||
.probe = probe_default,
|
.probe = probe_default,
|
||||||
|
@ -125,19 +131,26 @@ struct genapic apic_default = {
|
||||||
.wait_for_init_deassert = default_wait_for_init_deassert,
|
.wait_for_init_deassert = default_wait_for_init_deassert,
|
||||||
|
|
||||||
.smp_callin_clear_local_apic = NULL,
|
.smp_callin_clear_local_apic = NULL,
|
||||||
.store_NMI_vector = NULL,
|
|
||||||
.inquire_remote_apic = default_inquire_remote_apic,
|
.inquire_remote_apic = default_inquire_remote_apic,
|
||||||
|
|
||||||
|
.read = native_apic_mem_read,
|
||||||
|
.write = native_apic_mem_write,
|
||||||
|
.icr_read = native_apic_icr_read,
|
||||||
|
.icr_write = native_apic_icr_write,
|
||||||
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct genapic apic_numaq;
|
extern struct apic apic_numaq;
|
||||||
extern struct genapic apic_summit;
|
extern struct apic apic_summit;
|
||||||
extern struct genapic apic_bigsmp;
|
extern struct apic apic_bigsmp;
|
||||||
extern struct genapic apic_es7000;
|
extern struct apic apic_es7000;
|
||||||
extern struct genapic apic_default;
|
extern struct apic apic_default;
|
||||||
|
|
||||||
struct genapic *apic = &apic_default;
|
struct apic *apic = &apic_default;
|
||||||
|
EXPORT_SYMBOL_GPL(apic);
|
||||||
|
|
||||||
static struct genapic *apic_probe[] __initdata = {
|
static struct apic *apic_probe[] __initdata = {
|
||||||
#ifdef CONFIG_X86_NUMAQ
|
#ifdef CONFIG_X86_NUMAQ
|
||||||
&apic_numaq,
|
&apic_numaq,
|
||||||
#endif
|
#endif
|
||||||
|
@ -170,8 +183,8 @@ static int __init parse_apic(char *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x86_quirks->update_genapic)
|
if (x86_quirks->update_apic)
|
||||||
x86_quirks->update_genapic();
|
x86_quirks->update_apic();
|
||||||
|
|
||||||
/* Parsed again by __setup for debug/verbose */
|
/* Parsed again by __setup for debug/verbose */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -191,8 +204,8 @@ void __init generic_bigsmp_probe(void)
|
||||||
if (!cmdline_apic && apic == &apic_default) {
|
if (!cmdline_apic && apic == &apic_default) {
|
||||||
if (apic_bigsmp.probe()) {
|
if (apic_bigsmp.probe()) {
|
||||||
apic = &apic_bigsmp;
|
apic = &apic_bigsmp;
|
||||||
if (x86_quirks->update_genapic)
|
if (x86_quirks->update_apic)
|
||||||
x86_quirks->update_genapic();
|
x86_quirks->update_apic();
|
||||||
printk(KERN_INFO "Overriding APIC driver with %s\n",
|
printk(KERN_INFO "Overriding APIC driver with %s\n",
|
||||||
apic->name);
|
apic->name);
|
||||||
}
|
}
|
||||||
|
@ -214,8 +227,8 @@ void __init generic_apic_probe(void)
|
||||||
if (!apic_probe[i])
|
if (!apic_probe[i])
|
||||||
panic("Didn't find an APIC driver");
|
panic("Didn't find an APIC driver");
|
||||||
|
|
||||||
if (x86_quirks->update_genapic)
|
if (x86_quirks->update_apic)
|
||||||
x86_quirks->update_genapic();
|
x86_quirks->update_apic();
|
||||||
}
|
}
|
||||||
printk(KERN_INFO "Using APIC driver %s\n", apic->name);
|
printk(KERN_INFO "Using APIC driver %s\n", apic->name);
|
||||||
}
|
}
|
||||||
|
@ -235,8 +248,8 @@ generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
|
||||||
|
|
||||||
if (!cmdline_apic) {
|
if (!cmdline_apic) {
|
||||||
apic = apic_probe[i];
|
apic = apic_probe[i];
|
||||||
if (x86_quirks->update_genapic)
|
if (x86_quirks->update_apic)
|
||||||
x86_quirks->update_genapic();
|
x86_quirks->update_apic();
|
||||||
printk(KERN_INFO "Switched to APIC driver `%s'.\n",
|
printk(KERN_INFO "Switched to APIC driver `%s'.\n",
|
||||||
apic->name);
|
apic->name);
|
||||||
}
|
}
|
||||||
|
@ -257,8 +270,8 @@ int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
|
||||||
|
|
||||||
if (!cmdline_apic) {
|
if (!cmdline_apic) {
|
||||||
apic = apic_probe[i];
|
apic = apic_probe[i];
|
||||||
if (x86_quirks->update_genapic)
|
if (x86_quirks->update_apic)
|
||||||
x86_quirks->update_genapic();
|
x86_quirks->update_apic();
|
||||||
printk(KERN_INFO "Switched to APIC driver `%s'.\n",
|
printk(KERN_INFO "Switched to APIC driver `%s'.\n",
|
||||||
apic->name);
|
apic->name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
# include <asm/iommu.h>
|
# include <asm/iommu.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Power off function, if any
|
* Power off function, if any
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -97,7 +97,6 @@
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
#include <asm/proto.h>
|
#include <asm/proto.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/paravirt.h>
|
#include <asm/paravirt.h>
|
||||||
#include <asm/hypervisor.h>
|
#include <asm/hypervisor.h>
|
||||||
|
|
||||||
|
@ -600,7 +599,7 @@ static int __init setup_elfcorehdr(char *arg)
|
||||||
early_param("elfcorehdr", setup_elfcorehdr);
|
early_param("elfcorehdr", setup_elfcorehdr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int __init default_update_genapic(void)
|
static int __init default_update_apic(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
if (!apic->wakeup_cpu)
|
if (!apic->wakeup_cpu)
|
||||||
|
@ -611,7 +610,7 @@ static int __init default_update_genapic(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct x86_quirks default_x86_quirks __initdata = {
|
static struct x86_quirks default_x86_quirks __initdata = {
|
||||||
.update_genapic = default_update_genapic,
|
.update_apic = default_update_apic,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
|
struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
|
||||||
|
@ -836,8 +835,7 @@ void __init setup_arch(char **cmdline_p)
|
||||||
#else
|
#else
|
||||||
num_physpages = max_pfn;
|
num_physpages = max_pfn;
|
||||||
|
|
||||||
if (cpu_has_x2apic)
|
check_x2apic();
|
||||||
check_x2apic();
|
|
||||||
|
|
||||||
/* How many end-of-memory variables you have, grandma! */
|
/* How many end-of-memory variables you have, grandma! */
|
||||||
/* need this before calling reserve_initrd */
|
/* need this before calling reserve_initrd */
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
#include <asm/proto.h>
|
#include <asm/proto.h>
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
/*
|
/*
|
||||||
* Some notes on x86 processor bugs affecting SMP operation:
|
* Some notes on x86 processor bugs affecting SMP operation:
|
||||||
*
|
*
|
||||||
|
|
|
@ -60,12 +60,11 @@
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/mtrr.h>
|
#include <asm/mtrr.h>
|
||||||
#include <asm/vmi.h>
|
#include <asm/vmi.h>
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include <asm/uv/uv.h>
|
#include <asm/uv/uv.h>
|
||||||
#include <linux/mc146818rtc.h>
|
#include <linux/mc146818rtc.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/smpboot_hooks.h>
|
#include <asm/smpboot_hooks.h>
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
|
@ -746,21 +745,21 @@ static void __cpuinit do_fork_idle(struct work_struct *work)
|
||||||
complete(&c_idle->done);
|
complete(&c_idle->done);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __cpuinit do_boot_cpu(int apicid, int cpu)
|
|
||||||
/*
|
/*
|
||||||
* NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
|
* NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
|
||||||
* (ie clustered apic addressing mode), this is a LOGICAL apic ID.
|
* (ie clustered apic addressing mode), this is a LOGICAL apic ID.
|
||||||
* Returns zero if CPU booted OK, else error code from ->wakeup_cpu.
|
* Returns zero if CPU booted OK, else error code from ->wakeup_cpu.
|
||||||
*/
|
*/
|
||||||
|
static int __cpuinit do_boot_cpu(int apicid, int cpu)
|
||||||
{
|
{
|
||||||
unsigned long boot_error = 0;
|
unsigned long boot_error = 0;
|
||||||
int timeout;
|
|
||||||
unsigned long start_ip;
|
unsigned long start_ip;
|
||||||
unsigned short nmi_high = 0, nmi_low = 0;
|
int timeout;
|
||||||
struct create_idle c_idle = {
|
struct create_idle c_idle = {
|
||||||
.cpu = cpu,
|
.cpu = cpu,
|
||||||
.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
|
.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
|
||||||
};
|
};
|
||||||
|
|
||||||
INIT_WORK(&c_idle.work, do_fork_idle);
|
INIT_WORK(&c_idle.work, do_fork_idle);
|
||||||
|
|
||||||
alternatives_smp_switch(1);
|
alternatives_smp_switch(1);
|
||||||
|
@ -825,9 +824,6 @@ do_rest:
|
||||||
|
|
||||||
pr_debug("Setting warm reset code and vector.\n");
|
pr_debug("Setting warm reset code and vector.\n");
|
||||||
|
|
||||||
if (apic->store_NMI_vector)
|
|
||||||
apic->store_NMI_vector(&nmi_high, &nmi_low);
|
|
||||||
|
|
||||||
smpboot_setup_warm_reset_vector(start_ip);
|
smpboot_setup_warm_reset_vector(start_ip);
|
||||||
/*
|
/*
|
||||||
* Be paranoid about clearing APIC errors.
|
* Be paranoid about clearing APIC errors.
|
||||||
|
@ -1128,8 +1124,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
|
||||||
current_thread_info()->cpu = 0; /* needed? */
|
current_thread_info()->cpu = 0; /* needed? */
|
||||||
set_cpu_sibling_map(0);
|
set_cpu_sibling_map(0);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
enable_IR_x2apic();
|
enable_IR_x2apic();
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
default_setup_apic_routing();
|
default_setup_apic_routing();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1154,13 +1150,12 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
|
||||||
*/
|
*/
|
||||||
setup_local_APIC();
|
setup_local_APIC();
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
/*
|
/*
|
||||||
* Enable IO APIC before setting up error vector
|
* Enable IO APIC before setting up error vector
|
||||||
*/
|
*/
|
||||||
if (!skip_ioapic_setup && nr_ioapics)
|
if (!skip_ioapic_setup && nr_ioapics)
|
||||||
enable_IO_APIC();
|
enable_IO_APIC();
|
||||||
#endif
|
|
||||||
end_local_APIC_setup();
|
end_local_APIC_setup();
|
||||||
|
|
||||||
map_cpu_to_logical_apicid();
|
map_cpu_to_logical_apicid();
|
||||||
|
|
|
@ -34,13 +34,11 @@
|
||||||
/*
|
/*
|
||||||
* APIC driver for the IBM "Summit" chipset.
|
* APIC driver for the IBM "Summit" chipset.
|
||||||
*/
|
*/
|
||||||
#define APIC_DEFINITION 1
|
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
#include <linux/cpumask.h>
|
#include <linux/cpumask.h>
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
#include <asm/genapic.h>
|
|
||||||
#include <asm/fixmap.h>
|
#include <asm/fixmap.h>
|
||||||
#include <asm/apicdef.h>
|
#include <asm/apicdef.h>
|
||||||
#include <asm/ipi.h>
|
#include <asm/ipi.h>
|
||||||
|
@ -209,16 +207,12 @@ static inline unsigned long summit_check_apicid_present(int bit)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define apicid_cluster(apicid) ((apicid) & XAPIC_DEST_CLUSTER_MASK)
|
|
||||||
|
|
||||||
extern u8 cpu_2_logical_apicid[];
|
|
||||||
|
|
||||||
static inline void summit_init_apic_ldr(void)
|
static inline void summit_init_apic_ldr(void)
|
||||||
{
|
{
|
||||||
unsigned long val, id;
|
unsigned long val, id;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
u8 my_id = (u8)hard_smp_processor_id();
|
u8 my_id = (u8)hard_smp_processor_id();
|
||||||
u8 my_cluster = (u8)apicid_cluster(my_id);
|
u8 my_cluster = APIC_CLUSTER(my_id);
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
u8 lid;
|
u8 lid;
|
||||||
int i;
|
int i;
|
||||||
|
@ -226,7 +220,7 @@ static inline void summit_init_apic_ldr(void)
|
||||||
/* Create logical APIC IDs by counting CPUs already in cluster. */
|
/* Create logical APIC IDs by counting CPUs already in cluster. */
|
||||||
for (count = 0, i = nr_cpu_ids; --i >= 0; ) {
|
for (count = 0, i = nr_cpu_ids; --i >= 0; ) {
|
||||||
lid = cpu_2_logical_apicid[i];
|
lid = cpu_2_logical_apicid[i];
|
||||||
if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster)
|
if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster)
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -266,7 +260,7 @@ static inline int summit_cpu_to_logical_apicid(int cpu)
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
if (cpu >= nr_cpu_ids)
|
if (cpu >= nr_cpu_ids)
|
||||||
return BAD_APICID;
|
return BAD_APICID;
|
||||||
return (int)cpu_2_logical_apicid[cpu];
|
return cpu_2_logical_apicid[cpu];
|
||||||
#else
|
#else
|
||||||
return logical_smp_processor_id();
|
return logical_smp_processor_id();
|
||||||
#endif
|
#endif
|
||||||
|
@ -323,8 +317,7 @@ static inline unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
|
||||||
if (cpu_isset(cpu, *cpumask)) {
|
if (cpu_isset(cpu, *cpumask)) {
|
||||||
int new_apicid = summit_cpu_to_logical_apicid(cpu);
|
int new_apicid = summit_cpu_to_logical_apicid(cpu);
|
||||||
|
|
||||||
if (apicid_cluster(apicid) !=
|
if (APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
|
||||||
apicid_cluster(new_apicid)) {
|
|
||||||
printk ("%s: Not a valid mask!\n", __func__);
|
printk ("%s: Not a valid mask!\n", __func__);
|
||||||
|
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
|
@ -544,7 +537,7 @@ void __init setup_summit(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct genapic apic_summit = {
|
struct apic apic_summit = {
|
||||||
|
|
||||||
.name = "summit",
|
.name = "summit",
|
||||||
.probe = probe_summit,
|
.probe = probe_summit,
|
||||||
|
@ -597,6 +590,12 @@ struct genapic apic_summit = {
|
||||||
.wait_for_init_deassert = default_wait_for_init_deassert,
|
.wait_for_init_deassert = default_wait_for_init_deassert,
|
||||||
|
|
||||||
.smp_callin_clear_local_apic = NULL,
|
.smp_callin_clear_local_apic = NULL,
|
||||||
.store_NMI_vector = NULL,
|
|
||||||
.inquire_remote_apic = default_inquire_remote_apic,
|
.inquire_remote_apic = default_inquire_remote_apic,
|
||||||
|
|
||||||
|
.read = native_apic_mem_read,
|
||||||
|
.write = native_apic_mem_write,
|
||||||
|
.icr_read = native_apic_icr_read,
|
||||||
|
.icr_write = native_apic_icr_write,
|
||||||
|
.wait_icr_idle = native_apic_wait_icr_idle,
|
||||||
|
.safe_wait_icr_idle = native_safe_apic_wait_icr_idle,
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,13 +15,11 @@
|
||||||
#include <asm/uv/uv_mmrs.h>
|
#include <asm/uv/uv_mmrs.h>
|
||||||
#include <asm/uv/uv_hub.h>
|
#include <asm/uv/uv_hub.h>
|
||||||
#include <asm/uv/uv_bau.h>
|
#include <asm/uv/uv_bau.h>
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/idle.h>
|
#include <asm/idle.h>
|
||||||
#include <asm/tsc.h>
|
#include <asm/tsc.h>
|
||||||
#include <asm/irq_vectors.h>
|
#include <asm/irq_vectors.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
static struct bau_control **uv_bau_table_bases __read_mostly;
|
static struct bau_control **uv_bau_table_bases __read_mostly;
|
||||||
static int uv_bau_retry_limit __read_mostly;
|
static int uv_bau_retry_limit __read_mostly;
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,12 @@ static inline void preempt_conditional_sti(struct pt_regs *regs)
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void conditional_cli(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
if (regs->flags & X86_EFLAGS_IF)
|
||||||
|
local_irq_disable();
|
||||||
|
}
|
||||||
|
|
||||||
static inline void preempt_conditional_cli(struct pt_regs *regs)
|
static inline void preempt_conditional_cli(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
if (regs->flags & X86_EFLAGS_IF)
|
if (regs->flags & X86_EFLAGS_IF)
|
||||||
|
@ -625,8 +631,10 @@ clear_dr7:
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
debug_vm86:
|
debug_vm86:
|
||||||
|
/* reenable preemption: handle_vm86_trap() might sleep */
|
||||||
|
dec_preempt_count();
|
||||||
handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
|
handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
|
||||||
preempt_conditional_cli(regs);
|
conditional_cli(regs);
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -29,13 +29,10 @@
|
||||||
#include <asm/fixmap.h>
|
#include <asm/fixmap.h>
|
||||||
#include <asm/reboot.h>
|
#include <asm/reboot.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
#include <asm/apic.h>
|
||||||
#include <asm/e820.h>
|
#include <asm/e820.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
|
|
||||||
#include <linux/kernel_stat.h>
|
#include <linux/kernel_stat.h>
|
||||||
|
|
||||||
#include <asm/i8259.h>
|
#include <asm/i8259.h>
|
||||||
|
@ -49,8 +46,6 @@
|
||||||
|
|
||||||
extern int no_broadcast;
|
extern int no_broadcast;
|
||||||
|
|
||||||
#include <asm/apic.h>
|
|
||||||
|
|
||||||
char visws_board_type = -1;
|
char visws_board_type = -1;
|
||||||
char visws_board_rev = -1;
|
char visws_board_rev = -1;
|
||||||
|
|
||||||
|
|
|
@ -798,8 +798,8 @@ static inline int __init activate_vmi(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
para_fill(apic_ops->read, APICRead);
|
para_fill(apic->read, APICRead);
|
||||||
para_fill(apic_ops->write, APICWrite);
|
para_fill(apic->write, APICWrite);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -828,13 +828,14 @@ static u32 lguest_apic_safe_wait_icr_idle(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct apic_ops lguest_basic_apic_ops = {
|
static void set_lguest_basic_apic_ops(void)
|
||||||
.read = lguest_apic_read,
|
{
|
||||||
.write = lguest_apic_write,
|
apic->read = lguest_apic_read;
|
||||||
.icr_read = lguest_apic_icr_read,
|
apic->write = lguest_apic_write;
|
||||||
.icr_write = lguest_apic_icr_write,
|
apic->icr_read = lguest_apic_icr_read;
|
||||||
.wait_icr_idle = lguest_apic_wait_icr_idle,
|
apic->icr_write = lguest_apic_icr_write;
|
||||||
.safe_wait_icr_idle = lguest_apic_safe_wait_icr_idle,
|
apic->wait_icr_idle = lguest_apic_wait_icr_idle;
|
||||||
|
apic->safe_wait_icr_idle = lguest_apic_safe_wait_icr_idle;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1035,7 +1036,7 @@ __init void lguest_init(void)
|
||||||
|
|
||||||
#ifdef CONFIG_X86_LOCAL_APIC
|
#ifdef CONFIG_X86_LOCAL_APIC
|
||||||
/* apic read/write intercepts */
|
/* apic read/write intercepts */
|
||||||
apic_ops = &lguest_basic_apic_ops;
|
set_lguest_basic_apic_ops();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* time operations */
|
/* time operations */
|
||||||
|
|
|
@ -1747,10 +1747,11 @@ static void __cpuinit voyager_smp_prepare_boot_cpu(void)
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
switch_to_new_gdt(cpu);
|
switch_to_new_gdt(cpu);
|
||||||
|
|
||||||
cpu_online_map = cpumask_of_cpu(smp_processor_id());
|
cpu_set(cpu, cpu_online_map);
|
||||||
cpu_callout_map = cpumask_of_cpu(smp_processor_id());
|
cpu_set(cpu, cpu_callout_map);
|
||||||
cpu_callin_map = CPU_MASK_NONE;
|
cpu_set(cpu, cpu_possible_map);
|
||||||
cpu_present_map = cpumask_of_cpu(smp_processor_id());
|
cpu_set(cpu, cpu_present_map);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __cpuinit voyager_cpu_up(unsigned int cpu)
|
static int __cpuinit voyager_cpu_up(unsigned int cpu)
|
||||||
|
|
|
@ -851,6 +851,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* kprobes don't want to hook the spurious faults. */
|
||||||
if (unlikely(notify_page_fault(regs)))
|
if (unlikely(notify_page_fault(regs)))
|
||||||
return;
|
return;
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <asm/proto.h>
|
#include <asm/proto.h>
|
||||||
#include <asm/numa.h>
|
#include <asm/numa.h>
|
||||||
#include <asm/e820.h>
|
#include <asm/e820.h>
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/uv/uv.h>
|
#include <asm/uv/uv.h>
|
||||||
|
|
||||||
int acpi_numa __initdata;
|
int acpi_numa __initdata;
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
|
DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
|
||||||
= { &init_mm, 0, };
|
= { &init_mm, 0, };
|
||||||
|
|
||||||
#include <asm/genapic.h>
|
|
||||||
/*
|
/*
|
||||||
* Smarter SMP flushing macros.
|
* Smarter SMP flushing macros.
|
||||||
* c/o Linus Torvalds.
|
* c/o Linus Torvalds.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/nodemask.h>
|
#include <linux/nodemask.h>
|
||||||
#include <asm/genapic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/mpspec.h>
|
#include <asm/mpspec.h>
|
||||||
#include <asm/pci_x86.h>
|
#include <asm/pci_x86.h>
|
||||||
|
|
||||||
|
|
|
@ -554,14 +554,15 @@ static u32 xen_safe_apic_wait_icr_idle(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct apic_ops xen_basic_apic_ops = {
|
static void set_xen_basic_apic_ops(void)
|
||||||
.read = xen_apic_read,
|
{
|
||||||
.write = xen_apic_write,
|
apic->read = xen_apic_read;
|
||||||
.icr_read = xen_apic_icr_read,
|
apic->write = xen_apic_write;
|
||||||
.icr_write = xen_apic_icr_write,
|
apic->icr_read = xen_apic_icr_read;
|
||||||
.wait_icr_idle = xen_apic_wait_icr_idle,
|
apic->icr_write = xen_apic_icr_write;
|
||||||
.safe_wait_icr_idle = xen_safe_apic_wait_icr_idle,
|
apic->wait_icr_idle = xen_apic_wait_icr_idle;
|
||||||
};
|
apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -898,7 +899,7 @@ asmlinkage void __init xen_start_kernel(void)
|
||||||
/*
|
/*
|
||||||
* set up the basic apic ops.
|
* set up the basic apic ops.
|
||||||
*/
|
*/
|
||||||
apic_ops = &xen_basic_apic_ops;
|
set_xen_basic_apic_ops();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
|
if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
|
||||||
|
|
|
@ -1273,8 +1273,6 @@ static void xen_flush_tlb_others(const struct cpumask *cpus,
|
||||||
/* Remove us, and any offline CPUS. */
|
/* Remove us, and any offline CPUS. */
|
||||||
cpumask_and(to_cpumask(args->mask), cpus, cpu_online_mask);
|
cpumask_and(to_cpumask(args->mask), cpus, cpu_online_mask);
|
||||||
cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask));
|
cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask));
|
||||||
if (unlikely(cpumask_empty(to_cpumask(args->mask))))
|
|
||||||
goto issue;
|
|
||||||
|
|
||||||
if (va == TLB_FLUSH_ALL) {
|
if (va == TLB_FLUSH_ALL) {
|
||||||
args->op.cmd = MMUEXT_TLB_FLUSH_MULTI;
|
args->op.cmd = MMUEXT_TLB_FLUSH_MULTI;
|
||||||
|
@ -1285,7 +1283,6 @@ static void xen_flush_tlb_others(const struct cpumask *cpus,
|
||||||
|
|
||||||
MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF);
|
MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF);
|
||||||
|
|
||||||
issue:
|
|
||||||
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
xen_mc_issue(PARAVIRT_LAZY_MMU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ struct mc_buffer {
|
||||||
struct multicall_entry entries[MC_BATCH];
|
struct multicall_entry entries[MC_BATCH];
|
||||||
#if MC_DEBUG
|
#if MC_DEBUG
|
||||||
struct multicall_entry debug[MC_BATCH];
|
struct multicall_entry debug[MC_BATCH];
|
||||||
|
void *caller[MC_BATCH];
|
||||||
#endif
|
#endif
|
||||||
unsigned char args[MC_ARGS];
|
unsigned char args[MC_ARGS];
|
||||||
struct callback {
|
struct callback {
|
||||||
|
@ -154,11 +155,12 @@ void xen_mc_flush(void)
|
||||||
ret, smp_processor_id());
|
ret, smp_processor_id());
|
||||||
dump_stack();
|
dump_stack();
|
||||||
for (i = 0; i < b->mcidx; i++) {
|
for (i = 0; i < b->mcidx; i++) {
|
||||||
printk(KERN_DEBUG " call %2d/%d: op=%lu arg=[%lx] result=%ld\n",
|
printk(KERN_DEBUG " call %2d/%d: op=%lu arg=[%lx] result=%ld\t%pF\n",
|
||||||
i+1, b->mcidx,
|
i+1, b->mcidx,
|
||||||
b->debug[i].op,
|
b->debug[i].op,
|
||||||
b->debug[i].args[0],
|
b->debug[i].args[0],
|
||||||
b->entries[i].result);
|
b->entries[i].result,
|
||||||
|
b->caller[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -168,8 +170,6 @@ void xen_mc_flush(void)
|
||||||
} else
|
} else
|
||||||
BUG_ON(b->argidx != 0);
|
BUG_ON(b->argidx != 0);
|
||||||
|
|
||||||
local_irq_restore(flags);
|
|
||||||
|
|
||||||
for (i = 0; i < b->cbidx; i++) {
|
for (i = 0; i < b->cbidx; i++) {
|
||||||
struct callback *cb = &b->callbacks[i];
|
struct callback *cb = &b->callbacks[i];
|
||||||
|
|
||||||
|
@ -177,7 +177,9 @@ void xen_mc_flush(void)
|
||||||
}
|
}
|
||||||
b->cbidx = 0;
|
b->cbidx = 0;
|
||||||
|
|
||||||
BUG_ON(ret);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
|
WARN_ON(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct multicall_space __xen_mc_entry(size_t args)
|
struct multicall_space __xen_mc_entry(size_t args)
|
||||||
|
@ -197,6 +199,9 @@ struct multicall_space __xen_mc_entry(size_t args)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.mc = &b->entries[b->mcidx];
|
ret.mc = &b->entries[b->mcidx];
|
||||||
|
#ifdef MC_DEBUG
|
||||||
|
b->caller[b->mcidx] = __builtin_return_address(0);
|
||||||
|
#endif
|
||||||
b->mcidx++;
|
b->mcidx++;
|
||||||
ret.args = &b->args[argidx];
|
ret.args = &b->args[argidx];
|
||||||
b->argidx = argidx + args;
|
b->argidx = argidx + args;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#ifndef _XTENSA_SWAB_H
|
#ifndef _XTENSA_SWAB_H
|
||||||
#define _XTENSA_SWAB_H
|
#define _XTENSA_SWAB_H
|
||||||
|
|
||||||
#include <asm/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
#define __SWAB_64_THRU_32__
|
#define __SWAB_64_THRU_32__
|
||||||
|
|
|
@ -2519,8 +2519,8 @@ fore200e_load_and_start_fw(struct fore200e* fore200e)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
|
sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
|
||||||
if (request_firmware(&firmware, buf, device) == 1) {
|
if ((err = request_firmware(&firmware, buf, device)) < 0) {
|
||||||
printk(FORE200E "missing %s firmware image\n", fore200e->bus->model_name);
|
printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -493,21 +493,27 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
|
||||||
}
|
}
|
||||||
/* read the data */
|
/* read the data */
|
||||||
spin_lock_irqsave(&adapter->lock, flags);
|
spin_lock_irqsave(&adapter->lock, flags);
|
||||||
i = 0;
|
for (i = 0; i < MAX_PCB_DATA; i++) {
|
||||||
do {
|
for (j = 0; j < 20000; j++) {
|
||||||
j = 0;
|
stat = get_status(dev->base_addr);
|
||||||
while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000);
|
if (stat & ACRF)
|
||||||
pcb->data.raw[i++] = inb_command(dev->base_addr);
|
break;
|
||||||
if (i > MAX_PCB_DATA)
|
}
|
||||||
INVALID_PCB_MSG(i);
|
pcb->data.raw[i] = inb_command(dev->base_addr);
|
||||||
} while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000);
|
if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000)
|
||||||
|
break;
|
||||||
|
}
|
||||||
spin_unlock_irqrestore(&adapter->lock, flags);
|
spin_unlock_irqrestore(&adapter->lock, flags);
|
||||||
|
if (i >= MAX_PCB_DATA) {
|
||||||
|
INVALID_PCB_MSG(i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (j >= 20000) {
|
if (j >= 20000) {
|
||||||
TIMEOUT_MSG(__LINE__);
|
TIMEOUT_MSG(__LINE__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* woops, the last "data" byte was really the length! */
|
/* the last "data" byte was really the length! */
|
||||||
total_length = pcb->data.raw[--i];
|
total_length = pcb->data.raw[i];
|
||||||
|
|
||||||
/* safety check total length vs data length */
|
/* safety check total length vs data length */
|
||||||
if (total_length != (pcb->length + 2)) {
|
if (total_length != (pcb->length + 2)) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* bnx2.c: Broadcom NX2 network driver.
|
/* bnx2.c: Broadcom NX2 network driver.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2008 Broadcom Corporation
|
* Copyright (c) 2004-2009 Broadcom Corporation
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -57,8 +57,8 @@
|
||||||
|
|
||||||
#define DRV_MODULE_NAME "bnx2"
|
#define DRV_MODULE_NAME "bnx2"
|
||||||
#define PFX DRV_MODULE_NAME ": "
|
#define PFX DRV_MODULE_NAME ": "
|
||||||
#define DRV_MODULE_VERSION "1.9.0"
|
#define DRV_MODULE_VERSION "1.9.2"
|
||||||
#define DRV_MODULE_RELDATE "Dec 16, 2008"
|
#define DRV_MODULE_RELDATE "Feb 11, 2009"
|
||||||
|
|
||||||
#define RUN_AT(x) (jiffies + (x))
|
#define RUN_AT(x) (jiffies + (x))
|
||||||
|
|
||||||
|
@ -2910,18 +2910,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
|
||||||
|
|
||||||
rx_hdr = (struct l2_fhdr *) skb->data;
|
rx_hdr = (struct l2_fhdr *) skb->data;
|
||||||
len = rx_hdr->l2_fhdr_pkt_len;
|
len = rx_hdr->l2_fhdr_pkt_len;
|
||||||
|
status = rx_hdr->l2_fhdr_status;
|
||||||
|
|
||||||
if ((status = rx_hdr->l2_fhdr_status) &
|
|
||||||
(L2_FHDR_ERRORS_BAD_CRC |
|
|
||||||
L2_FHDR_ERRORS_PHY_DECODE |
|
|
||||||
L2_FHDR_ERRORS_ALIGNMENT |
|
|
||||||
L2_FHDR_ERRORS_TOO_SHORT |
|
|
||||||
L2_FHDR_ERRORS_GIANT_FRAME)) {
|
|
||||||
|
|
||||||
bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
|
|
||||||
sw_ring_prod);
|
|
||||||
goto next_rx;
|
|
||||||
}
|
|
||||||
hdr_len = 0;
|
hdr_len = 0;
|
||||||
if (status & L2_FHDR_STATUS_SPLIT) {
|
if (status & L2_FHDR_STATUS_SPLIT) {
|
||||||
hdr_len = rx_hdr->l2_fhdr_ip_xsum;
|
hdr_len = rx_hdr->l2_fhdr_ip_xsum;
|
||||||
|
@ -2931,6 +2921,24 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
|
||||||
pg_ring_used = 1;
|
pg_ring_used = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unlikely(status & (L2_FHDR_ERRORS_BAD_CRC |
|
||||||
|
L2_FHDR_ERRORS_PHY_DECODE |
|
||||||
|
L2_FHDR_ERRORS_ALIGNMENT |
|
||||||
|
L2_FHDR_ERRORS_TOO_SHORT |
|
||||||
|
L2_FHDR_ERRORS_GIANT_FRAME))) {
|
||||||
|
|
||||||
|
bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
|
||||||
|
sw_ring_prod);
|
||||||
|
if (pg_ring_used) {
|
||||||
|
int pages;
|
||||||
|
|
||||||
|
pages = PAGE_ALIGN(len - hdr_len) >> PAGE_SHIFT;
|
||||||
|
|
||||||
|
bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages);
|
||||||
|
}
|
||||||
|
goto next_rx;
|
||||||
|
}
|
||||||
|
|
||||||
len -= 4;
|
len -= 4;
|
||||||
|
|
||||||
if (len <= bp->rx_copy_thresh) {
|
if (len <= bp->rx_copy_thresh) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* bnx2.h: Broadcom NX2 network driver.
|
/* bnx2.h: Broadcom NX2 network driver.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004-2007 Broadcom Corporation
|
* Copyright (c) 2004-2009 Broadcom Corporation
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче