data_in now accepts buffer and size over 4MiB, and frees allocated prd/command buffers

This commit is contained in:
pjht 2024-08-12 20:48:01 -05:00
parent 82e3f2f7b5
commit fd3eae75ed
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
2 changed files with 57 additions and 20 deletions

View File

@ -21,3 +21,8 @@ x86_64 = "0.15.1"
[patch.crates-io] [patch.crates-io]
tock-registers = {path = "./tock-registers"} tock-registers = {path = "./tock-registers"}
[profile.release]
strip = true
lto = true
opt-level = "s"

View File

@ -65,9 +65,11 @@ impl AhciPort {
fn issue_command_data_in( fn issue_command_data_in(
&self, &self,
fis: &RegH2DFis, fis: &RegH2DFis,
len: usize, buf: &mut [u8]
) -> Result<Vec<u8>, CommandIssueError> { ) -> Result<(), CommandIssueError> {
if len > 0x40_0000 { let len = buf.len();
if len > 0x40_0000 * 0xFFFF {
return Err(CommandIssueError::DataTooBig); return Err(CommandIssueError::DataTooBig);
} }
@ -77,7 +79,23 @@ impl AhciPort {
.map_free_cont_phys(len.div_ceil(4096)) .map_free_cont_phys(len.div_ceil(4096))
.unwrap(); .unwrap();
let prdt = [Prd::new(data_buf_phys, len as u32, false).unwrap()]; let num_prds = len.div_ceil(0x40_0000);
let prdt = (0..num_prds)
.map(|i| {
let size = if i == num_prds - 1 {
len - (i * 0x40_0000)
} else {
0x40_0000
};
println!(
"Prd::new({:#x}, {:#x}, false)",
data_buf_phys + (i * 0x40_0000) as u64,
size as u32
);
Prd::new(data_buf_phys + (i * 0x40_0000) as u64, size as u32, false).unwrap()
})
.collect_vec();
unsafe { unsafe {
self.issue_command_prdt(fis, &prdt)?; self.issue_command_prdt(fis, &prdt)?;
@ -89,12 +107,16 @@ impl AhciPort {
len, len,
)) ))
}; };
let mut data = vec![0; len];
data_vol.copy_into_slice(data.as_mut_slice()); data_vol.copy_into_slice(buf);
// TODO: Free data buffer std::os::mikros::address_space::ACTIVE_SPACE
Ok(data) .lock()
.unwrap()
.unmap(data_buf, len.div_ceil(4096))
.unwrap();
Ok(())
} }
unsafe fn issue_command_prdt( unsafe fn issue_command_prdt(
@ -164,7 +186,12 @@ impl AhciPort {
return Err(CommandIssueError::CommandFailed); return Err(CommandIssueError::CommandFailed);
} }
// TODO: Free command table std::os::mikros::address_space::ACTIVE_SPACE
.lock()
.unwrap()
.unmap(buf, tbl_size.div_ceil(4096))
.unwrap();
Ok(()) Ok(())
} }
@ -371,10 +398,10 @@ fn main() {
.build() .build()
.unwrap(); .unwrap();
if let Ok(data) = port.issue_command_data_in(&cmd_fis, 512) { let mut ident_buf = [0; 512];
let identify_data = IdentifyData::read(&mut Cursor::new(data.as_slice())).unwrap();
dbg!(&identify_data); if port.issue_command_data_in(&cmd_fis, &mut ident_buf).is_ok() {
let identify_data = IdentifyData::read(&mut Cursor::new(ident_buf.as_slice())).unwrap();
let sect_sz_info_valid = identify_data.phys_log_sect_sz & 0xC000 == 0x4000; let sect_sz_info_valid = identify_data.phys_log_sect_sz & 0xC000 == 0x4000;
let sect_size = if sect_sz_info_valid { let sect_size = if sect_sz_info_valid {
@ -427,16 +454,14 @@ fn main() {
.build() .build()
.unwrap(); .unwrap();
let Ok(data) = port.issue_command_data_in(&cmd_fis, 512) else { if port.issue_command_data_in(&cmd_fis, &mut ident_buf).is_err() {
syslog_client syslog_client
.send_text_message("ahci", format!("Port {} failed to identify", port.phys_no)) .send_text_message("ahci", format!("Port {} failed to identify", port.phys_no))
.unwrap(); .unwrap();
continue; continue;
}; };
let identify_data = IdentifyDataATAPI::read(&mut Cursor::new(data.as_slice())).unwrap(); let identify_data = IdentifyDataATAPI::read(&mut Cursor::new(ident_buf.as_slice())).unwrap();
dbg!(&identify_data);
syslog_client syslog_client
.send_text_message( .send_text_message(
@ -466,7 +491,10 @@ fn main() {
.build() .build()
.unwrap(); .unwrap();
let mbr = avail_ports[0].issue_command_data_in(&cmd_fis, 512).unwrap(); let mut mbr = [0; 512];
avail_ports[0].issue_command_data_in(&cmd_fis, &mut mbr).unwrap();
let mbr_entries = (0..4) let mbr_entries = (0..4)
.map(|i| { .map(|i| {
@ -517,7 +545,9 @@ fn main() {
.build() .build()
.unwrap(); .unwrap();
let gpt_header = avail_ports[0].issue_command_data_in(&cmd_fis, 512).unwrap(); let mut gpt_header = [0; 512];
avail_ports[0].issue_command_data_in(&cmd_fis, &mut gpt_header).unwrap();
if &gpt_header[0..8] != b"EFI PART" { if &gpt_header[0..8] != b"EFI PART" {
println!("Invalid GPT signature!"); println!("Invalid GPT signature!");
@ -570,8 +600,10 @@ fn main() {
.build() .build()
.unwrap(); .unwrap();
let gpt_part_table = avail_ports[0] let mut gpt_part_table = vec![0; part_table_num_lbas * 512];
.issue_command_data_in(&cmd_fis, part_table_num_lbas * 512)
avail_ports[0]
.issue_command_data_in(&cmd_fis, gpt_part_table.as_mut_slice())
.unwrap(); .unwrap();
for i in 0..num_parts { for i in 0..num_parts {