From 19897ff143b51b465294f4bef7e34282cb56b3f4 Mon Sep 17 00:00:00 2001
From: Recolic Keghart <root@recolic.net>
Date: Sun, 29 Dec 2019 20:30:20 +0800
Subject: [PATCH] >  Manual commit:  fix timer problem U201614531 recolic Linux
 RECOLICPC 5.4.6-arch3-1 #1 SMP PREEMPT Tue, 24 Dec 2019 04:36:53 +0000 x86_64
 GNU/Linux  20:30:20 up 1 day,  2:04,  1 user,  load average: 1.48, 1.27, 1.23
 f2f315ecd19fd1dcf2b60d6edcf47eeb3341fa25

---
 nemu/src/device/timer.cc                      | 17 ++++++++++++-----
 nexus-am/am/arch/x86-nemu/src/devices/timer.c |  8 ++++----
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/nemu/src/device/timer.cc b/nemu/src/device/timer.cc
index 9fd1ea7..e4e9127 100644
--- a/nemu/src/device/timer.cc
+++ b/nemu/src/device/timer.cc
@@ -12,17 +12,24 @@ void timer_intr() {
 }
 
 static uint32_t *rtc_port_base;
+static uint32_t startup_milli = 0;
+
+uint32_t host_get_uptime_milli() {
+  struct timeval now;
+  gettimeofday(&now, NULL);
+  uint32_t seconds = now.tv_sec;
+  uint32_t useconds = now.tv_usec;
+
+  return seconds * 1000 + (useconds + 500) / 1000 - startup_milli;
+}
 
 void rtc_io_handler(ioaddr_t addr, int len, bool is_write) {
   if (!is_write) {
-    struct timeval now;
-    gettimeofday(&now, NULL);
-    uint32_t seconds = now.tv_sec;
-    uint32_t useconds = now.tv_usec;
-    rtc_port_base[0] = seconds * 1000 + (useconds + 500) / 1000;
+    rtc_port_base[0] = host_get_uptime_milli();
   }
 }
 
 void init_timer() {
   rtc_port_base = (uint32_t *)add_pio_map(RTC_PORT, 4, rtc_io_handler);
+  startup_milli = host_get_uptime_milli();
 }
diff --git a/nexus-am/am/arch/x86-nemu/src/devices/timer.c b/nexus-am/am/arch/x86-nemu/src/devices/timer.c
index 9fd970c..1c009e0 100644
--- a/nexus-am/am/arch/x86-nemu/src/devices/timer.c
+++ b/nexus-am/am/arch/x86-nemu/src/devices/timer.c
@@ -2,16 +2,16 @@
 #include <x86.h>
 #include <amdev.h>
 
+#include <klib.h>
+
 size_t timer_read(uintptr_t reg, void *buf, size_t size) {
   const size_t rtc_port_id = 0x48;
-  uint64_t curr_time;
 
   switch (reg) {
     case _DEVREG_TIMER_UPTIME: {
       _UptimeReg *uptime = (_UptimeReg *)buf;
-      curr_time = inl(rtc_port_id);
-      uptime->hi = curr_time >> 32;
-      uptime->lo = (uint32_t) curr_time;
+      uptime->hi = 0;
+      uptime->lo = inl(rtc_port_id);
       return sizeof(_UptimeReg);
     }
     case _DEVREG_TIMER_DATE: {
-- 
GitLab