Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 113594
b: refs/heads/master
c: 7d77f2d
h: refs/heads/master
v: v3
  • Loading branch information
Robert Richter authored and Ingo Molnar committed Jul 26, 2008
1 parent 5ab2e1f commit 0c019fa
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 31 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: 7939d2bf7e30353d40d14f967b7fe2b2a7be5bd9
refs/heads/master: 7d77f2dcae37cf232950cd0181fb0a2cddb18130
84 changes: 54 additions & 30 deletions trunk/arch/x86/oprofile/op_model_athlon.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,55 +356,79 @@ static void op_amd_shutdown(struct op_msrs const * const msrs)
}
}

static u8 ibs_eilvt_off;

static inline void apic_init_ibs_nmi_per_cpu(void *arg)
{
setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0);
ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0);
}

static inline void apic_clear_ibs_nmi_per_cpu(void *arg)
{
setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
}

static int pfm_amd64_setup_eilvt(void)
{
#define IBSCTL_LVTOFFSETVAL (1 << 8)
#define IBSCTL 0x1cc
struct pci_dev *cpu_cfg;
int nodes;
u32 value = 0;

/* per CPU setup */
on_each_cpu(apic_init_ibs_nmi_per_cpu, NULL, 0, 1);

nodes = 0;
cpu_cfg = NULL;
do {
cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_10H_NB_MISC,
cpu_cfg);
if (!cpu_cfg)
break;
++nodes;
pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
| IBSCTL_LVTOFFSETVAL);
pci_read_config_dword(cpu_cfg, IBSCTL, &value);
if (value != (ibs_eilvt_off | IBSCTL_LVTOFFSETVAL)) {
printk(KERN_DEBUG "Failed to setup IBS LVT offset, "
"IBSCTL = 0x%08x", value);
return 1;
}
} while (1);

if (!nodes) {
printk(KERN_DEBUG "No CPU node configured for IBS");
return 1;
}

#ifdef CONFIG_NUMA
/* Sanity check */
/* Works only for 64bit with proper numa implementation. */
if (nodes != num_possible_nodes()) {
printk(KERN_DEBUG "Failed to setup CPU node(s) for IBS, "
"found: %d, expected %d",
nodes, num_possible_nodes());
return 1;
}
#endif
return 0;
}

/*
* initialize the APIC for the IBS interrupts
* if needed on AMD Family10h rev B0 and later
* if available (AMD Family10h rev B0 and later)
*/
static void setup_ibs(void)
{
struct pci_dev *gh_device = NULL;
u32 low, high;
u8 vector;

ibs_allowed = boot_cpu_has(X86_FEATURE_IBS);

if (!ibs_allowed)
return;

/* This gets the APIC_EILVT_LVTOFF_IBS value */
vector = setup_APIC_eilvt_ibs(0, 0, 1);

/*see if the IBS control register is already set correctly*/
/*remove this when we know for sure it is done
in the kernel init*/
rdmsr(MSR_AMD64_IBSCTL, low, high);
if ((low & (IBS_CTL_LVT_OFFSET_VALID_BIT | vector)) !=
(IBS_CTL_LVT_OFFSET_VALID_BIT | vector)) {

/**** Be sure to run loop until NULL is returned to
decrement reference count on any pci_dev structures
returned ****/
while ((gh_device = pci_get_device(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_10H_NB_MISC, gh_device))
!= NULL) {
/* This code may change if we can find a proper
* way to get at the PCI extended config space */
pci_write_config_dword(
gh_device, IBS_LVT_OFFSET_PCI,
(vector | IBS_CTL_LVT_OFFSET_VALID_BIT));
}
}
on_each_cpu(apic_init_ibs_nmi_per_cpu, NULL, 1, 1);
if (pfm_amd64_setup_eilvt())
ibs_allowed = 0;
}


Expand Down

0 comments on commit 0c019fa

Please sign in to comment.