source: libcaca/trunk/kernel/drivers/processor.c @ 4159

Last change on this file since 4159 was 4159, checked in by Jean-Yves Lamoureux, 10 years ago
  • Added 64bits RDTSC support, as well as CPU frequency guess (more like a 8254a test, actually)
File size: 3.1 KB
Line 
1/*
2 *  libcaca       
3 *  libcaca       Colour ASCII-Art library
4 *  Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
5 *                2009 Jean-Yves Lamoureux <jylam@lnxscene.org>
6 *                All Rights Reserved
7 *
8 *  $Id: kernel.h 4154 2009-12-20 13:33:11Z jylam $
9 *
10 *  This library is free software. It comes without any warranty, to
11 *  the extent permitted by applicable law. You can redistribute it
12 *  and/or modify it under the terms of the Do What The Fuck You Want
13 *  To Public License, Version 2, as published by Sam Hocevar. See
14 *  http://sam.zoy.org/wtfpl/COPYING for more details.
15 */
16
17#include "kernel.h"
18#include "klibc.h"
19#include "drivers/timer.h"
20#include "processor.h"
21
22
23int processor_get_info(struct processor_info *processor_info)
24{
25    processor_info->id = 0;
26
27    /* Vendor String */
28    int code = CPUID_GETVENDORSTRING;
29    unsigned int where[5];
30    char *s;
31    asm volatile ("cpuid":"=a" (*where), "=b"(*(where + 1)),
32                  "=c"(*(where + 2)), "=d"(*(where + 3)):"0"(code));
33
34    s = (char *)where;
35
36    unsigned int a = 0;
37    unsigned int b = where[1];
38    unsigned int d = where[3];
39    unsigned int c = where[2];
40
41    where[0] = b;
42    where[1] = d;
43    where[2] = c;
44    where[3] = 0;
45
46    memcpy(processor_info->vendor, where, 13);
47
48    /* Features */
49    code = CPUID_GETFEATURES;
50    asm volatile ("cpuid":"=a" (a), "=d"(d):"0"(code):"ecx", "ebx");
51    processor_info->features = a;
52
53    processor_info->frequency = 0;
54    processor_info->frequency = processor_get_frequency(processor_info);
55
56    return 0;
57}
58
59u32 processor_get_frequency(struct processor_info * processor_info)
60{
61    if (processor_info->frequency)
62        return processor_info->frequency;
63    u64 srdtsc64, erdtsc64;
64    u32 srdtsc_l, srdtsc_h;
65    u32 erdtsc_l, erdtsc_h;
66
67    rdtsc(srdtsc_l, srdtsc_h);  /* Get RDTSC */
68    sleep(2);                   /* Sleep for 2 seconds */
69    rdtsc(erdtsc_l, erdtsc_h);  /* Get RDTSC again */
70
71    srdtsc64 = srdtsc_h;
72    srdtsc64 <<= 32;
73    srdtsc64 |= srdtsc_l;
74    erdtsc64 = erdtsc_h;
75    erdtsc64 <<= 32;
76    erdtsc64 |= erdtsc_l;
77
78
79    u32 diff = erdtsc64 - srdtsc64;     /* Cycle count for 2 seconds */
80    diff /= 2;                  /* Divide by 2 to get cycles per sec */
81    return diff;
82}
83
84void processor_print_info(struct processor_info *processor_info)
85{
86    printf("CPU%d\n", processor_info->id);
87    printf("Vendor ID : %s\n", processor_info->vendor);
88    if (processor_info->frequency > 1000000000)
89    {
90        printf("Frequency : ~%dGhz (or something like that)\n",
91               processor_info->frequency / 1000000000);
92    }
93    else if (processor_info->frequency > 1000000)
94    {
95        printf("Frequency : ~%dMhz (or something like that)\n",
96               processor_info->frequency / 1000000);
97    }
98    else if (processor_info->frequency > 1000)
99    {
100        printf("Frequency : ~%dKhz (or something like that)\n",
101               processor_info->frequency / 1000);
102    }
103    else
104    {
105        printf("Frequency : ~%dhz (you must be running Bochs)\n",
106               processor_info->frequency);
107    }
108    printf("Features : 0x%x\n", processor_info->features);
109}
Note: See TracBrowser for help on using the repository browser.