summary refs log tree commit diff
path: root/devices/src/cmos.rs
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2019-05-22 10:24:24 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-05-23 02:14:28 -0700
commitced74e6f2f4653049fc9a23959214bd9b3a3ab4a (patch)
tree97c780836f97d40292242419bb24e5167bc9cf16 /devices/src/cmos.rs
parent2b570f698a8dc018a61a192a377a281546585f02 (diff)
downloadcrosvm-ced74e6f2f4653049fc9a23959214bd9b3a3ab4a.tar
crosvm-ced74e6f2f4653049fc9a23959214bd9b3a3ab4a.tar.gz
crosvm-ced74e6f2f4653049fc9a23959214bd9b3a3ab4a.tar.bz2
crosvm-ced74e6f2f4653049fc9a23959214bd9b3a3ab4a.tar.lz
crosvm-ced74e6f2f4653049fc9a23959214bd9b3a3ab4a.tar.xz
crosvm-ced74e6f2f4653049fc9a23959214bd9b3a3ab4a.tar.zst
crosvm-ced74e6f2f4653049fc9a23959214bd9b3a3ab4a.zip
devices: cmos: report memory size in CMOS
This matches the QEMU CMOS implementation and is used by BIOSes to
determine the valid memory regions to add to the e820 map.

BUG=b:133358982
TEST=Boot u-boot qemu build; observe memory size

Change-Id: I27956bc05738b5dd5b84240d5137cb06846aaab9
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1625330
Tested-by: kokoro <noreply+kokoro@google.com>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'devices/src/cmos.rs')
-rw-r--r--devices/src/cmos.rs28
1 files changed, 22 insertions, 6 deletions
diff --git a/devices/src/cmos.rs b/devices/src/cmos.rs
index 7cf9006..daf391c 100644
--- a/devices/src/cmos.rs
+++ b/devices/src/cmos.rs
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 use libc::{gmtime_r, time, time_t, tm};
+use std::cmp::min;
 use std::mem;
 
 use crate::BusDevice;
@@ -19,12 +20,27 @@ pub struct Cmos {
 }
 
 impl Cmos {
-    /// Constructs a CMOS/RTC device with zero data.
-    pub fn new() -> Cmos {
-        Cmos {
-            index: 0,
-            data: [0; DATA_LEN],
-        }
+    /// Constructs a CMOS/RTC device with initial data.
+    /// `mem_below_4g` is the size of memory in bytes below the 32-bit gap.
+    /// `mem_above_4g` is the size of memory in bytes above the 32-bit gap.
+    pub fn new(mem_below_4g: u64, mem_above_4g: u64) -> Cmos {
+        let mut data = [0u8; DATA_LEN];
+
+        // Extended memory from 16 MB to 4 GB in units of 64 KB
+        let ext_mem = min(
+            0xFFFF,
+            mem_below_4g.saturating_sub(16 * 1024 * 1024) / (64 * 1024),
+        );
+        data[0x34] = ext_mem as u8;
+        data[0x35] = (ext_mem >> 8) as u8;
+
+        // High memory (> 4GB) in units of 64 KB
+        let high_mem = min(0xFFFFFF, mem_above_4g / (64 * 1024));
+        data[0x5b] = high_mem as u8;
+        data[0x5c] = (high_mem >> 8) as u8;
+        data[0x5d] = (high_mem >> 16) as u8;
+
+        Cmos { index: 0, data }
     }
 }