lvtt_value = APIC_TIMER_MODE_ONESHOT | LOCAL_TIMER_VECTOR;
apic_write(APIC_LVTT, lvtt_value);
- tmp_value = apic_read(APIC_TDCR);
- apic_write(APIC_TDCR, tmp_value | APIC_TDR_DIV_1);
+ tmp_value = apic_read(APIC_TDCR) & ~APIC_TDR_DIV_MASK;
+ apic_write(APIC_TDCR, tmp_value | PASTE(APIC_TDR_DIV_, APIC_DIVISOR));
apic_write(APIC_TMICT, clocks / APIC_DIVISOR);
}
* APIC irq that way.
*/
+#define BUS_SCALE_SHIFT 18
+
static void __init calibrate_APIC_clock(void)
{
unsigned long bus_freq; /* KAF: pointer-size avoids compile warns. */
/* set up multipliers for accurate timer code */
bus_cycle = 1000000000000UL / bus_freq; /* in pico seconds */
bus_cycle += (1000000000000UL % bus_freq) * 2 > bus_freq;
- bus_scale = (1000*262144)/bus_cycle;
- bus_scale += ((1000 * 262144) % bus_cycle) * 2 > bus_cycle;
+ bus_scale = (1000 << BUS_SCALE_SHIFT) / bus_cycle;
+ bus_scale += ((1000 << BUS_SCALE_SHIFT) % bus_cycle) * 2 > bus_cycle;
apic_printk(APIC_VERBOSE, "..... bus_scale = %#x\n", bus_scale);
/* reset APIC to zero timeout value */
}
if ( timeout && ((expire = timeout - NOW()) > 0) )
- apic_tmict = min_t(u64, (bus_scale * expire) >> 18, UINT_MAX);
+ apic_tmict = min_t(uint64_t, (bus_scale * expire) >> BUS_SCALE_SHIFT,
+ UINT32_MAX);
apic_write(APIC_TMICT, (unsigned long)apic_tmict);
static void vlapic_set_tdcr(struct vlapic *vlapic, unsigned int val)
{
/* Only bits 0, 1 and 3 are settable; others are MBZ. */
- val &= 0xb;
+ val &= APIC_TDR_DIV_MASK;
vlapic_set_reg(vlapic, APIC_TDCR, val);
/* Update the demangled hw.timer_divisor. */
{
uint32_t current_divisor = vlapic->hw.timer_divisor;
- vlapic_set_tdcr(vlapic, val & 0xb);
+ vlapic_set_tdcr(vlapic, val);
vlapic_update_timer(vlapic, vlapic_get_reg(vlapic, APIC_LVTT), false,
current_divisor);
break;
case APIC_TDCR:
- if ( msr_content & ~APIC_TDR_DIV_1 )
+ if ( msr_content & ~APIC_TDR_DIV_MASK )
return X86EMUL_EXCEPTION;
break;
#define APIC_TMICT 0x380
#define APIC_TMCCT 0x390
#define APIC_TDCR 0x3E0
-#define APIC_TDR_DIV_TMBASE (1<<2)
+#define APIC_TDR_DIV_MASK 0xB
#define APIC_TDR_DIV_1 0xB
#define APIC_TDR_DIV_2 0x0
#define APIC_TDR_DIV_4 0x1
#define count_args(args...) \
count_args_(., ## args, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+/* Indirect macros required for expanded argument pasting. */
+#define PASTE_(a, b) a ## b
+#define PASTE(a, b) PASTE_(a, b)
+
#ifndef __ASSEMBLY__
#include <xen/inttypes.h>