Alioth Code Coverage

firmware_x86_64.rs0.00%

1// Copyright 2024 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fs::File;
16use std::io::Read;
17use std::path::Path;
18use std::sync::Arc;
19
20use snafu::ResultExt;
21
22use crate::arch::layout::MEM_64_START;
23use crate::arch::reg::{Cr0, DtReg, DtRegVal, Reg, Rflags, SReg, SegAccess, SegReg, SegRegVal};
24use crate::loader::{InitState, Result, error};
25use crate::mem::mapped::ArcMemPages;
26use crate::mem::{MemRegion, MemRegionType, Memory};
27
28pub fn load<P: AsRef<Path>>(memory: &Memory, path: P) -> Result<(InitState, ArcMemPages)> {
29 let access_firmware = error::AccessFile {
30 path: path.as_ref(),
31 };
32 let mut file = File::open(&path).context(access_firmware)?;
33 let size = file.metadata().context(access_firmware)?.len();
34 if size & 0xfff != 0 {
35 return error::SizeNotAligned { size }.fail();
36 }
37
38 let mut rom =
39 ArcMemPages::from_anonymous(size as usize, None, None).context(error::AddMemSlot)?;
40 file.read_exact(rom.as_slice_mut())
41 .context(access_firmware)?;
42
43 let gpa = MEM_64_START - size;
44 let region = Arc::new(MemRegion::with_dev_mem(
45 rom.clone(),
46 MemRegionType::Reserved,
47 ));
48 memory.add_region(gpa, region).context(error::AddMemSlot)?;
49 let boot_cs = SegRegVal {
50 selector: 0xf000,
51 base: 0xffff0000,
52 limit: 0xffff,
53 access: SegAccess(0x9a),
54 };
55 let boot_ds = SegRegVal {
56 selector: 0x0,
57 base: 0x0,
58 limit: 0xffff,
59 access: SegAccess(0x93),
60 };
61 let boot_ss = SegRegVal {
62 selector: 0x0,
63 base: 0x0,
64 limit: 0xffff,
65 access: SegAccess(0x92),
66 };
67 let boot_tr = SegRegVal {
68 selector: 0x0,
69 base: 0x0,
70 limit: 0xffff,
71 access: SegAccess(0x83),
72 };
73 let boot_ldtr = SegRegVal {
74 selector: 0x0,
75 base: 0x0,
76 limit: 0xffff,
77 access: SegAccess(0x82),
78 };
79 let init = InitState {
80 regs: vec![
81 (Reg::Rax, 0),
82 (Reg::Rbx, 0),
83 (Reg::Rcx, 0),
84 (Reg::Rdx, 0x600),
85 (Reg::Rsi, 0),
86 (Reg::Rdi, 0),
87 (Reg::Rsp, 0),
88 (Reg::Rbp, 0),
89 (Reg::R8, 0),
90 (Reg::R9, 0),
91 (Reg::R10, 0),
92 (Reg::R11, 0),
93 (Reg::R12, 0),
94 (Reg::R13, 0),
95 (Reg::R14, 0),
96 (Reg::R15, 0),
97 (Reg::Rip, 0xfff0),
98 (Reg::Rflags, Rflags::RESERVED_1.bits() as u64),
99 ],
100 sregs: vec![
101 (SReg::Cr0, (Cr0::ET | Cr0::NW | Cr0::CD).bits() as u64),
102 (SReg::Cr2, 0),
103 (SReg::Cr3, 0),
104 (SReg::Cr4, 0),
105 (SReg::Cr8, 0),
106 (SReg::Efer, 0),
107 ],
108 seg_regs: vec![
109 (SegReg::Cs, boot_cs),
110 (SegReg::Ds, boot_ds),
111 (SegReg::Es, boot_ds),
112 (SegReg::Fs, boot_ds),
113 (SegReg::Gs, boot_ds),
114 (SegReg::Ss, boot_ss),
115 (SegReg::Tr, boot_tr),
116 (SegReg::Ldtr, boot_ldtr),
117 ],
118 dt_regs: vec![
119 (
120 DtReg::Idtr,
121 DtRegVal {
122 base: 0,
123 limit: 0xffff,
124 },
125 ),
126 (
127 DtReg::Gdtr,
128 DtRegVal {
129 base: 0,
130 limit: 0xffff,
131 },
132 ),
133 ],
134 initramfs: None,
135 };
136 Ok((init, rom))
137}
138