From 2b37884a607887f8bca1698175eddcc3e1094863 Mon Sep 17 00:00:00 2001 From: Marco Thomas Date: Tue, 10 Jun 2025 09:44:34 +0900 Subject: [PATCH] fix: align interrupt data with minix src --- src/interpreter/interpreter.rs | 77 +++++++++++----------------------- src/interpreter/interrupt.rs | 67 +++++++++++++++++++++++++++++ src/interpreter/mod.rs | 1 + 3 files changed, 92 insertions(+), 53 deletions(-) create mode 100644 src/interpreter/interrupt.rs diff --git a/src/interpreter/interpreter.rs b/src/interpreter/interpreter.rs index 51d0a34..6eaf024 100644 --- a/src/interpreter/interpreter.rs +++ b/src/interpreter/interpreter.rs @@ -3,10 +3,14 @@ use std::{fmt::Debug, process::exit}; use crate::{ instructions::{Instruction, Mnemonic}, - operands::{Byte, ImmediateOperand, ModRmTarget, Word}, + interpreter::interrupt::Mess1, + operands::{Byte, ImmediateOperand, ModRmTarget}, }; -use super::computer::{Computer, Operand}; +use super::{ + computer::{Computer, Operand}, + interrupt::InterruptMessage, +}; #[derive(Debug, Clone)] pub enum InterpreterError { @@ -79,7 +83,7 @@ impl Interpreter { * MOV */ Mnemonic::MOV_BXIv(word) => self.computer.regs.bx.write(word), - Mnemonic::INT(id) => self.handle_int(id)?, + Mnemonic::INT(id) => self.interpret_interrupt(id)?, _ => log::info!("no action done"), } } @@ -87,7 +91,7 @@ impl Interpreter { Ok(()) } - fn handle_int(&self, id: u8) -> Result<(), InterpreterError> { + fn interpret_interrupt(&self, id: u8) -> Result<(), InterpreterError> { let bx = self.computer.regs.bx.read() as usize; // a message is always 8 words aligned let len = 2 * 8; @@ -96,17 +100,28 @@ impl Interpreter { .get(bx..bx + len) .ok_or(InterpreterError::EndOfData)? .to_owned(); - let interrupt_data = InterruptData::new(data); + + let msg = InterruptMessage::new(&data); // simulate interrupt handler code of MINIX match id { // sofware interrupts 0x20 => { - match interrupt_data.interrupt_id { + log::debug!("Software interrupt with raw data {:?}", data); + match msg.m_type { + // EXIT() + 0x01 => { + let data = Mess1::new(&data); + let status = data.i1; + log::info!("executing exit({})", status); + exit(status.into()) + } + // WRITE() 0x04 => { - let fd = interrupt_data.m_type; - let location = interrupt_data.data_position; - let len = interrupt_data.count; + let data = Mess1::new(&data); + let fd = data.i1; + let len = data.i2; + let location = data.p1; log::info!("executing write({}, {}, {})", fd, location, len); for byte in &self.data[location as usize..] { if *byte == 0x00 { @@ -116,11 +131,6 @@ impl Interpreter { } } } - 0x01 => { - let exit_code = interrupt_data.data_position; - log::info!("executing exit({})", exit_code); - exit(exit_code.into()) - } _ => todo!(), }; } @@ -130,42 +140,3 @@ impl Interpreter { Ok(()) } } - -#[derive(Debug, Clone)] -// https://cse.unl.edu/~goddard/Courses/CSCE351/Lectures/Lecture8.pdf -pub struct InterruptData { - pub m_type: Word, // Operation requested - pub interrupt_id: Word, // Minor device to use - pub proc_nr: Word, // Process requesting the I/O - pub count: Word, // Word count or ioctl code - pub position: Word, // Position on device - pub data_position: Word, // Minor device to use -} - -impl InterruptData { - pub fn new(data: Vec) -> Self { - Self { - m_type: Word::from_le_bytes([data[0], data[1]]), - interrupt_id: Word::from_le_bytes([data[2], data[3]]), - proc_nr: Word::from_le_bytes([data[4], data[5]]), - count: Word::from_le_bytes([data[6], data[7]]), - position: Word::from_le_bytes([data[8], data[9]]), - data_position: Word::from_le_bytes([data[10], data[11]]), - } - } -} - -impl fmt::Display for InterruptData { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "Interrupt({}, {}, {}, {}, {}, {})", - self.m_type, - self.interrupt_id, - self.proc_nr, - self.count, - self.position, - self.data_position - ) - } -} diff --git a/src/interpreter/interrupt.rs b/src/interpreter/interrupt.rs new file mode 100644 index 0000000..719d204 --- /dev/null +++ b/src/interpreter/interrupt.rs @@ -0,0 +1,67 @@ +use core::fmt; + +use crate::operands::Word; + +// TODO: +// typedef struct {int m2i1, m2i2, m2i3; long m2l1, m2l2; char *m2p1;} mess_2; +// typedef struct {int m3i1, m3i2; char *m3p1; char m3ca1[M3_STRING];} mess_3; +// typedef struct {long m4l1, m4l2, m4l3, m4l4, m4l5;} mess_4; +// typedef struct {char m5c1, m5c2; int m5i1, m5i2; long m5l1, m5l2, m5l3;}mess_5; +// typedef struct {int m6i1, m6i2, m6i3; long m6l1; sighandler_t m6f1;} mess_6; + +#[derive(Debug, Clone)] +// typedef struct {int m1i1, m1i2, m1i3; char *m1p1, *m1p2, *m1p3;} mess_1; +pub struct Mess1 { + pub i1: Word, + pub i2: Word, + pub i3: Word, + pub p1: Word, + pub p2: Word, + pub p3: Word, +} + +impl Mess1 { + pub fn new(data: &Vec) -> Self { + Self { + i1: Word::from_le_bytes([data[4], data[5]]), + i2: Word::from_le_bytes([data[6], data[7]]), + i3: Word::from_le_bytes([data[8], data[9]]), + p1: Word::from_le_bytes([data[10], data[11]]), + p2: Word::from_le_bytes([data[12], data[13]]), + p3: Word::from_le_bytes([data[14], data[15]]), + } + } +} + +impl fmt::Display for Mess1 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Mess1({} {} {} {} {} {})", + self.i1, self.i2, self.i3, self.p1, self.p2, self.p3 + ) + } +} +#[derive(Debug, Clone)] +/// First part of: include/minix/type.h:struct message +/// The union-type will be handled differently, where I the data of each +/// MessX type will be parsed, when needed for each specific interrupt. +pub struct InterruptMessage { + pub m_source: Word, + pub m_type: Word, +} + +impl InterruptMessage { + pub fn new(data: &Vec) -> Self { + Self { + m_source: Word::from_le_bytes([data[0], data[1]]), + m_type: Word::from_le_bytes([data[2], data[3]]), + } + } +} + +impl fmt::Display for InterruptMessage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Interrupt({}, {})", self.m_source, self.m_type) + } +} diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 9dd6495..e43b375 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -1,5 +1,6 @@ mod computer; mod flags; pub mod interpreter; +mod interrupt; mod memory; mod register;