Browse Source

check acknowledge_irq to return irq, rather than calling into cpu

Fabian 4 months ago
parent
commit
be933590ac
5 changed files with 32 additions and 28 deletions
  1. 5 4
      src/apic.js
  2. 1 1
      src/browser/starter.js
  3. 0 1
      src/cpu.js
  4. 10 6
      src/rust/cpu/cpu.rs
  5. 16 16
      src/rust/cpu/pic.rs

+ 5 - 4
src/apic.js

@@ -513,7 +513,7 @@ APIC.prototype.acknowledge_irq = function()
     if(highest_irr === -1)
     {
         //dbg_log("Spurious", LOG_APIC);
-        return;
+        return -1;
     }
 
     var highest_isr = this.highest_isr();
@@ -521,22 +521,23 @@ APIC.prototype.acknowledge_irq = function()
     if(highest_isr >= highest_irr)
     {
         APIC_LOG_VERBOSE && dbg_log("Higher isr, isr=" + h(highest_isr) + " irr=" + h(highest_irr), LOG_APIC);
-        return;
+        return -1;
     }
 
     if((highest_irr & 0xF0) <= (this.tpr & 0xF0))
     {
         APIC_LOG_VERBOSE && dbg_log("Higher tpr, tpr=" + h(this.tpr & 0xF0) + " irr=" + h(highest_irr), LOG_APIC);
-        return;
+        return -1;
     }
 
     this.register_clear_bit(this.irr, highest_irr);
     this.register_set_bit(this.isr, highest_irr);
 
     APIC_LOG_VERBOSE && dbg_log("Calling vector " + h(highest_irr), LOG_APIC);
-    this.cpu.pic_call_irq(highest_irr);
 
     this.check_vector();
+
+    return highest_irr;
 };
 
 APIC.prototype.get_state = function()

+ 1 - 1
src/browser/starter.js

@@ -114,7 +114,7 @@ function V86(options)
         "abort": function() { dbg_assert(false); },
         "microtick": v86.microtick,
         "get_rand_int": function() { return v86util.get_rand_int(); },
-        "apic_acknowledge_irq": function() { cpu.devices.apic.acknowledge_irq(); },
+        "apic_acknowledge_irq": function() { return cpu.devices.apic.acknowledge_irq(); },
 
         "io_port_read8": function(addr) { return cpu.io.port_read8(addr); },
         "io_port_read16": function(addr) { return cpu.io.port_read16(addr); },

+ 0 - 1
src/cpu.js

@@ -225,7 +225,6 @@ CPU.prototype.wasm_patch = function()
     this.get_eflags = get_import("get_eflags");
 
     this.handle_irqs = get_import("handle_irqs");
-    this.pic_call_irq = get_import("pic_call_irq");
 
     this.main_loop = get_import("main_loop");
 

+ 10 - 6
src/rust/cpu/cpu.rs

@@ -6,7 +6,7 @@ extern "C" {
     pub fn microtick() -> f64;
     pub fn run_hardware_timers(t: f64) -> f64;
     pub fn cpu_event_halt();
-    pub fn apic_acknowledge_irq();
+    pub fn apic_acknowledge_irq() -> i32;
 
     pub fn io_port_read8(port: i32) -> i32;
     pub fn io_port_read16(port: i32) -> i32;
@@ -4161,15 +4161,19 @@ pub unsafe fn store_current_tsc() { *current_tsc = read_tsc(); }
 #[no_mangle]
 pub unsafe fn handle_irqs() {
     if *flags & FLAG_INTERRUPT != 0 {
-        pic::pic_acknowledge_irq();
-        if *acpi_enabled {
-            apic_acknowledge_irq();
+        if let Some(irq) = pic::pic_acknowledge_irq() {
+            pic_call_irq(irq)
+        }
+        else if *acpi_enabled {
+            let irq = apic_acknowledge_irq();
+            if irq >= 0 {
+                pic_call_irq(irq as u8)
+            }
         }
     }
 }
 
-#[no_mangle]
-pub unsafe fn pic_call_irq(interrupt_nr: u8) {
+unsafe fn pic_call_irq(interrupt_nr: u8) {
     *previous_ip = *instruction_pointer; // XXX: What if called after instruction (port IO)
     *in_hlt = false;
     call_interrupt_vector(interrupt_nr as i32, false, None);

+ 16 - 16
src/rust/cpu/pic.rs

@@ -87,24 +87,24 @@ static mut slave: Pic = Pic {
 
 
 // Checking for callable interrupts:
-// (cpu changes interrupt flag) -> cpu.handle_irqs -> pic_acknowledge_irq -> cpu.pic_call_irq
+// (cpu changes interrupt flag) -> cpu.handle_irqs -> pic_acknowledge_irq
 // (pic changes isr/irr) -> pic.check_irqs -> cpu.handle_irqs -> ...
 
 // triggering irqs:
 // (io device has irq) -> cpu.device_raise_irq -> pic.set_irq -> pic.check_irqs -> cpu.handle_irqs -> (see above)
 
 // called by the cpu
-pub unsafe fn pic_acknowledge_irq() {
+pub unsafe fn pic_acknowledge_irq() -> Option<u8> {
     let irq = match get_irq(&mut master) {
         Some(i) => i,
-        None => return
+        None => return None
     };
 
     if master.irr == 0 {
         dbg_assert!(false);
         //PIC_LOG_VERBOSE && dbg_log!("master> spurious requested=" + irq);
-        //pic.cpu.pic_call_irq(pic.irq_map | 7);
-        return;
+        //Some(pic.irq_map | 7)
+        return None
     }
 
     let mask = 1 << irq;
@@ -121,28 +121,28 @@ pub unsafe fn pic_acknowledge_irq() {
     if PIC_LOG_VERBOSE {
         dbg_log!("[PIC] master> acknowledge {}", irq);
     }
+
+    check_irqs(&mut master);
+
     if irq == 2 {
-        acknowledge_irq_slave();
+        acknowledge_irq_slave()
     }
     else {
-        cpu::pic_call_irq(master.irq_map | irq);
+        Some(master.irq_map | irq)
     }
-
-    check_irqs(&mut master);
 }
 
-unsafe fn acknowledge_irq_slave() {
+unsafe fn acknowledge_irq_slave() -> Option<u8> {
     let irq = match get_irq(&mut slave) {
         Some(i) => i,
-        None => return
+        None => return None
     };
 
     if slave.irr == 0 {
         //PIC_LOG_VERBOSE && dbg_log!("slave> spurious requested=" + irq);
-        //pic.cpu.pic_call_irq(pic.irq_map | 7);
+        //Some(pic.irq_map | 7)
         dbg_assert!(false);
-        cpu::pic_call_irq(slave.irq_map | 7);
-        return;
+        return None
     }
 
     let mask = 1 << irq;
@@ -159,9 +159,9 @@ unsafe fn acknowledge_irq_slave() {
     if PIC_LOG_VERBOSE {
         dbg_log!("[PIC] slave> acknowledge {}", irq);
     }
-    cpu::pic_call_irq(slave.irq_map | irq);
-
     check_irqs(&mut slave);
+
+    Some(slave.irq_map | irq)
 }
 
 unsafe fn get_irq(pic: &mut Pic) -> Option<u8> {