diff --git a/devicemodel/hw/platform/rtc.c b/devicemodel/hw/platform/rtc.c index 0d424f9c0..88092a7da 100644 --- a/devicemodel/hw/platform/rtc.c +++ b/devicemodel/hw/platform/rtc.c @@ -31,19 +31,14 @@ #include #include #include -#include #include -#include -#include -#include -#include -#include #include "vmmapi.h" #include "inout.h" #include "mc146818rtc.h" #include "rtc.h" #include "mevent.h" +#include "timer.h" /* #define DEBUG_RTC */ #ifdef DEBUG_RTC @@ -76,10 +71,8 @@ struct rtcdev { struct vrtc { struct vmctx *vm; pthread_mutex_t mtx; - int signal_fd; - struct mevent *mevp; - timer_t periodic_timer_id; /*periodic timer id*/ - timer_t update_timer_id; /*update timer id*/ + struct acrn_timer update_timer; /* timer for update interrupt */ + struct acrn_timer periodic_timer; /* timer for periodic interrupt */ u_int addr; /* RTC register to read or write */ time_t base_uptime; time_t base_rtctime; @@ -576,34 +569,17 @@ fail: } static void -vrtc_create_timer(timer_t *timer_id, time_t sec, time_t nsec) +vrtc_start_timer(struct acrn_timer *timer, time_t sec, time_t nsec) { - struct sigevent sigevt; struct itimerspec ts; - memset(&sigevt, 0, sizeof(struct sigevent)); - memset(&ts, 0, sizeof(struct itimerspec)); - - /* there is no glibc wrapper for gettid */ - sigevt._sigev_un._tid = syscall(SYS_gettid); - sigevt.sigev_value.sival_ptr = timer_id; - sigevt.sigev_notify = SIGEV_THREAD_ID | SIGEV_SIGNAL; - sigevt.sigev_signo = VRTC_TIMER_SIGNO; - - assert(timer_create(CLOCK_REALTIME, &sigevt, timer_id) == 0); /*setting the interval time*/ ts.it_interval.tv_sec = sec; ts.it_interval.tv_nsec = nsec; /*set the delay time it will be started when timer_setting*/ ts.it_value.tv_sec = sec; ts.it_value.tv_nsec = nsec; - assert(timer_settime(*timer_id, 0, &ts, NULL) == 0); -} - -static void -vrtc_delete_timer(timer_t timerid) -{ - timer_delete(timerid); + assert(acrn_timer_settime(timer, &ts) == 0); } static int @@ -814,15 +790,8 @@ vrtc_set_reg_b(struct vrtc *vrtc, uint8_t newval) newfreq = vrtc_freq(vrtc); if (pintr_enabled(vrtc) && newfreq != oldfreq) { - /*stop the previous timer*/ - if (vrtc->periodic_timer_id > 0) { - assert(timer_delete(vrtc->periodic_timer_id) == 0); - vrtc->periodic_timer_id = 0; - } - - /*create the new periodic timer*/ - vrtc_create_timer(&vrtc->periodic_timer_id, 0, newfreq); - assert(vrtc->periodic_timer_id > 0); + /*start the new periodic timer*/ + vrtc_start_timer(&vrtc->periodic_timer, 0, newfreq); } else { /*Nothing to do*/ @@ -875,15 +844,8 @@ vrtc_set_reg_a(struct vrtc *vrtc, uint8_t newval) newfreq = vrtc_freq(vrtc); if (pintr_enabled(vrtc) && newfreq != oldfreq) { - /*stop the previous timer*/ - if (vrtc->periodic_timer_id > 0) { - assert(timer_delete(vrtc->periodic_timer_id) == 0); - vrtc->periodic_timer_id = 0; - } - - /*create the new periodic timer*/ - vrtc_create_timer(&vrtc->periodic_timer_id, 0, newfreq); - assert(vrtc->periodic_timer_id > 0); + /*start the new periodic timer*/ + vrtc_start_timer(&vrtc->periodic_timer, 0, newfreq); } else { /*Nothing to do*/ } @@ -1108,41 +1070,6 @@ vrtc_enable_localtime(int l_time) local_time = l_time; } -static void -vrtc_handle_timer(int fd __attribute__((unused)), - enum ev_type t __attribute__((unused)), - void *arg) -{ - struct vrtc *vrtc = arg; - struct signalfd_siginfo info; - timer_t *timer_id; - int len; - - while (1) { - len = read(vrtc->signal_fd, &info, sizeof(info)); - if (len == -1 && errno == EAGAIN) - break; - if (len == -1) { - RTC_DEBUG("signal_fd read failed: error = %d\n", - errno); - break; - } - if (len != sizeof(info)) { - RTC_DEBUG("signal_fd read len error: len = %d\n", - len); - break; - } - - timer_id = (timer_t *)info.ssi_ptr; - if (*timer_id == vrtc->update_timer_id) - vrtc_update_timer(vrtc); - else if (*timer_id == vrtc->periodic_timer_id) - vrtc_periodic_timer(vrtc); - else - RTC_DEBUG("unsupported timer_id 0xlx\n", *timer_id); - } -} - int vrtc_init(struct vmctx *ctx) { @@ -1151,8 +1078,6 @@ vrtc_init(struct vmctx *ctx) int err; struct rtcdev *rtc; time_t curtime; - sigset_t mask; - int flags; struct inout_port rtc_addr, rtc_data; vrtc = calloc(1, sizeof(struct vrtc)); @@ -1226,30 +1151,14 @@ vrtc_init(struct vmctx *ctx) secs_to_rtc(curtime, vrtc, 0); pthread_mutex_unlock(&vrtc->mtx); - /*block VRTC_TIMER_SIGNO so it can be polled by signalfd*/ - sigemptyset(&mask); - sigaddset(&mask, VRTC_TIMER_SIGNO); - pthread_sigmask(SIG_BLOCK, &mask, NULL); + /* init periodic interrupt timer */ + vrtc->periodic_timer.clockid = CLOCK_REALTIME; + acrn_timer_init(&vrtc->periodic_timer, vrtc_periodic_timer, vrtc); - /*create signalfd*/ - vrtc->signal_fd = signalfd(-1, &mask, 0); - assert(vrtc->signal_fd > 0); - - /*set close-on-exec*/ - flags = fcntl(vrtc->signal_fd, F_GETFD); - fcntl(vrtc->signal_fd, F_SETFD, flags | FD_CLOEXEC); - - /*set non-block*/ - flags = fcntl(vrtc->signal_fd, F_GETFL); - fcntl(vrtc->signal_fd, F_SETFL, flags | O_NONBLOCK); - - vrtc->mevp = mevent_add(vrtc->signal_fd, EVF_READ, - vrtc_handle_timer, vrtc); - assert(vrtc->mevp != NULL); - - /*create update interrupt timer(1s)*/ - vrtc_create_timer(&vrtc->update_timer_id, 1, 0); - assert(vrtc->update_timer_id > 0); + /* init update interrupt timer(1s)*/ + vrtc->update_timer.clockid = CLOCK_REALTIME; + acrn_timer_init(&vrtc->update_timer, vrtc_update_timer, vrtc); + vrtc_start_timer(&vrtc->update_timer, 1, 0); return 0; } @@ -1259,29 +1168,10 @@ vrtc_deinit(struct vmctx *ctx) { struct vrtc *vrtc = ctx->vrtc; struct inout_port iop; - sig_t prev_sig_handler; - /*delete timer*/ - if (vrtc->update_timer_id > 0) { - vrtc_delete_timer(vrtc->update_timer_id); - vrtc->update_timer_id = (timer_t)-1; - } - - if (vrtc->periodic_timer_id > 0) { - vrtc_delete_timer(vrtc->periodic_timer_id); - vrtc->periodic_timer_id = (timer_t)-1; - } - - if (vrtc->mevp) - mevent_delete(vrtc->mevp); - - if (vrtc->signal_fd > 0) - close(vrtc->signal_fd); - - /*clear pending signals*/ - prev_sig_handler = signal(VRTC_TIMER_SIGNO, SIG_IGN); - if (prev_sig_handler != SIG_ERR) - signal(VRTC_TIMER_SIGNO, prev_sig_handler); + /*deinit acrn_timer*/ + acrn_timer_deinit(&vrtc->periodic_timer); + acrn_timer_deinit(&vrtc->update_timer); memset(&iop, 0, sizeof(struct inout_port)); iop.name = "rtc";