in kernel/perf.c [735:812]
static int perf_write_image(uint64_t *memaddr)
{
uint64_t buffer[MAX_RDR_WORDS];
uint64_t *bptr;
uint32_t dwords;
const uint32_t *intrigue_rdr;
const uint64_t *intrigue_bitmask;
uint64_t tmp64;
void __iomem *runway;
const struct rdr_tbl_ent *tentry;
int i;
/* Clear out counters */
if (perf_processor_interface == ONYX_INTF) {
perf_rdr_clear(16);
/* Toggle performance monitor */
perf_intrigue_enable_perf_counters();
perf_intrigue_disable_perf_counters();
intrigue_rdr = perf_rdrs_U;
} else {
perf_rdr_clear(15);
intrigue_rdr = perf_rdrs_W;
}
/* Write all RDRs */
while (*intrigue_rdr != -1) {
tentry = perf_rdr_get_entry(*intrigue_rdr);
perf_rdr_read_ubuf(*intrigue_rdr, buffer);
bptr = &buffer[0];
dwords = tentry->num_words;
if (tentry->write_control) {
intrigue_bitmask = &bitmask_array[tentry->write_control >> 3];
while (dwords--) {
tmp64 = *intrigue_bitmask & *memaddr++;
tmp64 |= (~(*intrigue_bitmask++)) & *bptr;
*bptr++ = tmp64;
}
} else {
while (dwords--) {
*bptr++ = *memaddr++;
}
}
perf_rdr_write(*intrigue_rdr, buffer);
intrigue_rdr++;
}
/*
* Now copy out the Runway stuff which is not in RDRs
*/
if (cpu_device == NULL)
{
printk(KERN_ERR "write_image: cpu_device not yet initialized!\n");
return -1;
}
runway = ioremap(cpu_device->hpa.start, 4096);
if (!runway) {
pr_err("perf_write_image: ioremap failed!\n");
return -ENOMEM;
}
/* Merge intrigue bits into Runway STATUS 0 */
tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful;
__raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul),
runway + RUNWAY_STATUS);
/* Write RUNWAY DEBUG registers */
for (i = 0; i < 8; i++) {
__raw_writeq(*memaddr++, runway + RUNWAY_DEBUG);
}
return 0;
}