Commit e171bd13 authored by Linus Torvalds's avatar Linus Torvalds Committed by Linus Torvalds

[PATCH] Fix missing part of x86-64 update

Three quarters of the update from Andi was uncommitted due to a bad
patch date and a bug in "bk import -temail"..

Here are the missing parts..
parent 78e8fcd6
......@@ -9,7 +9,7 @@
* Erich Boleyn : MP v1.4 and additional changes.
* Alan Cox : Added EBDA scanning
* Ingo Molnar : various cleanups and rewrites
* Maciej W. Rozycki : Bits for default MP configurations
* Maciej W. Rozycki: Bits for default MP configurations
* Paul Diefenbaugh: Added full ACPI support
*/
......@@ -690,25 +690,25 @@ void __init mp_register_lapic (
struct mp_ioapic_routing {
int apic_id;
int irq_start;
int irq_end;
int gsi_start;
int gsi_end;
u32 pin_programmed[4];
} mp_ioapic_routing[MAX_IO_APICS];
static int __init mp_find_ioapic (
int irq)
int gsi)
{
int i = 0;
/* Find the IOAPIC that manages this IRQ. */
/* Find the IOAPIC that manages this GSI. */
for (i = 0; i < nr_ioapics; i++) {
if ((irq >= mp_ioapic_routing[i].irq_start)
&& (irq <= mp_ioapic_routing[i].irq_end))
if ((gsi >= mp_ioapic_routing[i].gsi_start)
&& (gsi <= mp_ioapic_routing[i].gsi_end))
return i;
}
printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d\n", irq);
printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
return -1;
}
......@@ -717,7 +717,7 @@ static int __init mp_find_ioapic (
void __init mp_register_ioapic (
u8 id,
u32 address,
u32 irq_base)
u32 gsi_base)
{
int idx = 0;
......@@ -743,19 +743,19 @@ void __init mp_register_ioapic (
mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
/*
* Build basic IRQ lookup table to facilitate irq->io_apic lookups
* Build basic IRQ lookup table to facilitate gsi->io_apic lookups
* and to prevent reprogramming of IOAPIC pins (PCI IRQs).
*/
mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid;
mp_ioapic_routing[idx].irq_start = irq_base;
mp_ioapic_routing[idx].irq_end = irq_base +
mp_ioapic_routing[idx].gsi_start = gsi_base;
mp_ioapic_routing[idx].gsi_end = gsi_base +
io_apic_get_redir_entries(idx);
printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
"IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
"GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
mp_ioapic_routing[idx].irq_start,
mp_ioapic_routing[idx].irq_end);
mp_ioapic_routing[idx].gsi_start,
mp_ioapic_routing[idx].gsi_end);
return;
}
......@@ -765,7 +765,7 @@ void __init mp_override_legacy_irq (
u8 bus_irq,
u8 polarity,
u8 trigger,
u32 global_irq)
u32 gsi)
{
struct mpc_config_intsrc intsrc;
int i = 0;
......@@ -774,12 +774,12 @@ void __init mp_override_legacy_irq (
int pin = -1;
/*
* Convert 'global_irq' to 'ioapic.pin'.
* Convert 'gsi' to 'ioapic.pin'.
*/
ioapic = mp_find_ioapic(global_irq);
ioapic = mp_find_ioapic(gsi);
if (ioapic < 0)
return;
pin = global_irq - mp_ioapic_routing[ioapic].irq_start;
pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
/*
* TBD: This check is for faulty timer entries, where the override
......@@ -804,7 +804,7 @@ void __init mp_override_legacy_irq (
/*
* If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it.
* Otherwise create a new entry (e.g. global_irq == 2).
* Otherwise create a new entry (e.g. gsi == 2).
*/
for (i = 0; i < mp_irq_entries; i++) {
if ((mp_irqs[i].mpc_srcbus == intsrc.mpc_srcbus)
......@@ -878,7 +878,7 @@ void __init mp_config_acpi_legacy_irqs (void)
extern FADT_DESCRIPTOR acpi_fadt;
void __init mp_config_ioapic_for_sci(int irq)
void __init mp_config_ioapic_for_sci(u32 gsi)
{
#ifdef CONFIG_ACPI_INTERPRETER
int ioapic;
......@@ -926,11 +926,11 @@ void __init mp_config_ioapic_for_sci(int irq)
*/
flags = entry->flags;
acpi_fadt.sci_int = entry->global_irq;
irq = entry->global_irq;
gsi = entry->global_irq;
ioapic = mp_find_ioapic(irq);
ioapic = mp_find_ioapic(gsi);
ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
/*
* MPS INTI flags:
......@@ -938,7 +938,7 @@ void __init mp_config_ioapic_for_sci(int irq)
* polarity: 0=default, 1=high, 3=low
* Per ACPI spec, default for SCI means level/low.
*/
io_apic_set_pci_routing(ioapic, ioapic_pin, irq,
io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
(flags.trigger == 1 ? 0 : 1), (flags.polarity == 1 ? 0 : 1));
#endif
}
......@@ -951,7 +951,7 @@ void __init mp_parse_prt (void)
struct acpi_prt_entry *entry = NULL;
int ioapic = -1;
int ioapic_pin = 0;
int irq = 0;
int gsi = 0;
int idx, bit = 0;
int edge_level = 0;
int active_high_low = 0;
......@@ -963,30 +963,30 @@ void __init mp_parse_prt (void)
list_for_each(node, &acpi_prt.entries) {
entry = list_entry(node, struct acpi_prt_entry, node);
/* Need to get irq for dynamic entry */
/* Need to get gsi for dynamic entry */
if (entry->link.handle) {
irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
if (!irq)
gsi = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, &edge_level, &active_high_low);
if (!gsi)
continue;
} else {
/* Hardwired IRQ. Assume PCI standard settings */
irq = entry->link.index;
/* Hardwired GSI. Assume PCI standard settings */
gsi = entry->link.index;
edge_level = 1;
active_high_low = 1;
}
/* Don't set up the ACPI SCI because it's already set up */
if (acpi_fadt.sci_int == irq)
if (acpi_fadt.sci_int == gsi)
continue;
ioapic = mp_find_ioapic(irq);
ioapic = mp_find_ioapic(gsi);
if (ioapic < 0)
continue;
ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
/*
* Avoid pin reprogramming. PRTs typically include entries
* with redundant pin->irq mappings (but unique PCI devices);
* with redundant pin->gsi mappings (but unique PCI devices);
* we only only program the IOAPIC on the first.
*/
bit = ioapic_pin % 32;
......@@ -1000,20 +1000,16 @@ void __init mp_parse_prt (void)
if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
if (use_pci_vector() && !platform_legacy_irq(irq))
irq = IO_APIC_VECTOR(irq);
entry->irq = irq;
acpi_gsi_to_irq(gsi, &entry->irq);
continue;
}
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq, edge_level, active_high_low)) {
if (use_pci_vector() && !platform_legacy_irq(irq))
irq = IO_APIC_VECTOR(irq);
entry->irq = irq;
if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, edge_level, active_high_low)) {
acpi_gsi_to_irq(gsi, &entry->irq);
}
printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d"
" -> IRQ %d\n", entry->id.segment, entry->id.bus,
printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
entry->id.segment, entry->id.bus,
entry->id.device, ('A' + entry->pin),
mp_ioapic_routing[ioapic].apic_id, ioapic_pin,
entry->irq);
......
......@@ -21,6 +21,7 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/topology.h>
#include <linux/interrupt.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/mtrr.h>
......@@ -31,6 +32,12 @@
#include <asm/kdebug.h>
#include <asm/proto.h>
#ifdef CONFIG_PREEMPT
#define preempt_atomic() in_atomic()
#else
#define preempt_atomic() 1
#endif
dma_addr_t bad_dma_address;
unsigned long iommu_bus_base; /* GART remapping area (physical) */
......@@ -96,6 +103,8 @@ AGPEXTERN __u32 *agp_gatt_table;
static unsigned long next_bit; /* protected by iommu_bitmap_lock */
static int need_flush; /* global flush state. set for each gart wrap */
static dma_addr_t pci_map_area(struct pci_dev *dev, unsigned long phys_mem,
size_t size, int dir);
static unsigned long alloc_iommu(int size)
{
......@@ -169,43 +178,44 @@ static void flush_gart(struct pci_dev *dev)
/*
* Allocate memory for a consistent mapping.
* All mappings are consistent here, so this is just a wrapper around
* pci_map_single.
*/
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle)
{
void *memory;
int gfp = GFP_ATOMIC;
unsigned long dma_mask;
int gfp = preempt_atomic() ? GFP_ATOMIC : GFP_KERNEL;
unsigned long dma_mask = 0;
u64 bus;
if (hwdev == NULL) {
gfp |= GFP_DMA;
dma_mask = 0xffffffff;
} else {
if (hwdev)
dma_mask = hwdev->dev.coherent_dma_mask;
}
if (dma_mask == 0)
dma_mask = 0xffffffff;
if (dma_mask < 0xffffffff || no_iommu)
gfp |= GFP_DMA;
/* Kludge to make it bug-to-bug compatible with i386. i386
uses the normal dma_mask for alloc_consistent. */
dma_mask &= hwdev->dma_mask;
again:
memory = (void *)__get_free_pages(gfp, get_order(size));
if (memory == NULL) {
if (memory == NULL)
return NULL;
} else {
{
int high, mmu;
high = ((unsigned long)virt_to_bus(memory) + size) >= dma_mask;
bus = virt_to_bus(memory);
high = (bus + size) >= dma_mask;
mmu = high;
if (force_iommu && !(gfp & GFP_DMA))
mmu = 1;
if (no_iommu) {
if (high) goto error;
if (no_iommu || dma_mask < 0xffffffffUL) {
if (high) {
if (!(gfp & GFP_DMA)) {
gfp |= GFP_DMA;
goto again;
}
goto free;
}
mmu = 0;
}
memset(memory, 0, size);
......@@ -215,15 +225,16 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
}
}
*dma_handle = pci_map_single(hwdev, memory, size, 0);
*dma_handle = pci_map_area(hwdev, bus, size, PCI_DMA_BIDIRECTIONAL);
if (*dma_handle == bad_dma_address)
goto error;
flush_gart(hwdev);
return memory;
error:
if (panic_on_overflow)
panic("pci_map_single: overflow %lu bytes\n", size);
panic("pci_alloc_consistent: overflow %lu bytes\n", size);
free:
free_pages((unsigned long)memory, get_order(size));
return NULL;
}
......@@ -608,6 +619,7 @@ EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_dma_supported);
EXPORT_SYMBOL(no_iommu);
EXPORT_SYMBOL(force_iommu);
EXPORT_SYMBOL(bad_dma_address);
static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
{
......@@ -733,7 +745,7 @@ static int __init pci_iommu_init(void)
if (swiotlb) {
no_iommu = 1;
printk(KERN_INFO "PCI-DMA: Using SWIOTLB :-(\n");
printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
return -1;
}
......@@ -837,6 +849,7 @@ fs_initcall(pci_iommu_init);
forcesac For SAC mode for masks <40bits (experimental)
fullflush Flush IOMMU on each allocation (default)
nofullflush Don't use IOMMU fullflush
soft Use software bounce buffering (default for Intel machines)
*/
__init int iommu_setup(char *opt)
{
......@@ -876,6 +889,8 @@ __init int iommu_setup(char *opt)
iommu_fullflush = 1;
if (!memcmp(p, "nofullflush", 11))
iommu_fullflush = 0;
if (!memcmp(p, "soft", 4))
swiotlb = 1;
#ifdef CONFIG_IOMMU_LEAK
if (!memcmp(p,"leak", 4)) {
leak_trace = 1;
......
......@@ -32,6 +32,7 @@
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/ptrace.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
......@@ -205,7 +206,8 @@ void __show_regs(struct pt_regs * regs)
printk("\n");
print_modules();
printk("Pid: %d, comm: %.20s %s\n", current->pid, current->comm, print_tainted());
printk("Pid: %d, comm: %.20s %s %s\n",
current->pid, current->comm, print_tainted(), UTS_RELEASE);
printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
printk_address(regs->rip);
printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp, regs->eflags);
......
......@@ -232,7 +232,7 @@ static __init void parse_cmdline_early (char ** cmdline_p)
if (!memcmp(from, "noapic", 6))
skip_ioapic_setup = 1;
if (!memcmp(from, "apic", 6)) {
if (!memcmp(from, "apic", 4)) {
skip_ioapic_setup = 0;
ioapic_force = 1;
}
......@@ -453,9 +453,7 @@ void __init setup_arch(char **cmdline_p)
paging_init();
#ifndef CONFIG_SMP
/* Temporary hack: disable the IO-APIC for UP Nvidia and
This is until we sort out the ACPI problems. */
if (!acpi_disabled)
/* Temporary hack: disable the IO-APIC for UP Nvidia and VIA. */
check_ioapic();
#endif
#ifdef CONFIG_ACPI_BOOT
......
......@@ -405,10 +405,10 @@ void __init mem_init(void)
int tmp;
#ifdef CONFIG_SWIOTLB
if (!iommu_aperture && end_pfn >= 0xffffffff>>PAGE_SHIFT) {
swiotlb_init();
if (!iommu_aperture && end_pfn >= 0xffffffff>>PAGE_SHIFT)
swiotlb = 1;
}
if (swiotlb)
swiotlb_init();
#endif
/* How many end-of-memory variables you have, grandma! */
......
......@@ -88,7 +88,7 @@ static int __init pci_mmcfg_init(void)
return 0;
}
printk(KERN_INFO "PCI: Using MMCONFIG at %lx\n", pci_mmcfg_base_addr);
printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr);
raw_pci_ops = &pci_mmcfg;
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
......
......@@ -110,6 +110,8 @@ static int rtc_has_irq = 1;
#define hpet_rtc_timer_init() do { } while (0)
#define hpet_rtc_dropped_irq() 0
static inline irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {return 0;}
#else
extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
#endif
/*
......
......@@ -109,6 +109,8 @@ extern int acpi_strict;
/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
#define FIX_ACPI_PAGES 4
extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
#else /* !CONFIG_ACPI_BOOT */
#define acpi_lapic 0
#define acpi_ioapic 0
......
......@@ -35,28 +35,28 @@
subq $9*8+\addskip,%rsp
CFI_ADJUST_CFA_OFFSET 9*8+\addskip
movq %rdi,8*8(%rsp)
CFI_OFFSET rdi,8*8-(9*8+\addskip)
CFI_REL_OFFSET rdi,8*8
movq %rsi,7*8(%rsp)
CFI_OFFSET rsi,7*8-(9*8+\addskip)
CFI_REL_OFFSET rsi,7*8
movq %rdx,6*8(%rsp)
CFI_OFFSET rdx,6*8-(9*8+\addskip)
CFI_REL_OFFSET rdx,6*8
.if \norcx
.else
movq %rcx,5*8(%rsp)
CFI_OFFSET rcx,5*8-(9*8+\addskip)
CFI_REL_OFFSET rcx,5*8
.endif
movq %rax,4*8(%rsp)
CFI_OFFSET rax,4*8-(9*8+\addskip)
CFI_REL_OFFSET rax,4*8
.if \nor891011
.else
movq %r8,3*8(%rsp)
CFI_OFFSET r8,3*8-(9*8+\addskip)
CFI_REL_OFFSET r8,3*8
movq %r9,2*8(%rsp)
CFI_OFFSET r9,2*8-(9*8+\addskip)
CFI_REL_OFFSET r9,2*8
movq %r10,1*8(%rsp)
CFI_OFFSET r10,1*8-(9*8+\addskip)
CFI_REL_OFFSET r10,1*8
movq %r11,(%rsp)
CFI_OFFSET r11,-(9*8+\addskip)
CFI_OFFSET r11
.endif
.endm
......@@ -109,17 +109,17 @@
subq $REST_SKIP,%rsp
CFI_ADJUST_CFA_OFFSET REST_SKIP
movq %rbx,5*8(%rsp)
CFI_OFFSET rbx,5*8-(REST_SKIP)
CFI_REL_OFFSET rbx,5*8
movq %rbp,4*8(%rsp)
CFI_OFFSET rbp,4*8-(REST_SKIP)
CFI_REL_OFFSET rbp,4*8
movq %r12,3*8(%rsp)
CFI_OFFSET r12,3*8-(REST_SKIP)
CFI_REL_OFFSET r12,3*8
movq %r13,2*8(%rsp)
CFI_OFFSET r13,2*8-(REST_SKIP)
CFI_REL_OFFSET r13,2*8
movq %r14,1*8(%rsp)
CFI_OFFSET r14,1*8-(REST_SKIP)
CFI_REL_OFFSET r14,1*8
movq %r15,(%rsp)
CFI_OFFSET r15,0*8-(REST_SKIP)
CFI_REL_OFFSET r15,0*8
.endm
.macro RESTORE_REST
......
......@@ -78,6 +78,7 @@
#ifdef CONFIG_PREEMPT
# include <linux/smp_lock.h>
# define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else
......
#ifndef _ASM_X8664_HPET_H
#define _ASM_X8664_HPET_H 1
#include <linux/interrupt.h>
/*
* Documentation on HPET can be found at:
* http://www.intel.com/ial/home/sp/pcmmspec.htm
......@@ -53,7 +51,6 @@ extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned ch
extern int hpet_set_periodic_freq(unsigned long freq);
extern int hpet_rtc_dropped_irq(void);
extern int hpet_rtc_timer_init(void);
extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
#endif /* CONFIG_HPET_EMULATE_RTC */
#endif
......@@ -186,14 +186,14 @@ extern void mp_register_lapic (u8 id, u8 enabled);
extern void mp_register_lapic_address (u64 address);
#ifdef CONFIG_X86_IO_APIC
extern void mp_register_ioapic (u8 id, u32 address, u32 irq_base);
extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 global_irq);
extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
extern void mp_config_acpi_legacy_irqs (void);
extern void mp_parse_prt (void);
#endif /*CONFIG_X86_IO_APIC*/
#endif
extern void mp_config_ioapic_for_sci(int irq);
extern void mp_config_ioapic_for_sci(u32 gsi);
extern int using_apic_timer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment