root/cherokee/trunk/cherokee/cacheline.c

Revision 1354, 2.9 kB (checked in by alo, 5 months ago)

--

Line 
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /* Cherokee
4  *
5  * Authors:
6  *      Alvaro Lopez Ortega <alvaro@alobbs.com>
7  *
8  * Copyright (C) 2001-2008 Alvaro Lopez Ortega
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of version 2 of the GNU General Public
12  * License as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22  * USA
23  */
24
25 #include "common-internal.h"
26 #include "cacheline.h"
27
28
29 #if (( __GNUC__ || __INTEL_COMPILER ) && ( __i386__ || __amd64__ ))
30
31 static void
32 get_cpuid (uint32_t i, uint32_t *buf)
33 {
34 # if __i386__
35         __asm__ (
36
37                 "    mov    %%ebx, %%esi;  "
38
39                 "    cpuid;                "
40                 "    mov    %%eax, (%1);   "
41                 "    mov    %%ebx, 4(%1);  "
42                 "    mov    %%edx, 8(%1);  "
43                 "    mov    %%ecx, 12(%1); "
44
45                 "    mov    %%esi, %%ebx;  "
46
47                 : : "a" (i), "D" (buf) : "ecx", "edx", "esi", "memory" );
48
49 # elif __amd64__
50
51         uint32_t  eax, ebx, ecx, edx;
52
53         __asm__ (
54                 "cpuid"
55                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (i) );
56
57         buf[0] = eax;
58         buf[1] = ebx;
59         buf[2] = edx;
60         buf[3] = ecx;
61
62 # endif
63 }
64
65 static ret_t
66 get_cache_line_live (cuint_t *size)
67 {
68         uint32_t    vendor_buf[5];
69         uint32_t processor_buf[5];
70        
71         const char *vendor;
72
73         memset (vendor_buf, 0, sizeof(vendor_buf));
74         memset (processor_buf, 0, sizeof(processor_buf));
75
76         /* EAX=0: Get vendor ID
77          */
78         get_cpuid (0, vendor_buf);
79         vendor = (const char *)&vendor_buf[1];
80
81         if (vendor_buf[0] == 0) {
82                 return ret_error;
83         }
84        
85         /* EAX=1: Get Processor Info and Feature Bits
86          */
87         get_cpuid(1, processor_buf);
88         if (strcmp (vendor, "GenuineIntel") == 0) {
89                 switch ((processor_buf[0] & 0xf00) >> 8) {
90                 case 5:
91                         /* Pentium */
92                         *size = 32;
93                         return ret_ok;
94
95                 case 6:
96                         /* Pentium Pro, II, III */
97                         *size = 32;
98
99                         if ((processor_buf[0] & 0xf0) >= 0xd0) {
100                                 /* Intel Core */
101                                 *size = 64;
102                         }
103                         return ret_ok;
104
105                 case 15:
106                         /* Pentium 4, although its cache line size is 64 bytes,
107                          * it prefetches up to two cache lines during memory read
108                          */
109                         *size = 128;
110                         return ret_ok;
111                 }
112                
113         } else if (strcmp(vendor, "AuthenticAMD") == 0) {
114                 *size = 64;
115                 return ret_ok;
116         }
117
118         return ret_not_found;
119 }
120
121 #endif  // (( __GNUC__ || __INTEL_COMPILER ) && ( __i386__ || __amd64__ ))
122
123
124 ret_t
125 cherokee_cacheline_size_get (cuint_t *size)
126 {
127 #if (( __GNUC__ || __INTEL_COMPILER ) && ( __i386__ || __amd64__ ))
128         ret_t ret;
129         ret = get_cache_line_live (size);
130         if (ret == ret_ok) return ret_ok;
131 #endif
132
133         *size = CPU_CACHE_LINE;
134         return ret_ok;
135 }
Note: See TracBrowser for help on using the browser.