Change handling of interrupts to involve APIC

This commit is contained in:
copy 2015-05-17 01:56:50 +02:00
parent 3cffcd05fc
commit 3a824eda12
11 changed files with 57 additions and 46 deletions

View file

@ -1858,14 +1858,34 @@ CPU.prototype.get_seg = function(segment /*, offset*/)
CPU.prototype.handle_irqs = function() 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(); 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);
} }
}; };

View file

@ -11,7 +11,7 @@ function FloppyController(cpu, fda_image, fdb_image)
this.io = cpu.io; this.io = cpu.io;
/** @const */ /** @const */
this.pic = cpu.devices.pic; this.cpu = cpu;
/** @const */ /** @const */
this.dma = cpu.devices.dma; this.dma = cpu.devices.dma;
@ -49,7 +49,7 @@ function FloppyController(cpu, fda_image, fdb_image)
/** @const */ /** @const */
this._state_skip = [ this._state_skip = [
this.io, this.io,
this.pic, this.cpu,
this.dma, this.dma,
]; ];
@ -260,7 +260,7 @@ FloppyController.prototype.port3F2_write = function(value)
if((value & 4) === 4 && (this.dor & 4) === 0) if((value & 4) === 4 && (this.dor & 4) === 0)
{ {
// reset // reset
this.pic.push_irq(6); this.cpu.device_raise_irq(6);
} }
dbg_log("start motors: " + h(value >> 4), LOG_DISK); dbg_log("start motors: " + h(value >> 4), LOG_DISK);
@ -290,7 +290,7 @@ FloppyController.prototype.seek = function(args)
if(this.dor & 8) 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) 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) 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) if(this.dor & 8)
{ {
this.pic.push_irq(6); this.cpu.device_raise_irq(6);
} }
} }

View file

@ -20,7 +20,6 @@ function HPET(cpu)
{ {
var me = this, var me = this,
io = cpu.io, io = cpu.io,
dev = cpu.devices,
hpet_enabled = false, hpet_enabled = false,
hpet_start = Date.now(), hpet_start = Date.now(),
@ -93,16 +92,16 @@ function HPET(cpu)
{ {
if(me.legacy_mode && i === 0) if(me.legacy_mode && i === 0)
{ {
dev.pic.push_irq(0); cpu.device_raise_irq(0);
} }
else if(me.legacy_mode && i === 1) else if(me.legacy_mode && i === 1)
{ {
dev.pic.push_irq(8); cpu.device_raise_irq(0);
} }
else else
{ {
// TODO // TODO
dev.pic.push_irq(0); cpu.device_raise_irq(0);
} }
} }
} }

View file

@ -54,7 +54,7 @@ function IDEDevice(cpu, buffer, is_cd, nr, bus)
this.master_port = 0xC000; this.master_port = 0xC000;
/** @const */ /** @const */
this.pic = cpu.devices.pic; this.cpu = cpu;
/** @const */ /** @const */
this.memory = cpu.memory; this.memory = cpu.memory;
@ -303,7 +303,7 @@ function IDEDevice(cpu, buffer, is_cd, nr, bus)
/** @const */ /** @const */
this._state_skip = [ this._state_skip = [
this.memory, this.memory,
this.pic, this.cpu,
this.stats, this.stats,
this.buffer, this.buffer,
this.bus, this.bus,
@ -337,8 +337,7 @@ IDEDevice.prototype.push_irq = function()
{ {
dbg_log("push irq", LOG_DISK); dbg_log("push irq", LOG_DISK);
this.dma_status |= 4; this.cpu.device_raise_irq(this.irq);
this.pic.push_irq(this.irq);
} }
}; };

View file

@ -60,7 +60,7 @@
function Ne2k(cpu, bus) function Ne2k(cpu, bus)
{ {
/** @const */ /** @const */
this.pic = cpu.devices.pic; this.cpu = cpu;
/** @const */ /** @const */
this.bus = bus; this.bus = bus;
@ -476,7 +476,7 @@ function Ne2k(cpu, bus)
this._state_skip = [ this._state_skip = [
this.bus, this.bus,
this.pic, this.cpu,
]; ];
} }
@ -487,7 +487,7 @@ Ne2k.prototype.do_interrupt = function(ir_mask)
if(this.imr & ir_mask) if(this.imr & ir_mask)
{ {
this.pic.push_irq(this.irq); this.cpu.device_raise_irq(this.irq);
} }
}; };

View file

