From: john stultz <johnstul@us.ibm.com>
To: marcelo <marcelo@conectiva.com.br>
Cc: lkml <linux-kernel@vger.kernel.org>,
Leah Cunningham <leahc@us.ibm.com>,
wilhelm.nuesser@sap.com, paramjit@us.ibm.com, msw@redhat.com,
James <jamesclv@us.ibm.com>
Subject: [PATCH] cyclone-timer_A9
Date: 07 Aug 2002 19:15:56 -0700 [thread overview]
Message-ID: <1028772956.22920.207.camel@cog> (raw)
In-Reply-To: <1028771615.22918.188.camel@cog>
Marcelo,
This patch (which applies on top of my tsc-disable_B9 patch as well as
James Cleverdon's summit patch), is a performance improvement for
multi-CEC IBM x440 systems which suffer from drifting TSCs. Rather then
forcing do_gettimeofday to call do_slow_gettimeoffset and access the PIT
(as my tsc-disable patch does), passing "cyclone" as a boot option will
make do_gettimeofday use a 100Mhz performance counter found in the
Summit chipset.
This patch does not effect/correct userspace access to the unsynced TSC
registers via the rdtsc call.
Comments, flames, etc welcome.
thanks
-john
diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help
--- a/Documentation/Configure.help Wed Aug 7 19:00:21 2002
+++ b/Documentation/Configure.help Wed Aug 7 19:00:21 2002
@@ -252,6 +252,14 @@
You will need a new lynxer.elf file to flash your firmware with - send
email to Martin.Bligh@us.ibm.com
+IBM x440 Summit support
+CONFIG_X86_SUMMIT_NUMA
+ This option enables support for the IBM x440 and related multi-CEC
+ systems based on the Summit chipset. This options allows you to pass
+ "cyclone" as a boot option to make use of a performance counter on
+ the Cyclone chipset for calculating do_gettimeofday, greatly
+ improving performance when compared to the PIT based method.
+
IO-APIC support on uniprocessors
CONFIG_X86_UP_IOAPIC
An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an
diff -Nru a/arch/i386/config.in b/arch/i386/config.in
--- a/arch/i386/config.in Wed Aug 7 19:00:20 2002
+++ b/arch/i386/config.in Wed Aug 7 19:00:20 2002
@@ -205,6 +205,7 @@
bool 'Multi-node NUMA system support' CONFIG_X86_NUMA
if [ "$CONFIG_X86_NUMA" = "y" ]; then
bool ' Multiquad (IBM/Sequent) NUMAQ support' CONFIG_MULTIQUAD
+ bool ' IBM x440 Summit support' CONFIG_X86_SUMMIT_NUMA
fi
fi
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c Wed Aug 7 19:00:20 2002
+++ b/arch/i386/kernel/time.c Wed Aug 7 19:00:21 2002
@@ -256,6 +256,138 @@
static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
+
+
+#ifdef CONFIG_X86_SUMMIT_NUMA
+
+#define CYCLONE_CBAR_ADDR 0xFEB00CD0
+#define CYCLONE_PMCC_OFFSET 0x51A0
+#define CYCLONE_MPMC_OFFSET 0x51D0
+#define CYCLONE_MPCS_OFFSET 0x51A8
+#define CYCLONE_TIMER_FREQ 100000000
+
+static int use_cyclone __initdata = 0;
+static int __init cyclone_setup(char *str)
+{
+ bad_tsc = 1;
+ use_cyclone = 1;
+ return 1;
+}
+__setup("cyclone", cyclone_setup);
+
+
+static u32* cyclone_timer; /*Cyclone MPMC0 register*/
+static u32 last_cyclone_timer;
+
+static inline void mark_timeoffset_cyclone(void)
+{
+ int count;
+
+ /*quickly read the cyclone timer*/
+ if(cyclone_timer)
+ last_cyclone_timer = cyclone_timer[0];
+
+ /*calculate delay_at_last_interrupt*/
+ spin_lock(&i8253_lock);
+ outb_p(0x00, 0x43); /* latch the count ASAP */
+
+ count = inb_p(0x40); /* read the latched count */
+ count |= inb(0x40) << 8;
+ spin_unlock(&i8253_lock);
+
+ count = ((LATCH-1) - count) * TICK_SIZE;
+ delay_at_last_interrupt = (count + LATCH/2) / LATCH;
+}
+
+static unsigned long do_gettimeoffset_cyclone(void)
+{
+ u32 offset;
+
+ if(!cyclone_timer)
+ return delay_at_last_interrupt;
+
+ /* Read the cyclone timer */
+ offset = cyclone_timer[0];
+
+ /* .. relative to previous jiffy*/
+ offset = offset - last_cyclone_timer;
+
+ /*convert cyclone ticks to microseconds*/
+ offset = offset/100; /*XXX slow, can we speed this up?*/
+
+ /* our adjusted time offset in microseconds */
+ return delay_at_last_interrupt + offset;
+}
+
+static void init_cyclone_clock(void)
+{
+ u32* reg;
+ u32 base; /*saved cyclone base address*/
+ u32 pageaddr; /*page that contains cyclone_timer register*/
+ u32 offset; /*offset from pageaddr to cyclone_timer register*/
+
+ printk("Summit chipset: Starting Cyclone Clock.\n");
+
+ /*find base address*/
+ pageaddr = (CYCLONE_CBAR_ADDR)&PAGE_MASK;
+ offset = (CYCLONE_CBAR_ADDR)&(~PAGE_MASK);
+ set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr);
+ reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset);
+ if(!reg){
+ printk("Summit chipset: Could not find valid CBAR register.\n");
+ return;
+ }
+ base = *reg;
+ if(!base){
+ printk("Summit chipset: Could not find valid CBAR value.\n");
+ return;
+ }
+
+ /*setup PMCC*/
+ pageaddr = (base + CYCLONE_PMCC_OFFSET)&PAGE_MASK;
+ offset = (base + CYCLONE_PMCC_OFFSET)&(~PAGE_MASK);
+ set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr);
+ reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset);
+ if(!reg){
+ printk("Summit chipset: Could not find valid PMCC register.\n");
+ return;
+ }
+ reg[0] = 0x00000001;
+
+ /*setup MPCS*/
+ pageaddr = (base + CYCLONE_MPCS_OFFSET)&PAGE_MASK;
+ offset = (base + CYCLONE_MPCS_OFFSET)&(~PAGE_MASK);
+ set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr);
+ reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset);
+ if(!reg){
+ printk("Summit chipset: Could not find valid MPCS register.\n");
+ return;
+ }
+ reg[0] = 0x00000001;
+
+ /*map in cyclone_timer*/
+ pageaddr = (base + CYCLONE_MPMC_OFFSET)&PAGE_MASK;
+ offset = (base + CYCLONE_MPMC_OFFSET)&(~PAGE_MASK);
+ set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr);
+ cyclone_timer = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset);
+ if(!cyclone_timer){
+ printk("Summit chipset: Could not find valid MPMC register.\n");
+ return;
+ }
+
+ /* Everything looks good, so set do_gettimeoffset*/
+ do_gettimeoffset = do_gettimeoffset_cyclone;
+}
+
+#else /*CONFIG_X86_SUMMIT_NUMA*/
+
+#define use_cyclone 0
+static void mark_timeoffset_cyclone(void) {}
+static unsigned long do_gettimeoffset_cyclone(void) {return 0;}
+static void init_cyclone_clock(void) {}
+
+#endif /*CONFIG_X86_SUMMIT_NUMA*/
+
#else
#define do_gettimeoffset() do_fast_gettimeoffset()
@@ -481,8 +613,7 @@
*/
write_lock(&xtime_lock);
- if (use_tsc)
- {
+ if (use_tsc) {
/*
* It is important that these two operations happen almost at
* the same time. We do the RDTSC stuff first, since it's
@@ -508,8 +639,11 @@
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
- }
-
+ } else {
+ if(use_cyclone)
+ mark_timeoffset_cyclone();
+ }
+
do_timer_interrupt(irq, NULL, regs);
write_unlock(&xtime_lock);
@@ -709,6 +843,9 @@
}
}
}
+
+ if((!use_tsc) && use_cyclone)
+ init_cyclone_clock();
#ifdef CONFIG_VISWS
printk("Starting Cobalt Timer system clock\n");
diff -Nru a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h
--- a/include/asm-i386/fixmap.h Wed Aug 7 19:00:20 2002
+++ b/include/asm-i386/fixmap.h Wed Aug 7 19:00:20 2002
@@ -61,6 +61,9 @@
FIX_LI_PCIA, /* Lithium PCI Bridge A */
FIX_LI_PCIB, /* Lithium PCI Bridge B */
#endif
+#ifdef CONFIG_X86_SUMMIT_NUMA
+ FIX_CYCLONE_TIMER, /*cyclone timer register*/
+#endif
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
next prev parent reply other threads:[~2002-08-08 2:26 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-08-08 1:53 [PATCH] tsc-disable_B9 john stultz
2002-08-08 2:15 ` john stultz [this message]
2002-08-08 13:18 ` [PATCH] cyclone-timer_A9 Alan Cox
2002-08-09 2:03 ` john stultz
2002-08-08 13:17 ` [PATCH] tsc-disable_B9 Alan Cox
2002-08-09 2:30 ` john stultz
2002-08-09 9:17 ` Alan Cox
2002-08-09 17:46 ` john stultz
2002-08-09 18:49 ` george anzinger
2002-08-09 20:58 ` john stultz
2002-08-13 1:23 ` James Cleverdon
2002-08-11 20:16 ` Alan Cox
2002-08-15 16:56 ` Andrea Arcangeli
2002-08-16 11:15 ` Alan Cox
2002-08-16 13:19 ` Mikael Pettersson
2002-08-21 13:12 ` Andrea Arcangeli
2002-08-21 14:10 ` Alan Cox
2002-08-21 14:33 ` Andrea Arcangeli
2002-08-21 15:01 ` Alan Cox
2002-08-21 16:13 ` Andrea Arcangeli
2002-08-21 16:25 ` Alan Cox
2002-08-21 17:17 ` Andrea Arcangeli
2002-08-21 17:34 ` Alan Cox
2002-08-26 16:10 ` Pavel Machek
2002-08-26 18:45 ` Martin J. Bligh
2002-08-26 19:00 ` Pavel Machek
2002-08-26 19:05 ` Alan Cox
2002-08-26 20:19 ` Martin J. Bligh
2002-08-26 19:18 ` Richard B. Johnson
2002-08-26 19:42 ` Pavel Machek
2002-08-26 20:23 ` Alan Cox
2002-08-26 22:49 ` Andrea Arcangeli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1028772956.22920.207.camel@cog \
--to=johnstul@us.ibm.com \
--cc=jamesclv@us.ibm.com \
--cc=leahc@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=marcelo@conectiva.com.br \
--cc=msw@redhat.com \
--cc=paramjit@us.ibm.com \
--cc=wilhelm.nuesser@sap.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.