From 3a824eda1270386b8e349938fbc85db8736cc70f Mon Sep 17 00:00:00 2001 From: copy Date: Sun, 17 May 2015 01:56:50 +0200 Subject: [PATCH] Change handling of interrupts to involve APIC --- src/cpu.macro.js | 28 ++++++++++++++++++++++++---- src/floppy.js | 14 +++++++------- src/hpet.js | 7 +++---- src/ide.js | 7 +++---- src/ne2k.js | 6 +++--- src/pic.js | 8 ++++---- src/pit.js | 6 +++--- src/ps2.js | 7 ++----- src/rtc.js | 8 ++------ src/uart.js | 6 +++--- src/virtio.js | 6 +++--- 11 files changed, 57 insertions(+), 46 deletions(-) diff --git a/src/cpu.macro.js b/src/cpu.macro.js index 2258c231..70d669c0 100644 --- a/src/cpu.macro.js +++ b/src/cpu.macro.js @@ -1858,14 +1858,34 @@ CPU.prototype.get_seg = function(segment /*, offset*/) CPU.prototype.handle_irqs = function() { - if(this.devices.pic) - { - dbg_assert(!this.page_fault); + dbg_assert(!this.page_fault); - if((this.flags & flag_interrupt) && !this.page_fault) + if((this.flags & flag_interrupt) && !this.page_fault) + { + if(this.devices.pic) { this.devices.pic.check_irqs(); } + + if(this.devices.apic) + { + this.devices.apic.check_irqs(); + } + } +}; + +CPU.prototype.device_raise_irq = function(i) +{ + dbg_assert(arguments.length === 1); + + if(this.devices.pic) + { + this.devices.pic.raise_irq(i); + } + + if(this.devices.apic) + { + this.devices.apic.raise_irq(i); } }; diff --git a/src/floppy.js b/src/floppy.js index e1fb8fa6..d9050ed8 100644 --- a/src/floppy.js +++ b/src/floppy.js @@ -11,7 +11,7 @@ function FloppyController(cpu, fda_image, fdb_image) this.io = cpu.io; /** @const */ - this.pic = cpu.devices.pic; + this.cpu = cpu; /** @const */ this.dma = cpu.devices.dma; @@ -49,7 +49,7 @@ function FloppyController(cpu, fda_image, fdb_image) /** @const */ this._state_skip = [ this.io, - this.pic, + this.cpu, this.dma, ]; @@ -260,7 +260,7 @@ FloppyController.prototype.port3F2_write = function(value) if((value & 4) === 4 && (this.dor & 4) === 0) { // reset - this.pic.push_irq(6); + this.cpu.device_raise_irq(6); } dbg_log("start motors: " + h(value >> 4), LOG_DISK); @@ -290,7 +290,7 @@ FloppyController.prototype.seek = function(args) if(this.dor & 8) { - this.pic.push_irq(6); + this.cpu.device_raise_irq(6); } } @@ -300,7 +300,7 @@ FloppyController.prototype.calibrate = function(args) if(this.dor & 8) { - this.pic.push_irq(6); + this.cpu.device_raise_irq(6); } } @@ -384,7 +384,7 @@ FloppyController.prototype.done = function(cylinder, args, head, sector, error) if(this.dor & 8) { - this.pic.push_irq(6); + this.cpu.device_raise_irq(6); } } @@ -410,7 +410,7 @@ FloppyController.prototype.read_sector_id = function(args) if(this.dor & 8) { - this.pic.push_irq(6); + this.cpu.device_raise_irq(6); } } diff --git a/src/hpet.js b/src/hpet.js index 7e74aa65..1b0dd0c3 100644 --- a/src/hpet.js +++ b/src/hpet.js @@ -20,7 +20,6 @@ function HPET(cpu) { var me = this, io = cpu.io, - dev = cpu.devices, hpet_enabled = false, hpet_start = Date.now(), @@ -93,16 +92,16 @@ function HPET(cpu) { if(me.legacy_mode && i === 0) { - dev.pic.push_irq(0); + cpu.device_raise_irq(0); } else if(me.legacy_mode && i === 1) { - dev.pic.push_irq(8); + cpu.device_raise_irq(0); } else { // TODO - dev.pic.push_irq(0); + cpu.device_raise_irq(0); } } } diff --git a/src/ide.js b/src/ide.js index 8df9db35..252debe7 100644 --- a/src/ide.js +++ b/src/ide.js @@ -54,7 +54,7 @@ function IDEDevice(cpu, buffer, is_cd, nr, bus) this.master_port = 0xC000; /** @const */ - this.pic = cpu.devices.pic; + this.cpu = cpu; /** @const */ this.memory = cpu.memory; @@ -303,7 +303,7 @@ function IDEDevice(cpu, buffer, is_cd, nr, bus) /** @const */ this._state_skip = [ this.memory, - this.pic, + this.cpu, this.stats, this.buffer, this.bus, @@ -337,8 +337,7 @@ IDEDevice.prototype.push_irq = function() { dbg_log("push irq", LOG_DISK); - this.dma_status |= 4; - this.pic.push_irq(this.irq); + this.cpu.device_raise_irq(this.irq); } }; diff --git a/src/ne2k.js b/src/ne2k.js index b4490549..a4f882a0 100644 --- a/src/ne2k.js +++ b/src/ne2k.js @@ -60,7 +60,7 @@ function Ne2k(cpu, bus) { /** @const */ - this.pic = cpu.devices.pic; + this.cpu = cpu; /** @const */ this.bus = bus; @@ -476,7 +476,7 @@ function Ne2k(cpu, bus) this._state_skip = [ this.bus, - this.pic, + this.cpu, ]; } @@ -487,7 +487,7 @@ Ne2k.prototype.do_interrupt = function(ir_mask) if(this.imr & ir_mask) { - this.pic.push_irq(this.irq); + this.cpu.device_raise_irq(this.irq); } }; diff --git a/src/pic.js b/src/pic.js index 624b7226..18a3fdfc 100644 --- a/src/pic.js +++ b/src/pic.js @@ -133,7 +133,7 @@ function PIC(cpu, master) if(this.irr) { // tell the master we have one more - master.push_irq(2); + master.raise_irq(2); } if(!this.auto_eoi) @@ -272,13 +272,13 @@ function PIC(cpu, master) if(this.is_master) { - this.push_irq = function(irq_number) + this.raise_irq = function(irq_number) { dbg_assert(irq_number >= 0 && irq_number < 16); if(irq_number >= 8) { - this.slave.push_irq(irq_number - 8); + this.slave.raise_irq(irq_number - 8); irq_number = 2; } @@ -289,7 +289,7 @@ function PIC(cpu, master) } else { - this.push_irq = function(irq_number) + this.raise_irq = function(irq_number) { dbg_assert(irq_number >= 0 && irq_number < 8); diff --git a/src/pit.js b/src/pit.js index d7c408a1..3aa39b1b 100644 --- a/src/pit.js +++ b/src/pit.js @@ -15,7 +15,7 @@ var OSCILLATOR_FREQ = 1193.1816666; // 1.193182 MHz function PIT(cpu) { /** @const */ - this.pic = cpu.devices.pic; + this.cpu = cpu; this.next_tick = Date.now(); @@ -59,7 +59,7 @@ function PIT(cpu) /** @const */ this._state_skip = [ - this.pic, + this.cpu, ]; } @@ -89,7 +89,7 @@ PIT.prototype.timer = function(time, no_irq) { time_to_next_interrupt = 0; - this.pic.push_irq(0); + this.cpu.device_raise_irq(0); mode = this.counter_mode[0]; if(mode === 0) diff --git a/src/ps2.js b/src/ps2.js index 69e389f9..7278cdfc 100644 --- a/src/ps2.js +++ b/src/ps2.js @@ -7,8 +7,6 @@ */ function PS2(cpu, bus) { - /** @const */ - this.pic = cpu.devices.pic; /** @const */ this.cpu = cpu; @@ -113,7 +111,6 @@ function PS2(cpu, bus) /** @const */ this._state_skip = [ this.bus, - this.pic, this.cpu, ]; } @@ -127,7 +124,7 @@ PS2.prototype.mouse_irq = function() { if(this.command_register & 2) { - this.pic.push_irq(12); + this.cpu.device_raise_irq(12); } } @@ -135,7 +132,7 @@ PS2.prototype.kbd_irq = function() { if(this.command_register & 1) { - this.pic.push_irq(1); + this.cpu.device_raise_irq(1); } } diff --git a/src/rtc.js b/src/rtc.js index de2ec9ba..ea0ce8df 100644 --- a/src/rtc.js +++ b/src/rtc.js @@ -47,9 +47,6 @@ function RTC(cpu) /** @const */ this.cpu = cpu; - /** @const */ - this.pic = cpu.devices.pic; - this.cmos_index = 0; this.cmos_data = new Uint8Array(256); @@ -84,7 +81,6 @@ function RTC(cpu) this._state_skip = [ this.cpu, - this.pic, ]; } @@ -96,8 +92,8 @@ RTC.prototype.timer = function(time, legacy_mode) if(this.periodic_interrupt && this.cmos_c_was_read && this.next_interrupt < time) { this.cmos_c_was_read = false; - this.pic.push_irq(8); - this.cmos_c |= 1 << 6; + this.cpu.device_raise_irq(8); + this.cmos_c |= 1 << 6 | 1 << 7; this.next_interrupt += this.periodic_interrupt_time * Math.ceil((time - this.next_interrupt) / this.periodic_interrupt_time); diff --git a/src/uart.js b/src/uart.js index d8fff3dc..75ef3f6c 100644 --- a/src/uart.js +++ b/src/uart.js @@ -33,7 +33,7 @@ function UART(cpu, port, bus) this.bus = bus; /** @const */ - this.pic = cpu.devices.pic; + this.cpu = cpu; this.ints = 0; @@ -251,14 +251,14 @@ function UART(cpu, port, bus) this._state_skip = [ this.bus, - this.pic, + this.cpu, ]; } UART.prototype.push_irq = function() { dbg_log("Push irq", LOG_SERIAL); - this.pic.push_irq(this.irq); + this.cpu.device_raise_irq(this.irq); }; UART.prototype.ClearInterrupt = function(line) diff --git a/src/virtio.js b/src/virtio.js index 73dcff49..a70f8721 100644 --- a/src/virtio.js +++ b/src/virtio.js @@ -132,7 +132,7 @@ function VirtIO(cpu, bus, filesystem) this.irq = 0xC; /** @const */ - this.pic = cpu.devices.pic; + this.cpu = cpu; /** @const */ this.bus = bus; @@ -172,7 +172,7 @@ function VirtIO(cpu, bus, filesystem) this._state_skip = [ this.memory, - this.pic, + this.cpu, this.bus, ]; this._state_restore = function() @@ -364,7 +364,7 @@ VirtIO.prototype.device_reply = function(infos) this.memory.write32(used_desc_offset + 4, result_length); this.isr |= 1; - this.pic.push_irq(this.irq); + this.cpu.device_raise_irq(this.irq); };