blob: de56348fd082d0096669b30fddcd00fab037d5bb [file] [log] [blame]
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! This crate provides access to an OpenTitan timer that satisfies the
//! HardwareTimer interface.
#![no_std]
#[allow(dead_code)]
mod opentitan_timer;
use opentitan_timer::*;
use cantrip_timer_interface::{HardwareTimer, Ticks};
use core::time::Duration;
// Primary clock frequency.
use reg_constants::platform::TOP_MATCHA_SMC_TIMER0_BASE_FREQ_HZ as TIMER_BASE_FREQ;
const TIMER_FREQ: u64 = 10_000;
const PRESCALE: u16 = ((TIMER_BASE_FREQ / TIMER_FREQ) - 1) as u16;
pub struct OtTimer;
impl HardwareTimer for OtTimer {
fn setup(&self) {
set_config(Config::new().with_prescale(PRESCALE).with_step(1));
set_compare_high(0);
set_value_low(0xFFFF_0000);
set_intr_status(IntrStatus::new().with_timer0(true)); // w1c
set_intr_enable(IntrEnable::new().with_timer0(false));
set_ctrl(Ctrl::new().with_active(true));
}
fn ack_interrupt(&self) {
set_intr_status(IntrStatus::new().with_timer0(true));
set_intr_enable(IntrEnable::new().with_timer0(false));
}
fn now(&self) -> Ticks {
let low: u32 = get_value_low();
let high: u32 = get_value_high();
((high as u64) << 32) | low as u64
}
fn deadline(&self, duration: Duration) -> Ticks {
let tick_duration = (TIMER_FREQ * duration.as_millis() as u64) / 1000;
self.now() + tick_duration
}
fn set_alarm(&self, deadline: Ticks) {
let high = (deadline >> 32) as u32;
let low = (deadline & 0xffffffff) as u32;
// Recommended approach for setting the two compare registers
// (RISC-V Privileged Architectures 3.1.15)
set_compare_low(0xffffffff);
set_compare_high(high);
set_compare_low(low);
set_intr_enable(IntrEnable::new().with_timer0(true));
}
}