Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 38424
b: refs/heads/master
c: 589e367
h: refs/heads/master
v: v3
  • Loading branch information
Eric W. Biederman authored and Linus Torvalds committed Oct 4, 2006
1 parent 40931c0 commit ac66b65
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1ce03373a7f4b5fa8ca5be02ff35229800a6e12b
refs/heads/master: 589e367f9b9117b3412da0d4e10ea6882db8da84
74 changes: 74 additions & 0 deletions trunk/arch/x86_64/kernel/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/mc146818rtc.h>
#include <linux/acpi.h>
#include <linux/sysdev.h>
Expand All @@ -41,6 +42,7 @@
#include <asm/acpi.h>
#include <asm/dma.h>
#include <asm/nmi.h>
#include <asm/msidef.h>

#define __apicdebuginit __init

Expand Down Expand Up @@ -1739,6 +1741,78 @@ void destroy_irq(unsigned int irq)
}
#endif

/*
* MSI mesage composition
*/
#ifdef CONFIG_PCI_MSI
static int msi_msg_setup(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
{
/* For now always this code always uses physical delivery
* mode.
*/
int vector;
unsigned dest;

vector = assign_irq_vector(irq);
if (vector >= 0) {
cpumask_t tmp;

cpus_clear(tmp);
cpu_set(first_cpu(cpu_online_map), tmp);
dest = cpu_mask_to_apicid(tmp);

msg->address_hi = MSI_ADDR_BASE_HI;
msg->address_lo =
MSI_ADDR_BASE_LO |
((INT_DEST_MODE == 0) ?
MSI_ADDR_DEST_MODE_PHYSICAL:
MSI_ADDR_DEST_MODE_LOGICAL) |
((INT_DELIVERY_MODE != dest_LowestPrio) ?
MSI_ADDR_REDIRECTION_CPU:
MSI_ADDR_REDIRECTION_LOWPRI) |
MSI_ADDR_DEST_ID(dest);

msg->data =
MSI_DATA_TRIGGER_EDGE |
MSI_DATA_LEVEL_ASSERT |
((INT_DELIVERY_MODE != dest_LowestPrio) ?
MSI_DATA_DELIVERY_FIXED:
MSI_DATA_DELIVERY_LOWPRI) |
MSI_DATA_VECTOR(vector);
}
return vector;
}

static void msi_msg_teardown(unsigned int irq)
{
return;
}

static void msi_msg_set_affinity(unsigned int irq, cpumask_t mask, struct msi_msg *msg)
{
int vector;
unsigned dest;

vector = assign_irq_vector(irq);
if (vector > 0) {
dest = cpu_mask_to_apicid(mask);

msg->data &= ~MSI_DATA_VECTOR_MASK;
msg->data |= MSI_DATA_VECTOR(vector);
msg->address_lo &= ~MSI_ADDR_DEST_ID_MASK;
msg->address_lo |= MSI_ADDR_DEST_ID(dest);
}
}

struct msi_ops arch_msi_ops = {
.needs_64bit_address = 0,
.setup = msi_msg_setup,
.teardown = msi_msg_teardown,
.target = msi_msg_set_affinity,
};

#endif

/* --------------------------------------------------------------------------
ACPI-based IOAPIC Configuration
-------------------------------------------------------------------------- */
Expand Down
7 changes: 2 additions & 5 deletions trunk/include/asm-x86_64/msi.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,11 @@
#include <asm/mach_apic.h>
#include <asm/smp.h>

#define LAST_DEVICE_VECTOR (FIRST_SYSTEM_VECTOR - 1)
#define MSI_TARGET_CPU_SHIFT 12

extern struct msi_ops msi_apic_ops;
extern struct msi_ops arch_msi_ops;

static inline int msi_arch_init(void)
{
msi_register(&msi_apic_ops);
msi_register(&arch_msi_ops);
return 0;
}

Expand Down
47 changes: 47 additions & 0 deletions trunk/include/asm-x86_64/msidef.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef ASM_MSIDEF_H
#define ASM_MSIDEF_H

/*
* Constants for Intel APIC based MSI messages.
*/

/*
* Shifts for MSI data
*/

#define MSI_DATA_VECTOR_SHIFT 0
#define MSI_DATA_VECTOR_MASK 0x000000ff
#define MSI_DATA_VECTOR(v) (((v) << MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK)

#define MSI_DATA_DELIVERY_MODE_SHIFT 8
#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_MODE_SHIFT)
#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_MODE_SHIFT)

#define MSI_DATA_LEVEL_SHIFT 14
#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)

#define MSI_DATA_TRIGGER_SHIFT 15
#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)

/*
* Shift/mask fields for msi address
*/

#define MSI_ADDR_BASE_HI 0
#define MSI_ADDR_BASE_LO 0xfee00000

#define MSI_ADDR_DEST_MODE_SHIFT 2
#define MSI_ADDR_DEST_MODE_PHYSICAL (0 << MSI_ADDR_DEST_MODE_SHIFT)
#define MSI_ADDR_DEST_MODE_LOGICAL (1 << MSI_ADDR_DEST_MODE_SHIFT)

#define MSI_ADDR_REDIRECTION_SHIFT 3
#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT) /* dedicated cpu */
#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT) /* lowest priority */

#define MSI_ADDR_DEST_ID_SHIFT 12
#define MSI_ADDR_DEST_ID_MASK 0x00ffff0
#define MSI_ADDR_DEST_ID(dest) (((dest) << MSI_ADDR_DEST_ID_SHIFT) & MSI_ADDR_DEST_ID_MASK)

#endif /* ASM_MSIDEF_H */

0 comments on commit ac66b65

Please sign in to comment.