Add acpi PM timer

This commit is contained in:
copy 2017-03-31 17:16:43 -05:00
parent 9dcf9c0df5
commit ff89ef09fb
2 changed files with 83 additions and 4 deletions

View file

@ -1,5 +1,7 @@
"use strict";
// http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf
/** @const */
var PMTIMER_FREQ = 3579545;
@ -9,6 +11,9 @@ var PMTIMER_FREQ = 3579545;
*/
function ACPI(cpu)
{
/** @type {CPU} */
this.cpu = cpu;
var io = cpu.io;
var acpi = {
@ -26,18 +31,90 @@ function ACPI(cpu)
// 00:07.0 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 08)
cpu.devices.pci.register_device(acpi);
this.status = 1;
this.pm1_status = 0;
this.pm1_enable = 0;
this.last_timer = this.get_timer(v86.microtick());
io.register_read(0xB000, this, undefined, function()
{
dbg_log("ACPI pm1_status read", LOG_ACPI);
return this.pm1_status;
});
io.register_write(0xB000, this, undefined, function(value)
{
dbg_log("ACPI pm1_status write: " + h(value, 4), LOG_ACPI);
this.pm1_status &= ~value;
});
io.register_read(0xB002, this, undefined, function()
{
dbg_log("ACPI pm1_enable read", LOG_ACPI);
return this.pm1_enable;
});
io.register_write(0xB002, this, undefined, function(value)
{
dbg_log("ACPI pm1_enable write: " + h(value), LOG_ACPI);
this.pm1_enable = value;
});
// ACPI status
io.register_read(0xB004, this, undefined, function()
{
dbg_log("ACPI status read", LOG_ACPI);
return 1;
return this.status;
});
io.register_write(0xB004, this, undefined, function(value)
{
dbg_log("ACPI status write: " + h(value), LOG_ACPI);
this.status = value;
});
// ACPI, pmtimer
io.register_read(0xB008, this, undefined, undefined, function()
{
var value = v86.microtick() * (PMTIMER_FREQ / 1000) | 0;
var value = this.get_timer(v86.microtick()) & 0xFFFFFF;
//dbg_log("pmtimer read: " + h(value >>> 0), LOG_ACPI);
return value;
});
}
ACPI.prototype.timer = function(now)
{
var timer = this.get_timer(now);
var highest_bit_changed = ((timer ^ this.last_timer) & (1 << 23)) !== 0;
if((this.pm1_enable & 1) && highest_bit_changed)
{
dbg_log("ACPI raise irq", LOG_ACPI);
this.pm1_status |= 1;
this.cpu.device_raise_irq(9);
}
else
{
this.cpu.device_lower_irq(9);
}
this.last_timer = timer;
};
ACPI.prototype.get_timer = function(now)
{
return now * (PMTIMER_FREQ / 1000) | 0;
};
ACPI.prototype.get_state = function()
{
var state = [];
state[0] = this.status;
state[1] = this.pm1_status;
state[2] = this.pm1_enable;
return state;
};
CPU.prototype.set_state = function(state)
{
this.status = state[0];
this.pm1_status = state[1];
this.pm1_enable = state[2];
};

View file

@ -308,7 +308,7 @@ CPU.prototype.get_state = function()
state[47] = this.devices.rtc;
state[48] = this.devices.pci;
state[49] = this.devices.dma;
//state[50] = this.devices.acpi;
state[50] = this.devices.acpi;
state[51] = this.devices.hpet;
state[52] = this.devices.vga;
state[53] = this.devices.ps2;
@ -377,7 +377,7 @@ CPU.prototype.set_state = function(state)
this.devices.rtc = state[47];
this.devices.pci = state[48];
this.devices.dma = state[49];
//this.devices.acpi = state[50];
this.devices.acpi = state[50];
this.devices.hpet = state[51];
this.devices.vga = state[52];
this.devices.ps2 = state[53];
@ -855,6 +855,7 @@ CPU.prototype.do_run = function()
if(ENABLE_ACPI)
{
this.devices.acpi.timer(now);
this.devices.apic.timer(now);
}
@ -1026,6 +1027,7 @@ CPU.prototype.hlt_loop = function()
if(ENABLE_ACPI)
{
this.devices.acpi.timer(now);
this.devices.apic.timer(now);
}