|
| 1 | +use crate::{address::VirtAddr, mm::PAGE_SIZE, process_manager::process_memory::ALLOCATION_RANGE_VIRT_START}; |
| 2 | + |
| 3 | +use super::{allocation::AllocationRange, process::ProcessID, process_paging::ProcessPageTableRef}; |
| 4 | + |
| 5 | +pub const INPUT_VADDR: u64 = 0xFF0000000000u64; |
| 6 | +pub const OUTPUT_VADDR: u64 = 0xFF8000000000u64; |
| 7 | + |
| 8 | +#[derive(Debug, Clone, Copy, Default)] |
| 9 | +pub struct MemoryChannel { |
| 10 | + pub input: AllocationRange, |
| 11 | + pub output: AllocationRange, |
| 12 | + pub owner: ProcessID, |
| 13 | + pub last_in_channel: bool, |
| 14 | + pub next: ProcessID, |
| 15 | +} |
| 16 | + |
| 17 | +impl MemoryChannel { |
| 18 | + |
| 19 | + pub fn allocate_input(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) { |
| 20 | + self.input = self.allocate_range(page_table_ref, size, INPUT_VADDR); |
| 21 | + } |
| 22 | + |
| 23 | + pub fn allocate_output(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) { |
| 24 | + self.output = self.allocate_range(page_table_ref, size, OUTPUT_VADDR); |
| 25 | + } |
| 26 | + |
| 27 | + pub fn inflate_input(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) { |
| 28 | + let page_count = (size + PAGE_SIZE - (size % PAGE_SIZE)) / PAGE_SIZE; |
| 29 | + self.input.inflate(page_table_ref, page_count as u64, INPUT_VADDR); |
| 30 | + } |
| 31 | + |
| 32 | + pub fn inflate_output(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize) { |
| 33 | + let page_count = (size + PAGE_SIZE - (size % PAGE_SIZE)) / PAGE_SIZE; |
| 34 | + self.output.inflate(page_table_ref, page_count as u64, OUTPUT_VADDR); |
| 35 | + } |
| 36 | + |
| 37 | + pub fn copy_into(&mut self, source_addr: u64, page_table: u64, size: usize) { |
| 38 | + let copy_size = size + PAGE_SIZE - (size % PAGE_SIZE); |
| 39 | + let copy_page_count = copy_size / PAGE_SIZE; |
| 40 | + let target = VirtAddr::from(ALLOCATION_RANGE_VIRT_START); |
| 41 | + |
| 42 | + let mut page_table_ref = ProcessPageTableRef::default(); |
| 43 | + page_table_ref.set_external_table(page_table); |
| 44 | + |
| 45 | + self.input.mount(); |
| 46 | + |
| 47 | + page_table_ref.copy_address_range(VirtAddr::from(source_addr), copy_size as u64, target); |
| 48 | + |
| 49 | + } |
| 50 | + |
| 51 | + pub fn copy_out(&mut self, target_addr: u64, page_table: u64, size: usize) { |
| 52 | + let copy_size = size + PAGE_SIZE - (size % PAGE_SIZE); |
| 53 | + let copy_page_count = copy_size / PAGE_SIZE; |
| 54 | + let target = VirtAddr::from(ALLOCATION_RANGE_VIRT_START); |
| 55 | + let mut page_table_ref = ProcessPageTableRef::default(); |
| 56 | + page_table_ref.set_external_table(page_table); |
| 57 | + |
| 58 | + self.output.mount(); |
| 59 | + |
| 60 | + page_table_ref.copy_address_range(VirtAddr::from(target), copy_size as u64, VirtAddr::from(target_addr)); |
| 61 | + } |
| 62 | + |
| 63 | + fn allocate_range(&mut self, page_table_ref: &mut ProcessPageTableRef, size: usize, start: u64) -> AllocationRange{ |
| 64 | + let mut r = AllocationRange::default(); |
| 65 | + let page_count = (size + PAGE_SIZE - (size % PAGE_SIZE)) / PAGE_SIZE; |
| 66 | + r.allocate_with_start_addr(page_table_ref, page_count as u64, start); |
| 67 | + return r; |
| 68 | + } |
| 69 | + |
| 70 | +} |
0 commit comments