[parisc-linux] sched_clock implementation

Joel Soete soete.joel@tiscali.be
Sun, 05 Oct 2003 15:43:16 +0000


Grant Grundler wrote:

>On Sat, Sep 20, 2003 at 06:02:10PM +0000, Joel Soete wrote:
>  
>
>>a quick look into paxx.pdf which about CR16 speak of "peak instruction 
>>rate" but do not define anywhere?
>>I presume that is the cpu clock but would like somebody confirm.
>>    
>>
>
>Read about "Interval Timer" (cr16) in the PA 2.0 Arch book.
>PDC provides the exact rate that CR16 is changing.
>Looks like PDC_TOD_ITIMER is the call but I'm not sure offhand.
>In any case, I've only seen it used as CPU cycle counter.
>(ie 1:1 with CPU clock).
>
>hth,
>grant
>_______________________________________________
>parisc-linux mailing list
>parisc-linux@lists.parisc-linux.org
>http://lists.parisc-linux.org/mailman/listinfo/parisc-linux
>
>  
>
Much more for remind, here is a proposed implementation of a pdc_tod_itimer:
diff -Naur linux-2.6.0-test6-pa6.orig/arch/parisc/kernel/firmware.c 
linux-2.6.0-test6-pa6.test/arch/parisc/kernel/firmware.c
--- linux-2.6.0-test6-pa6.orig/arch/parisc/kernel/firmware.c    
2003-10-05 17:14:13.000000000 +0200
+++ linux-2.6.0-test6-pa6.test/arch/parisc/kernel/firmware.c    
2003-10-05 17:09:14.000000000 +0200
@@ -682,6 +682,26 @@
 }
 EXPORT_SYMBOL(pdc_tod_set);

+/**
+ * pdc_tod_Calibrate_timers - Read "Calibrate timers" data
+ * @tod_calib: The return buffer:
+ *
+ * Calibrate the Interval Timer (CR16).
+ */
+int pdc_tod_itimer(struct pdc_tod_calib *tod_calib)
+{
+        int retval;
+
+        spin_lock_irq(&pdc_lock);
+        retval = mem_pdc_call(PDC_TOD, PDC_TOD_ITIMER, 
__pa(pdc_result), 0);
+        convert_to_wide(pdc_result);
+        memcpy(tod_calib, pdc_result, sizeof(tod_calib));
+        spin_unlock_irq(&pdc_lock);
+
+        return retval;
+}
+EXPORT_SYMBOL(pdc_tod_itimer);
+
 #ifdef __LP64__
 int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
                struct pdc_memory_table *tbl, unsigned long entries)
diff -Naur linux-2.6.0-test6-pa6.orig/include/asm-parisc/pdc.h 
linux-2.6.0-test6-pa6.test/include/asm-parisc/pdc.h
--- linux-2.6.0-test6-pa6.orig/include/asm-parisc/pdc.h 2003-10-05 
17:15:09.000000000 +0200
+++ linux-2.6.0-test6-pa6.test/include/asm-parisc/pdc.h 2003-10-05 
17:11:26.000000000 +0200
@@ -670,6 +670,13 @@
        unsigned long tod_usec;
 };

+struct pdc_tod_calib {
+       unsigned long calib_0;
+       unsigned long calib_1;
+       unsigned long TOD_acc;
+       unsigned long CR_acc;
+};
+
 #ifdef __LP64__
 struct pdc_pat_cell_num {
        unsigned long cell_num;
@@ -943,6 +950,7 @@
 int pdc_get_initiator(struct hardware_path *hwpath, unsigned char 
*scsi_id, unsigned long *period, char *width, char *mode);
 int pdc_tod_read(struct pdc_tod *tod);
 int pdc_tod_set(unsigned long sec, unsigned long usec);
+int pdc_tod_itimer(struct pdc_tod_calib *tod_calib);

 #ifdef __LP64__
 int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,

Well I don't know yet if it would help for a better sched_clock() because:
a) I already found some get_jiffies_64() which seems to be a good candidate?

b) I don't yet find how jiffies and jiffies_64 are continuously updated. 
I presume that we take advantage of an 'external interupt request' by 
CR16 (interval timer) but don't reach to find neither where this one is 
initialised (just to determine if get_jiffies_64 is enough (theoriticaly 
1/100s ?) or request more) nor where it is updated?

Thanks in advance for comments and idea,
    Joel

PS:
I added some test on my c110 and got some:
Oct  5 15:57:51 hpalin kernel: Calib_0 =  0x405e0000
Oct  5 15:57:51 hpalin kernel: Calib_1 =  0x00000000
Oct  5 15:57:51 hpalin kernel: TOD_acc =  0x00000000
Oct  5 15:57:51 hpalin kernel: CR_acc  =  0x00000000

merging Calib_1, Calib_0 in a union retrun me a frequency of 120Mhz 
(exactly) when "Oct  5 15:57:51 hpalin kernel: Calibrating delay loop... 
119.60 BogoMIPS" (but printk don't print float :( )

but it is curious that TOD_acc and CR_acc are 0 any idea?