cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

time_64.c (21408B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* time.c: UltraSparc timer and TOD clock support.
      3 *
      4 * Copyright (C) 1997, 2008 David S. Miller (davem@davemloft.net)
      5 * Copyright (C) 1998 Eddie C. Dost   (ecd@skynet.be)
      6 *
      7 * Based largely on code which is:
      8 *
      9 * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
     10 */
     11
     12#include <linux/errno.h>
     13#include <linux/export.h>
     14#include <linux/sched.h>
     15#include <linux/kernel.h>
     16#include <linux/param.h>
     17#include <linux/string.h>
     18#include <linux/mm.h>
     19#include <linux/interrupt.h>
     20#include <linux/time.h>
     21#include <linux/timex.h>
     22#include <linux/init.h>
     23#include <linux/ioport.h>
     24#include <linux/mc146818rtc.h>
     25#include <linux/delay.h>
     26#include <linux/profile.h>
     27#include <linux/bcd.h>
     28#include <linux/jiffies.h>
     29#include <linux/cpufreq.h>
     30#include <linux/percpu.h>
     31#include <linux/rtc/m48t59.h>
     32#include <linux/kernel_stat.h>
     33#include <linux/clockchips.h>
     34#include <linux/clocksource.h>
     35#include <linux/platform_device.h>
     36#include <linux/ftrace.h>
     37
     38#include <asm/oplib.h>
     39#include <asm/timer.h>
     40#include <asm/irq.h>
     41#include <asm/io.h>
     42#include <asm/prom.h>
     43#include <asm/starfire.h>
     44#include <asm/smp.h>
     45#include <asm/sections.h>
     46#include <asm/cpudata.h>
     47#include <linux/uaccess.h>
     48#include <asm/irq_regs.h>
     49#include <asm/cacheflush.h>
     50
     51#include "entry.h"
     52#include "kernel.h"
     53
     54DEFINE_SPINLOCK(rtc_lock);
     55
     56#ifdef CONFIG_SMP
     57unsigned long profile_pc(struct pt_regs *regs)
     58{
     59	unsigned long pc = instruction_pointer(regs);
     60
     61	if (in_lock_functions(pc))
     62		return regs->u_regs[UREG_RETPC];
     63	return pc;
     64}
     65EXPORT_SYMBOL(profile_pc);
     66#endif
     67
     68static void tick_disable_protection(void)
     69{
     70	/* Set things up so user can access tick register for profiling
     71	 * purposes.  Also workaround BB_ERRATA_1 by doing a dummy
     72	 * read back of %tick after writing it.
     73	 */
     74	__asm__ __volatile__(
     75	"	ba,pt	%%xcc, 1f\n"
     76	"	 nop\n"
     77	"	.align	64\n"
     78	"1:	rd	%%tick, %%g2\n"
     79	"	add	%%g2, 6, %%g2\n"
     80	"	andn	%%g2, %0, %%g2\n"
     81	"	wrpr	%%g2, 0, %%tick\n"
     82	"	rdpr	%%tick, %%g0"
     83	: /* no outputs */
     84	: "r" (TICK_PRIV_BIT)
     85	: "g2");
     86}
     87
     88static void tick_disable_irq(void)
     89{
     90	__asm__ __volatile__(
     91	"	ba,pt	%%xcc, 1f\n"
     92	"	 nop\n"
     93	"	.align	64\n"
     94	"1:	wr	%0, 0x0, %%tick_cmpr\n"
     95	"	rd	%%tick_cmpr, %%g0"
     96	: /* no outputs */
     97	: "r" (TICKCMP_IRQ_BIT));
     98}
     99
    100static void tick_init_tick(void)
    101{
    102	tick_disable_protection();
    103	tick_disable_irq();
    104}
    105
    106static unsigned long long tick_get_tick(void)
    107{
    108	unsigned long ret;
    109
    110	__asm__ __volatile__("rd	%%tick, %0\n\t"
    111			     "mov	%0, %0"
    112			     : "=r" (ret));
    113
    114	return ret & ~TICK_PRIV_BIT;
    115}
    116
    117static int tick_add_compare(unsigned long adj)
    118{
    119	unsigned long orig_tick, new_tick, new_compare;
    120
    121	__asm__ __volatile__("rd	%%tick, %0"
    122			     : "=r" (orig_tick));
    123
    124	orig_tick &= ~TICKCMP_IRQ_BIT;
    125
    126	/* Workaround for Spitfire Errata (#54 I think??), I discovered
    127	 * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
    128	 * number 103640.
    129	 *
    130	 * On Blackbird writes to %tick_cmpr can fail, the
    131	 * workaround seems to be to execute the wr instruction
    132	 * at the start of an I-cache line, and perform a dummy
    133	 * read back from %tick_cmpr right after writing to it. -DaveM
    134	 */
    135	__asm__ __volatile__("ba,pt	%%xcc, 1f\n\t"
    136			     " add	%1, %2, %0\n\t"
    137			     ".align	64\n"
    138			     "1:\n\t"
    139			     "wr	%0, 0, %%tick_cmpr\n\t"
    140			     "rd	%%tick_cmpr, %%g0\n\t"
    141			     : "=r" (new_compare)
    142			     : "r" (orig_tick), "r" (adj));
    143
    144	__asm__ __volatile__("rd	%%tick, %0"
    145			     : "=r" (new_tick));
    146	new_tick &= ~TICKCMP_IRQ_BIT;
    147
    148	return ((long)(new_tick - (orig_tick+adj))) > 0L;
    149}
    150
    151static unsigned long tick_add_tick(unsigned long adj)
    152{
    153	unsigned long new_tick;
    154
    155	/* Also need to handle Blackbird bug here too. */
    156	__asm__ __volatile__("rd	%%tick, %0\n\t"
    157			     "add	%0, %1, %0\n\t"
    158			     "wrpr	%0, 0, %%tick\n\t"
    159			     : "=&r" (new_tick)
    160			     : "r" (adj));
    161
    162	return new_tick;
    163}
    164
    165/* Searches for cpu clock frequency with given cpuid in OpenBoot tree */
    166static unsigned long cpuid_to_freq(phandle node, int cpuid)
    167{
    168	bool is_cpu_node = false;
    169	unsigned long freq = 0;
    170	char type[128];
    171
    172	if (!node)
    173		return freq;
    174
    175	if (prom_getproperty(node, "device_type", type, sizeof(type)) != -1)
    176		is_cpu_node = (strcmp(type, "cpu") == 0);
    177
    178	/* try upa-portid then cpuid to get cpuid, see prom_64.c */
    179	if (is_cpu_node && (prom_getint(node, "upa-portid") == cpuid ||
    180			    prom_getint(node, "cpuid") == cpuid))
    181		freq = prom_getintdefault(node, "clock-frequency", 0);
    182	if (!freq)
    183		freq = cpuid_to_freq(prom_getchild(node), cpuid);
    184	if (!freq)
    185		freq = cpuid_to_freq(prom_getsibling(node), cpuid);
    186
    187	return freq;
    188}
    189
    190static unsigned long tick_get_frequency(void)
    191{
    192	return cpuid_to_freq(prom_root_node, hard_smp_processor_id());
    193}
    194
    195static struct sparc64_tick_ops tick_operations __cacheline_aligned = {
    196	.name		=	"tick",
    197	.init_tick	=	tick_init_tick,
    198	.disable_irq	=	tick_disable_irq,
    199	.get_tick	=	tick_get_tick,
    200	.add_tick	=	tick_add_tick,
    201	.add_compare	=	tick_add_compare,
    202	.get_frequency	=	tick_get_frequency,
    203	.softint_mask	=	1UL << 0,
    204};
    205
    206struct sparc64_tick_ops *tick_ops __read_mostly = &tick_operations;
    207EXPORT_SYMBOL(tick_ops);
    208
    209static void stick_disable_irq(void)
    210{
    211	__asm__ __volatile__(
    212	"wr	%0, 0x0, %%asr25"
    213	: /* no outputs */
    214	: "r" (TICKCMP_IRQ_BIT));
    215}
    216
    217static void stick_init_tick(void)
    218{
    219	/* Writes to the %tick and %stick register are not
    220	 * allowed on sun4v.  The Hypervisor controls that
    221	 * bit, per-strand.
    222	 */
    223	if (tlb_type != hypervisor) {
    224		tick_disable_protection();
    225		tick_disable_irq();
    226
    227		/* Let the user get at STICK too. */
    228		__asm__ __volatile__(
    229		"	rd	%%asr24, %%g2\n"
    230		"	andn	%%g2, %0, %%g2\n"
    231		"	wr	%%g2, 0, %%asr24"
    232		: /* no outputs */
    233		: "r" (TICK_PRIV_BIT)
    234		: "g1", "g2");
    235	}
    236
    237	stick_disable_irq();
    238}
    239
    240static unsigned long long stick_get_tick(void)
    241{
    242	unsigned long ret;
    243
    244	__asm__ __volatile__("rd	%%asr24, %0"
    245			     : "=r" (ret));
    246
    247	return ret & ~TICK_PRIV_BIT;
    248}
    249
    250static unsigned long stick_add_tick(unsigned long adj)
    251{
    252	unsigned long new_tick;
    253
    254	__asm__ __volatile__("rd	%%asr24, %0\n\t"
    255			     "add	%0, %1, %0\n\t"
    256			     "wr	%0, 0, %%asr24\n\t"
    257			     : "=&r" (new_tick)
    258			     : "r" (adj));
    259
    260	return new_tick;
    261}
    262
    263static int stick_add_compare(unsigned long adj)
    264{
    265	unsigned long orig_tick, new_tick;
    266
    267	__asm__ __volatile__("rd	%%asr24, %0"
    268			     : "=r" (orig_tick));
    269	orig_tick &= ~TICKCMP_IRQ_BIT;
    270
    271	__asm__ __volatile__("wr	%0, 0, %%asr25"
    272			     : /* no outputs */
    273			     : "r" (orig_tick + adj));
    274
    275	__asm__ __volatile__("rd	%%asr24, %0"
    276			     : "=r" (new_tick));
    277	new_tick &= ~TICKCMP_IRQ_BIT;
    278
    279	return ((long)(new_tick - (orig_tick+adj))) > 0L;
    280}
    281
    282static unsigned long stick_get_frequency(void)
    283{
    284	return prom_getintdefault(prom_root_node, "stick-frequency", 0);
    285}
    286
    287static struct sparc64_tick_ops stick_operations __read_mostly = {
    288	.name		=	"stick",
    289	.init_tick	=	stick_init_tick,
    290	.disable_irq	=	stick_disable_irq,
    291	.get_tick	=	stick_get_tick,
    292	.add_tick	=	stick_add_tick,
    293	.add_compare	=	stick_add_compare,
    294	.get_frequency	=	stick_get_frequency,
    295	.softint_mask	=	1UL << 16,
    296};
    297
    298/* On Hummingbird the STICK/STICK_CMPR register is implemented
    299 * in I/O space.  There are two 64-bit registers each, the
    300 * first holds the low 32-bits of the value and the second holds
    301 * the high 32-bits.
    302 *
    303 * Since STICK is constantly updating, we have to access it carefully.
    304 *
    305 * The sequence we use to read is:
    306 * 1) read high
    307 * 2) read low
    308 * 3) read high again, if it rolled re-read both low and high again.
    309 *
    310 * Writing STICK safely is also tricky:
    311 * 1) write low to zero
    312 * 2) write high
    313 * 3) write low
    314 */
    315static unsigned long __hbird_read_stick(void)
    316{
    317	unsigned long ret, tmp1, tmp2, tmp3;
    318	unsigned long addr = HBIRD_STICK_ADDR+8;
    319
    320	__asm__ __volatile__("ldxa	[%1] %5, %2\n"
    321			     "1:\n\t"
    322			     "sub	%1, 0x8, %1\n\t"
    323			     "ldxa	[%1] %5, %3\n\t"
    324			     "add	%1, 0x8, %1\n\t"
    325			     "ldxa	[%1] %5, %4\n\t"
    326			     "cmp	%4, %2\n\t"
    327			     "bne,a,pn	%%xcc, 1b\n\t"
    328			     " mov	%4, %2\n\t"
    329			     "sllx	%4, 32, %4\n\t"
    330			     "or	%3, %4, %0\n\t"
    331			     : "=&r" (ret), "=&r" (addr),
    332			       "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3)
    333			     : "i" (ASI_PHYS_BYPASS_EC_E), "1" (addr));
    334
    335	return ret;
    336}
    337
    338static void __hbird_write_stick(unsigned long val)
    339{
    340	unsigned long low = (val & 0xffffffffUL);
    341	unsigned long high = (val >> 32UL);
    342	unsigned long addr = HBIRD_STICK_ADDR;
    343
    344	__asm__ __volatile__("stxa	%%g0, [%0] %4\n\t"
    345			     "add	%0, 0x8, %0\n\t"
    346			     "stxa	%3, [%0] %4\n\t"
    347			     "sub	%0, 0x8, %0\n\t"
    348			     "stxa	%2, [%0] %4"
    349			     : "=&r" (addr)
    350			     : "0" (addr), "r" (low), "r" (high),
    351			       "i" (ASI_PHYS_BYPASS_EC_E));
    352}
    353
    354static void __hbird_write_compare(unsigned long val)
    355{
    356	unsigned long low = (val & 0xffffffffUL);
    357	unsigned long high = (val >> 32UL);
    358	unsigned long addr = HBIRD_STICKCMP_ADDR + 0x8UL;
    359
    360	__asm__ __volatile__("stxa	%3, [%0] %4\n\t"
    361			     "sub	%0, 0x8, %0\n\t"
    362			     "stxa	%2, [%0] %4"
    363			     : "=&r" (addr)
    364			     : "0" (addr), "r" (low), "r" (high),
    365			       "i" (ASI_PHYS_BYPASS_EC_E));
    366}
    367
    368static void hbtick_disable_irq(void)
    369{
    370	__hbird_write_compare(TICKCMP_IRQ_BIT);
    371}
    372
    373static void hbtick_init_tick(void)
    374{
    375	tick_disable_protection();
    376
    377	/* XXX This seems to be necessary to 'jumpstart' Hummingbird
    378	 * XXX into actually sending STICK interrupts.  I think because
    379	 * XXX of how we store %tick_cmpr in head.S this somehow resets the
    380	 * XXX {TICK + STICK} interrupt mux.  -DaveM
    381	 */
    382	__hbird_write_stick(__hbird_read_stick());
    383
    384	hbtick_disable_irq();
    385}
    386
    387static unsigned long long hbtick_get_tick(void)
    388{
    389	return __hbird_read_stick() & ~TICK_PRIV_BIT;
    390}
    391
    392static unsigned long hbtick_add_tick(unsigned long adj)
    393{
    394	unsigned long val;
    395
    396	val = __hbird_read_stick() + adj;
    397	__hbird_write_stick(val);
    398
    399	return val;
    400}
    401
    402static int hbtick_add_compare(unsigned long adj)
    403{
    404	unsigned long val = __hbird_read_stick();
    405	unsigned long val2;
    406
    407	val &= ~TICKCMP_IRQ_BIT;
    408	val += adj;
    409	__hbird_write_compare(val);
    410
    411	val2 = __hbird_read_stick() & ~TICKCMP_IRQ_BIT;
    412
    413	return ((long)(val2 - val)) > 0L;
    414}
    415
    416static unsigned long hbtick_get_frequency(void)
    417{
    418	return prom_getintdefault(prom_root_node, "stick-frequency", 0);
    419}
    420
    421static struct sparc64_tick_ops hbtick_operations __read_mostly = {
    422	.name		=	"hbtick",
    423	.init_tick	=	hbtick_init_tick,
    424	.disable_irq	=	hbtick_disable_irq,
    425	.get_tick	=	hbtick_get_tick,
    426	.add_tick	=	hbtick_add_tick,
    427	.add_compare	=	hbtick_add_compare,
    428	.get_frequency	=	hbtick_get_frequency,
    429	.softint_mask	=	1UL << 0,
    430};
    431
    432unsigned long cmos_regs;
    433EXPORT_SYMBOL(cmos_regs);
    434
    435static struct resource rtc_cmos_resource;
    436
    437static struct platform_device rtc_cmos_device = {
    438	.name		= "rtc_cmos",
    439	.id		= -1,
    440	.resource	= &rtc_cmos_resource,
    441	.num_resources	= 1,
    442};
    443
    444static int rtc_probe(struct platform_device *op)
    445{
    446	struct resource *r;
    447
    448	printk(KERN_INFO "%pOF: RTC regs at 0x%llx\n",
    449	       op->dev.of_node, op->resource[0].start);
    450
    451	/* The CMOS RTC driver only accepts IORESOURCE_IO, so cons
    452	 * up a fake resource so that the probe works for all cases.
    453	 * When the RTC is behind an ISA bus it will have IORESOURCE_IO
    454	 * already, whereas when it's behind EBUS is will be IORESOURCE_MEM.
    455	 */
    456
    457	r = &rtc_cmos_resource;
    458	r->flags = IORESOURCE_IO;
    459	r->name = op->resource[0].name;
    460	r->start = op->resource[0].start;
    461	r->end = op->resource[0].end;
    462
    463	cmos_regs = op->resource[0].start;
    464	return platform_device_register(&rtc_cmos_device);
    465}
    466
    467static const struct of_device_id rtc_match[] = {
    468	{
    469		.name = "rtc",
    470		.compatible = "m5819",
    471	},
    472	{
    473		.name = "rtc",
    474		.compatible = "isa-m5819p",
    475	},
    476	{
    477		.name = "rtc",
    478		.compatible = "isa-m5823p",
    479	},
    480	{
    481		.name = "rtc",
    482		.compatible = "ds1287",
    483	},
    484	{},
    485};
    486
    487static struct platform_driver rtc_driver = {
    488	.probe		= rtc_probe,
    489	.driver = {
    490		.name = "rtc",
    491		.of_match_table = rtc_match,
    492	},
    493};
    494
    495static struct platform_device rtc_bq4802_device = {
    496	.name		= "rtc-bq4802",
    497	.id		= -1,
    498	.num_resources	= 1,
    499};
    500
    501static int bq4802_probe(struct platform_device *op)
    502{
    503
    504	printk(KERN_INFO "%pOF: BQ4802 regs at 0x%llx\n",
    505	       op->dev.of_node, op->resource[0].start);
    506
    507	rtc_bq4802_device.resource = &op->resource[0];
    508	return platform_device_register(&rtc_bq4802_device);
    509}
    510
    511static const struct of_device_id bq4802_match[] = {
    512	{
    513		.name = "rtc",
    514		.compatible = "bq4802",
    515	},
    516	{},
    517};
    518
    519static struct platform_driver bq4802_driver = {
    520	.probe		= bq4802_probe,
    521	.driver = {
    522		.name = "bq4802",
    523		.of_match_table = bq4802_match,
    524	},
    525};
    526
    527static unsigned char mostek_read_byte(struct device *dev, u32 ofs)
    528{
    529	struct platform_device *pdev = to_platform_device(dev);
    530	void __iomem *regs = (void __iomem *) pdev->resource[0].start;
    531
    532	return readb(regs + ofs);
    533}
    534
    535static void mostek_write_byte(struct device *dev, u32 ofs, u8 val)
    536{
    537	struct platform_device *pdev = to_platform_device(dev);
    538	void __iomem *regs = (void __iomem *) pdev->resource[0].start;
    539
    540	writeb(val, regs + ofs);
    541}
    542
    543static struct m48t59_plat_data m48t59_data = {
    544	.read_byte	= mostek_read_byte,
    545	.write_byte	= mostek_write_byte,
    546};
    547
    548static struct platform_device m48t59_rtc = {
    549	.name		= "rtc-m48t59",
    550	.id		= 0,
    551	.num_resources	= 1,
    552	.dev	= {
    553		.platform_data = &m48t59_data,
    554	},
    555};
    556
    557static int mostek_probe(struct platform_device *op)
    558{
    559	struct device_node *dp = op->dev.of_node;
    560
    561	/* On an Enterprise system there can be multiple mostek clocks.
    562	 * We should only match the one that is on the central FHC bus.
    563	 */
    564	if (of_node_name_eq(dp->parent, "fhc") &&
    565	    !of_node_name_eq(dp->parent->parent, "central"))
    566		return -ENODEV;
    567
    568	printk(KERN_INFO "%pOF: Mostek regs at 0x%llx\n",
    569	       dp, op->resource[0].start);
    570
    571	m48t59_rtc.resource = &op->resource[0];
    572	return platform_device_register(&m48t59_rtc);
    573}
    574
    575static const struct of_device_id mostek_match[] = {
    576	{
    577		.name = "eeprom",
    578	},
    579	{},
    580};
    581
    582static struct platform_driver mostek_driver = {
    583	.probe		= mostek_probe,
    584	.driver = {
    585		.name = "mostek",
    586		.of_match_table = mostek_match,
    587	},
    588};
    589
    590static struct platform_device rtc_sun4v_device = {
    591	.name		= "rtc-sun4v",
    592	.id		= -1,
    593};
    594
    595static struct platform_device rtc_starfire_device = {
    596	.name		= "rtc-starfire",
    597	.id		= -1,
    598};
    599
    600static int __init clock_init(void)
    601{
    602	if (this_is_starfire)
    603		return platform_device_register(&rtc_starfire_device);
    604
    605	if (tlb_type == hypervisor)
    606		return platform_device_register(&rtc_sun4v_device);
    607
    608	(void) platform_driver_register(&rtc_driver);
    609	(void) platform_driver_register(&mostek_driver);
    610	(void) platform_driver_register(&bq4802_driver);
    611
    612	return 0;
    613}
    614
    615/* Must be after subsys_initcall() so that busses are probed.  Must
    616 * be before device_initcall() because things like the RTC driver
    617 * need to see the clock registers.
    618 */
    619fs_initcall(clock_init);
    620
    621/* Return true if this is Hummingbird, aka Ultra-IIe */
    622static bool is_hummingbird(void)
    623{
    624	unsigned long ver, manuf, impl;
    625
    626	__asm__ __volatile__ ("rdpr %%ver, %0"
    627			      : "=&r" (ver));
    628	manuf = ((ver >> 48) & 0xffff);
    629	impl = ((ver >> 32) & 0xffff);
    630
    631	return (manuf == 0x17 && impl == 0x13);
    632}
    633
    634struct freq_table {
    635	unsigned long clock_tick_ref;
    636	unsigned int ref_freq;
    637};
    638static DEFINE_PER_CPU(struct freq_table, sparc64_freq_table) = { 0, 0 };
    639
    640unsigned long sparc64_get_clock_tick(unsigned int cpu)
    641{
    642	struct freq_table *ft = &per_cpu(sparc64_freq_table, cpu);
    643
    644	if (ft->clock_tick_ref)
    645		return ft->clock_tick_ref;
    646	return cpu_data(cpu).clock_tick;
    647}
    648EXPORT_SYMBOL(sparc64_get_clock_tick);
    649
    650#ifdef CONFIG_CPU_FREQ
    651
    652static int sparc64_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
    653				    void *data)
    654{
    655	struct cpufreq_freqs *freq = data;
    656	unsigned int cpu;
    657	struct freq_table *ft;
    658
    659	for_each_cpu(cpu, freq->policy->cpus) {
    660		ft = &per_cpu(sparc64_freq_table, cpu);
    661
    662		if (!ft->ref_freq) {
    663			ft->ref_freq = freq->old;
    664			ft->clock_tick_ref = cpu_data(cpu).clock_tick;
    665		}
    666
    667		if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
    668		    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
    669			cpu_data(cpu).clock_tick =
    670				cpufreq_scale(ft->clock_tick_ref, ft->ref_freq,
    671					      freq->new);
    672		}
    673	}
    674
    675	return 0;
    676}
    677
    678static struct notifier_block sparc64_cpufreq_notifier_block = {
    679	.notifier_call	= sparc64_cpufreq_notifier
    680};
    681
    682static int __init register_sparc64_cpufreq_notifier(void)
    683{
    684
    685	cpufreq_register_notifier(&sparc64_cpufreq_notifier_block,
    686				  CPUFREQ_TRANSITION_NOTIFIER);
    687	return 0;
    688}
    689
    690core_initcall(register_sparc64_cpufreq_notifier);
    691
    692#endif /* CONFIG_CPU_FREQ */
    693
    694static int sparc64_next_event(unsigned long delta,
    695			      struct clock_event_device *evt)
    696{
    697	return tick_operations.add_compare(delta) ? -ETIME : 0;
    698}
    699
    700static int sparc64_timer_shutdown(struct clock_event_device *evt)
    701{
    702	tick_operations.disable_irq();
    703	return 0;
    704}
    705
    706static struct clock_event_device sparc64_clockevent = {
    707	.features		= CLOCK_EVT_FEAT_ONESHOT,
    708	.set_state_shutdown	= sparc64_timer_shutdown,
    709	.set_next_event		= sparc64_next_event,
    710	.rating			= 100,
    711	.shift			= 30,
    712	.irq			= -1,
    713};
    714static DEFINE_PER_CPU(struct clock_event_device, sparc64_events);
    715
    716void __irq_entry timer_interrupt(int irq, struct pt_regs *regs)
    717{
    718	struct pt_regs *old_regs = set_irq_regs(regs);
    719	unsigned long tick_mask = tick_operations.softint_mask;
    720	int cpu = smp_processor_id();
    721	struct clock_event_device *evt = &per_cpu(sparc64_events, cpu);
    722
    723	clear_softint(tick_mask);
    724
    725	irq_enter();
    726
    727	local_cpu_data().irq0_irqs++;
    728	kstat_incr_irq_this_cpu(0);
    729
    730	if (unlikely(!evt->event_handler)) {
    731		printk(KERN_WARNING
    732		       "Spurious SPARC64 timer interrupt on cpu %d\n", cpu);
    733	} else
    734		evt->event_handler(evt);
    735
    736	irq_exit();
    737
    738	set_irq_regs(old_regs);
    739}
    740
    741void setup_sparc64_timer(void)
    742{
    743	struct clock_event_device *sevt;
    744	unsigned long pstate;
    745
    746	/* Guarantee that the following sequences execute
    747	 * uninterrupted.
    748	 */
    749	__asm__ __volatile__("rdpr	%%pstate, %0\n\t"
    750			     "wrpr	%0, %1, %%pstate"
    751			     : "=r" (pstate)
    752			     : "i" (PSTATE_IE));
    753
    754	tick_operations.init_tick();
    755
    756	/* Restore PSTATE_IE. */
    757	__asm__ __volatile__("wrpr	%0, 0x0, %%pstate"
    758			     : /* no outputs */
    759			     : "r" (pstate));
    760
    761	sevt = this_cpu_ptr(&sparc64_events);
    762
    763	memcpy(sevt, &sparc64_clockevent, sizeof(*sevt));
    764	sevt->cpumask = cpumask_of(smp_processor_id());
    765
    766	clockevents_register_device(sevt);
    767}
    768
    769#define SPARC64_NSEC_PER_CYC_SHIFT	10UL
    770
    771static struct clocksource clocksource_tick = {
    772	.rating		= 100,
    773	.mask		= CLOCKSOURCE_MASK(64),
    774	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
    775};
    776
    777static unsigned long tb_ticks_per_usec __read_mostly;
    778
    779void __delay(unsigned long loops)
    780{
    781	unsigned long bclock = get_tick();
    782
    783	while ((get_tick() - bclock) < loops)
    784		;
    785}
    786EXPORT_SYMBOL(__delay);
    787
    788void udelay(unsigned long usecs)
    789{
    790	__delay(tb_ticks_per_usec * usecs);
    791}
    792EXPORT_SYMBOL(udelay);
    793
    794static u64 clocksource_tick_read(struct clocksource *cs)
    795{
    796	return get_tick();
    797}
    798
    799static void __init get_tick_patch(void)
    800{
    801	unsigned int *addr, *instr, i;
    802	struct get_tick_patch *p;
    803
    804	if (tlb_type == spitfire && is_hummingbird())
    805		return;
    806
    807	for (p = &__get_tick_patch; p < &__get_tick_patch_end; p++) {
    808		instr = (tlb_type == spitfire) ? p->tick : p->stick;
    809		addr = (unsigned int *)(unsigned long)p->addr;
    810		for (i = 0; i < GET_TICK_NINSTR; i++) {
    811			addr[i] = instr[i];
    812			/* ensure that address is modified before flush */
    813			wmb();
    814			flushi(&addr[i]);
    815		}
    816	}
    817}
    818
    819static void __init init_tick_ops(struct sparc64_tick_ops *ops)
    820{
    821	unsigned long freq, quotient, tick;
    822
    823	freq = ops->get_frequency();
    824	quotient = clocksource_hz2mult(freq, SPARC64_NSEC_PER_CYC_SHIFT);
    825	tick = ops->get_tick();
    826
    827	ops->offset = (tick * quotient) >> SPARC64_NSEC_PER_CYC_SHIFT;
    828	ops->ticks_per_nsec_quotient = quotient;
    829	ops->frequency = freq;
    830	tick_operations = *ops;
    831	get_tick_patch();
    832}
    833
    834void __init time_init_early(void)
    835{
    836	if (tlb_type == spitfire) {
    837		if (is_hummingbird()) {
    838			init_tick_ops(&hbtick_operations);
    839			clocksource_tick.archdata.vclock_mode = VCLOCK_NONE;
    840		} else {
    841			init_tick_ops(&tick_operations);
    842			clocksource_tick.archdata.vclock_mode = VCLOCK_TICK;
    843		}
    844	} else {
    845		init_tick_ops(&stick_operations);
    846		clocksource_tick.archdata.vclock_mode = VCLOCK_STICK;
    847	}
    848}
    849
    850void __init time_init(void)
    851{
    852	unsigned long freq;
    853
    854	freq = tick_operations.frequency;
    855	tb_ticks_per_usec = freq / USEC_PER_SEC;
    856
    857	clocksource_tick.name = tick_operations.name;
    858	clocksource_tick.read = clocksource_tick_read;
    859
    860	clocksource_register_hz(&clocksource_tick, freq);
    861	printk("clocksource: mult[%x] shift[%d]\n",
    862	       clocksource_tick.mult, clocksource_tick.shift);
    863
    864	sparc64_clockevent.name = tick_operations.name;
    865	clockevents_calc_mult_shift(&sparc64_clockevent, freq, 4);
    866
    867	sparc64_clockevent.max_delta_ns =
    868		clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent);
    869	sparc64_clockevent.max_delta_ticks = 0x7fffffffffffffffUL;
    870	sparc64_clockevent.min_delta_ns =
    871		clockevent_delta2ns(0xF, &sparc64_clockevent);
    872	sparc64_clockevent.min_delta_ticks = 0xF;
    873
    874	printk("clockevent: mult[%x] shift[%d]\n",
    875	       sparc64_clockevent.mult, sparc64_clockevent.shift);
    876
    877	setup_sparc64_timer();
    878}
    879
    880unsigned long long sched_clock(void)
    881{
    882	unsigned long quotient = tick_operations.ticks_per_nsec_quotient;
    883	unsigned long offset = tick_operations.offset;
    884
    885	/* Use barrier so the compiler emits the loads first and overlaps load
    886	 * latency with reading tick, because reading %tick/%stick is a
    887	 * post-sync instruction that will flush and restart subsequent
    888	 * instructions after it commits.
    889	 */
    890	barrier();
    891
    892	return ((get_tick() * quotient) >> SPARC64_NSEC_PER_CYC_SHIFT) - offset;
    893}
    894
    895int read_current_timer(unsigned long *timer_val)
    896{
    897	*timer_val = get_tick();
    898	return 0;
    899}