1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is the Netscape Portable Runtime (NSPR).
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1999-2000
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
50 GetHighResClock(void *buf, size_t maxbytes)
55 return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
63 GetHighResClock(void *buf, size_t maxbytes)
71 #include <ia64/sys/inline.h>
74 GetHighResClock(void *buf, size_t maxbytes)
79 __asm__ __volatile__("mov %0 = ar.itc" : "=r" (t));
81 t = _Asm_mov_from_ar(_AREG44);
83 return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
87 GetHighResClock(void *buf, size_t maxbytes)
89 extern int ret_cr16();
93 return(_pr_CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val)));
102 * Use the "get the cycle counter" instruction on the alpha.
103 * The low 32 bits completely turn over in less than a minute.
104 * The high 32 bits are some non-counter gunk that changes sometimes.
107 GetHighResClock(void *buf, size_t maxbytes)
112 __asm__("rpcc %0" : "=r" (t));
116 return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
122 GetHighResClock(void *buf, size_t maxbytes)
127 #elif (defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD_kernel__) \
128 || defined(NETBSD) || defined(__NetBSD_kernel__) || defined(OPENBSD) \
130 #include <sys/types.h>
131 #include <sys/stat.h>
134 static int fdDevURandom;
135 static PRCallOnceType coOpenDevURandom;
137 static PRStatus OpenDevURandom( void )
139 fdDevURandom = open( "/dev/urandom", O_RDONLY );
140 return((-1 == fdDevURandom)? PR_FAILURE : PR_SUCCESS );
141 } /* end OpenDevURandom() */
143 static size_t GetDevURandom( void *buf, size_t size )
148 rc = PR_CallOnce( &coOpenDevURandom, OpenDevURandom );
149 if ( PR_FAILURE == rc ) {
150 _PR_MD_MAP_OPEN_ERROR( errno );
154 bytesIn = read( fdDevURandom, buf, size );
155 if ( -1 == bytesIn ) {
156 _PR_MD_MAP_READ_ERROR( errno );
161 } /* end GetDevURandom() */
164 GetHighResClock(void *buf, size_t maxbytes)
166 return(GetDevURandom( buf, maxbytes ));
172 GetHighResClock(void *buf, size_t maxbytes)
180 #include <sys/mman.h>
181 #include <sys/syssgi.h>
182 #include <sys/immu.h>
183 #include <sys/systeminfo.h>
184 #include <sys/utsname.h>
186 static size_t GetHighResClock(void *buf, size_t maxbuf)
188 unsigned phys_addr, raddr, cycleval;
189 static volatile unsigned *iotimer_addr = NULL;
190 static int tries = 0;
191 static int cntr_size;
195 #ifndef SGI_CYCLECNTR_SIZE
196 #define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */
199 if (iotimer_addr == NULL) {
201 /* Don't keep trying if it didn't work */
206 ** For SGI machines we can use the cycle counter, if it has one,
207 ** to generate some truly random numbers
209 phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
211 int pgsz = getpagesize();
212 int pgoffmask = pgsz - 1;
214 raddr = phys_addr & ~pgoffmask;
215 mfd = open("/dev/mmem", O_RDONLY);
219 iotimer_addr = (unsigned *)
220 mmap(0, pgoffmask, PROT_READ, MAP_PRIVATE, mfd, (int)raddr);
221 if (iotimer_addr == (unsigned*)-1) {
226 iotimer_addr = (unsigned*)
227 ((__psint_t)iotimer_addr | (phys_addr & pgoffmask));
229 * The file 'mfd' is purposefully not closed.
231 cntr_size = syssgi(SGI_CYCLECNTR_SIZE);
233 struct utsname utsinfo;
236 * We must be executing on a 6.0 or earlier system, since the
237 * SGI_CYCLECNTR_SIZE call is not supported.
239 * The only pre-6.1 platforms with 64-bit counters are
240 * IP19 and IP21 (Challenge, PowerChallenge, Onyx).
243 if (!strncmp(utsinfo.machine, "IP19", 4) ||
244 !strncmp(utsinfo.machine, "IP21", 4))
249 cntr_size /= 8; /* Convert from bits to bytes */
253 s0[0] = *iotimer_addr;
255 s0[1] = *(iotimer_addr + 1);
256 memcpy(buf, (char *)&s0[0], cntr_size);
257 return _pr_CopyLowBits(buf, maxbuf, &s0, cntr_size);
263 GetHighResClock(void *buf, size_t maxbytes)
269 #include <sys/times.h>
272 GetHighResClock(void *buf, size_t maxbytes)
277 ticks=times(&buffer);
278 return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
284 GetHighResClock(void *buf, size_t maxbytes)
288 #elif defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(NTO) \
289 || defined(QNX) || defined(DARWIN) || defined(RISCOS)
290 #include <sys/times.h>
293 GetHighResClock(void *buf, size_t maxbytes)
298 ticks=times(&buffer);
299 return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
302 #error! Platform undefined
303 #endif /* defined(SOLARIS) */
305 extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
311 n += GetHighResClock(buf, size);
317 s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec));
322 s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec));
328 } /* end _PR_MD_GetRandomNoise() */