@ -133,7 +133,7 @@ function PIC(cpu, master)
if(this.irr) if(this.irr)
{ {
// tell the master we have one more // tell the master we have one more
master.push_irq(2); master.raise_irq(2);
} }
if(!this.auto_eoi) if(!this.auto_eoi)
@ -272,13 +272,13 @@ function PIC(cpu, master)
if(this.is_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); dbg_assert(irq_number >= 0 && irq_number < 16);
if(irq_number >= 8) if(irq_number >= 8)
{ {
this.slave.push_irq(irq_number - 8); this.slave.raise_irq(irq_number - 8);
irq_number = 2; irq_number = 2;
} }
@ -289,7 +289,7 @@ function PIC(cpu, master)
} }
else else
{ {
this.push_irq = function(irq_number) this.raise_irq = function(irq_number)
{ {
dbg_assert(irq_number >= 0 && irq_number < 8); dbg_assert(irq_number >= 0 && irq_number < 8);

View file

@ -15,7 +15,7 @@ var OSCILLATOR_FREQ = 1193.1816666; // 1.193182 MHz
function PIT(cpu) function PIT(cpu)
{ {
/** @const */ /** @const */
this.pic = cpu.devices.pic; this.cpu = cpu;
this.next_tick = Date.now(); this.next_tick = Date.now();
@ -59,7 +59,7 @@ function PIT(cpu)
/** @const */ /** @const */
this._state_skip = [ this._state_skip = [
this.pic, this.cpu,
]; ];
} }
@ -89,7 +89,7 @@ PIT.prototype.timer = function(time, no_irq)
{ {
time_to_next_interrupt = 0; time_to_next_interrupt = 0;
this.pic.push_irq(0); this.cpu.device_raise_irq(0);
mode = this.counter_mode[0]; mode = this.counter_mode[0];
if(mode === 0) if(mode === 0)

View file

@ -7,8 +7,6 @@
*/ */
function PS2(cpu, bus) function PS2(cpu, bus)
{ {
/** @const */
this.pic = cpu.devices.pic;
/** @const */ /** @const */
this.cpu = cpu; this.cpu = cpu;
@ -113,7 +111,6 @@ function PS2(cpu, bus)
/** @const */ /** @const */
this._state_skip = [ this._state_skip = [
this.bus, this.bus,
this.pic,
this.cpu, this.cpu,
]; ];
} }
@ -127,7 +124,7 @@ PS2.prototype.mouse_irq = function()
{ {
if(this.command_register & 2) 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) if(this.command_register & 1)
{ {
this.pic.push_irq(1); this.cpu.device_raise_irq(1);
} }
} }

View file

@ -47,9 +47,6 @@ function RTC(cpu)
/** @const */ /** @const */
this.cpu = cpu; this.cpu = cpu;
/** @const */
this.pic = cpu.devices.pic;
this.cmos_index = 0; this.cmos_index = 0;
this.cmos_data = new Uint8Array(256); this.cmos_data = new Uint8Array(256);
@ -84,7 +81,6 @@ function RTC(cpu)
this._state_skip = [ this._state_skip = [
this.cpu, 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) if(this.periodic_interrupt && this.cmos_c_was_read && this.next_interrupt < time)
{ {
this.cmos_c_was_read = false; this.cmos_c_was_read = false;
this.pic.push_irq(8); this.cpu.device_raise_irq(8);
this.cmos_c |= 1 << 6; this.cmos_c |= 1 << 6 | 1 << 7;
this.next_interrupt += this.periodic_interrupt_time * this.next_interrupt += this.periodic_interrupt_time *
Math.ceil((time - this.next_interrupt) / this.periodic_interrupt_time); Math.ceil((time - this.next_interrupt) / this.periodic_interrupt_time);

View file

@ -33,7 +33,7 @@ function UART(cpu, port, bus)
this.bus = bus; this.bus = bus;
/** @const */ /** @const */
this.pic = cpu.devices.pic; this.cpu = cpu;
this.ints = 0; this.ints = 0;
@ -251,14 +251,14 @@ function UART(cpu, port, bus)
this._state_skip = [ this._state_skip = [
this.bus, this.bus,
this.pic, this.cpu,
]; ];
} }
UART.prototype.push_irq = function() UART.prototype.push_irq = function()
{ {
dbg_log("Push irq", LOG_SERIAL); dbg_log("Push irq", LOG_SERIAL);
this.pic.push_irq(this.irq); this.cpu.device_raise_irq(this.irq);
}; };
UART.prototype.ClearInterrupt = function(line) UART.prototype.ClearInterrupt = function(line)

View file

@ -132,7 +132,7 @@ function VirtIO(cpu, bus, filesystem)
this.irq = 0xC; this.irq = 0xC;
/** @const */ /** @const */
this.pic = cpu.devices.pic; this.cpu = cpu;
/** @const */ /** @const */
this.bus = bus; this.bus = bus;
@ -172,7 +172,7 @@ function VirtIO(cpu, bus, filesystem)
this._state_skip = [ this._state_skip = [
this.memory, this.memory,
this.pic, this.cpu,
this.bus, this.bus,
]; ];
this._state_restore = function() this._state_restore = function()
@ -364,7 +364,7 @@ VirtIO.prototype.device_reply = function(infos)
this.memory.write32(used_desc_offset + 4, result_length); this.memory.write32(used_desc_offset + 4, result_length);
this.isr |= 1; this.isr |= 1;
this.pic.push_irq(this.irq); this.cpu.device_raise_irq(this.irq);
}; };