* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: dumbtod.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
#pragma ident "@(#)dumbtod.c 1.13 07/02/15 SMI"
* This is a very generic TOD device.
* It provides a single read-only 64-bit register that
* contains the time in standard Unix form: number of seconds
#define DBGX(s) do { } while (0)
* ----- -- ------ --------------
static void dtod_parse(config_dev_t
*);
static void dtod_init(config_dev_t
*);
static void dtod_dump(config_dev_t
*);
static bool_t
dtod_cpu_access(simcpu_t
*sp
, config_addr_t
* cap
,
tpaddr_t offset
, maccess_t op
, uint64_t * regp
);
dev_type_t dev_type_dumbtod
= {
generic_device_non_cacheable
,
* Complete the creation and parsing of this specific device
dtod_parse(config_dev_t
*config_devp
)
if (config_devp
->addrp
->range
!= 8)
fatal("dumbtod: dumbtod requires address space size of 0x8");
DBG( printf("dumbtod_parse: parsing device %d\n", config_devp
->device_id
); );
dtp
= (void*)Xcalloc(1, dtod_state_t
);
dtp
->todfreq
= 1; /* defaults to 1 */
lex_fatal("unexpected token");
* Parse the optional tod frequency
if (strcmp(lex
.strp
,"frequency") == 0) {
dtp
->todfreq
= parse_number_assign();
lex_fatal("dumbtod: dumbtod cannot have a tod freq of 0");
printf("dumbtod_parse: setting tod frequency of %lld\n", dtp
->todfreq
);
* Initialise the device after parsing is complete
dtod_init(config_dev_t
*config_devp
)
dtp
->start_time
= time(NULL
);
dtp
->sysclkfreq
= 0; /* find put from first CPU access */
dtod_dump(config_dev_t
*config_devp
)
dtod_cpu_access(simcpu_t
*sp
, config_addr_t
*cap
, tpaddr_t offset
, maccess_t op
,
if ((op
& MA_Op_Mask
) != MA_Ld
&& (op
& MA_Op_Mask
) != MA_LdSigned
) {
EXEC_WARNING(("dumbtod: Illegal access - only loads allowed "
if (offset
!= 0 || (op
& MA_Size_Mask
) != MA_Size64
) {
EXEC_WARNING(("dumbtod: Illegal device load access (%d bytes) "
"- offset (0x%d) not 8-byte sized or aligned",
1<<(op
& MA_Size_Mask
), offset
));
dtp
= cap
->config_devp
->devp
;
*regp
= time(NULL
) * dtp
->todfreq
;
if (dtp
->sysclkfreq
== 0) {
/* First time through - obtain clock frequency. */
dtp
->sysclkfreq
= sp
->config_procp
->domainp
->sysclkfreq
;
*regp
= (dtp
->start_time
+ (time_t)(sp
->cycle
/ dtp
->sysclkfreq
)) * dtp
->todfreq
;