firmware_x86_64.rs0.00%
1
// Copyright 2024 Google LLC2
//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 at6
//7
// https://www.apache.org/licenses/LICENSE-2.08
//9
// Unless required by applicable law or agreed to in writing, software10
// 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 and13
// limitations under the License.14
15
use std::fs::File;16
use std::io::Read;17
use std::path::Path;18
use std::sync::Arc;19
20
use snafu::ResultExt;21
22
use crate::arch::layout::MEM_64_START;23
use crate::arch::reg::{Cr0, DtReg, DtRegVal, Reg, Rflags, SReg, SegAccess, SegReg, SegRegVal};24
use crate::loader::{InitState, Result, error};25
use crate::mem::mapped::ArcMemPages;26
use crate::mem::{MemRegion, MemRegionType, Memory};27
28
pub 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