From owner-p4-projects@FreeBSD.ORG Mon Mar 6 14:25:06 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8A35916A423; Mon, 6 Mar 2006 14:25:05 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 489E316A420 for ; Mon, 6 Mar 2006 14:25:05 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0E84C43D45 for ; Mon, 6 Mar 2006 14:25:05 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k26EP4Qe066903 for ; Mon, 6 Mar 2006 14:25:04 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k26EP4HE066899 for perforce@freebsd.org; Mon, 6 Mar 2006 14:25:04 GMT (envelope-from jhb@freebsd.org) Date: Mon, 6 Mar 2006 14:25:04 GMT Message-Id: <200603061425.k26EP4HE066899@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Cc: Subject: PERFORCE change 92848 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Mar 2006 14:25:06 -0000 http://perforce.freebsd.org/chv.cgi?CH=92848 Change 92848 by jhb@jhb_zion on 2006/03/06 14:24:04 Attempt to fix the alpha cpu ticker. The RPCC register is not exactly like the TSC on i386. The upper 32-bits have a quirky meaning, so we basically have to treat it like a 32-bit counter and handle the roll-overs ourself. I think this may end up not being any cheaper than just using the alpha timecounter, though perhaps it will be cheaper for SMP where we have to use the i8254 right now for cpu_ticks. Affected files ... .. //depot/projects/smpng/sys/alpha/alpha/clock.c#23 edit .. //depot/projects/smpng/sys/alpha/alpha/interrupt.c#38 edit .. //depot/projects/smpng/sys/alpha/include/md_var.h#9 edit .. //depot/projects/smpng/sys/alpha/include/pcpu.h#5 edit Differences ... ==== //depot/projects/smpng/sys/alpha/alpha/clock.c#23 (text+ko) ==== @@ -152,7 +152,7 @@ calibrate_clocks(cycles_per_sec, &pcc, &freq); cycles_per_sec = pcc; - set_cputicker(alpha_rpcc, cycles_per_sec, 0); + set_cputicker(read_cycle_count, cycles_per_sec, 0); /* * XXX: TurboLaser doesn't have an i8254 counter. @@ -556,6 +556,30 @@ return alpha_rpcc(); } +/* + * The RPCC register actually consists of two halves. The lower half + * is a raw 32-bit counter that wraps. The upper half is defined in + * the Digital UNIX PAL as being a raw per-process cycle count mod 2^32 + * that is updated on each call to swpctx. In order to produce a 64-bit + * counter, we just use the lower half and simulate the upper 32-bits. + * The architecture guarantees that there will always be at least one + * clock interrupt in between overlaps in the lower half, so as long as + * we call this function every clock interrupt we should not miss any + * overlaps. + */ +uint64_t +read_cycle_count(void) +{ + unsigned pcc_cnt; + + /* Assert a critical section? */ + pcc_cnt = alpha_rpcc() & 0xffffffff; + if (pcc_cnt < PCPU_GET(last_pcc_cnt)) + PCPU_SET(pcc_base, PCPU_GET(pcc_base) + 1); + PCPU_SET(last_pcc_cnt, pcc_cnt); + return (pcc_cnt | (PCPU_GET(pcc_base) << 32)); +} + int acquire_timer2(int mode) { ==== //depot/projects/smpng/sys/alpha/alpha/interrupt.c#38 (text+ko) ==== @@ -483,6 +483,9 @@ #endif if (platform.clockintr) { critical_enter(); + + /* Check for PCC roll-over. */ + (void)read_cycle_count(); #ifdef SMP /* * Only one processor drives the actual timer. ==== //depot/projects/smpng/sys/alpha/include/md_var.h#9 (text+ko) ==== @@ -84,6 +84,7 @@ int is_physical_memory(vm_offset_t addr); void machine_check(unsigned long, struct trapframe *, unsigned long, unsigned long); +uint64_t read_cycle_count(void); void regdump(struct trapframe *); void regtoframe(struct reg *, struct trapframe *); void set_iointr(void (*)(void *, unsigned long)); ==== //depot/projects/smpng/sys/alpha/include/pcpu.h#5 (text+ko) ==== @@ -38,7 +38,9 @@ u_int64_t pc_idlepcbphys; /* pa of pc_idlepcb */ \ u_int64_t pc_pending_ipis; /* pending IPI's */ \ u_int32_t pc_next_asn; /* next ASN to alloc */ \ - u_int32_t pc_current_asngen /* ASN rollover check */ + u_int32_t pc_current_asngen /* ASN rollover check */ \ + u_int32_t pc_last_ppc_cnt; /* Previous PCC_CNT value */ \ + u_int32_t pc_ppc_base; /* Hi word of cycle count. */ struct pcpu;