Prepared devices and timer code for HPET support
- PIT / CMOS: added methods to control IRQ generation (for HPET legacy mode). - Added method for activating timer with nanosecond value. - Removed unused declaration in the keyboard code. - TODO: virtual timer code also needs to handle nanosecond values.
This commit is contained in:
parent
73bcd4f8ca
commit
89654a4beb
@ -278,6 +278,7 @@ void bx_cmos_c::init(void)
|
||||
void bx_cmos_c::reset(unsigned type)
|
||||
{
|
||||
BX_CMOS_THIS s.cmos_mem_address = 0;
|
||||
BX_CMOS_THIS s.irq_enabled = 1;
|
||||
|
||||
// RESET affects the following registers:
|
||||
// CRA: no effects
|
||||
@ -318,6 +319,7 @@ void bx_cmos_c::register_state(void)
|
||||
{
|
||||
bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "cmos", "CMOS State");
|
||||
BXRS_HEX_PARAM_FIELD(list, mem_address, BX_CMOS_THIS s.cmos_mem_address);
|
||||
BXRS_PARAM_BOOL(list, irq_enabled, BX_CMOS_THIS s.irq_enabled);
|
||||
new bx_shadow_data_c(list, "ram", BX_CMOS_THIS s.reg, 128, 1);
|
||||
}
|
||||
|
||||
@ -386,7 +388,9 @@ Bit32u bx_cmos_c::read(Bit32u address, unsigned io_len)
|
||||
// all bits of Register C are cleared after a read occurs.
|
||||
if (BX_CMOS_THIS s.cmos_mem_address == REG_STAT_C) {
|
||||
BX_CMOS_THIS s.reg[REG_STAT_C] = 0x00;
|
||||
DEV_pic_lower_irq(8);
|
||||
if (BX_CMOS_THIS s.irq_enabled) {
|
||||
DEV_pic_lower_irq(8);
|
||||
}
|
||||
}
|
||||
return(ret8);
|
||||
|
||||
@ -659,7 +663,9 @@ void bx_cmos_c::periodic_timer()
|
||||
// update status register C
|
||||
if (BX_CMOS_THIS s.reg[REG_STAT_B] & 0x40) {
|
||||
BX_CMOS_THIS s.reg[REG_STAT_C] |= 0xc0; // Interrupt Request, Periodic Int
|
||||
DEV_pic_raise_irq(8);
|
||||
if (BX_CMOS_THIS s.irq_enabled) {
|
||||
DEV_pic_raise_irq(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -703,7 +709,9 @@ void bx_cmos_c::uip_timer()
|
||||
// update status register C
|
||||
if (BX_CMOS_THIS s.reg[REG_STAT_B] & 0x10) {
|
||||
BX_CMOS_THIS s.reg[REG_STAT_C] |= 0x90; // Interrupt Request, Update Ended
|
||||
DEV_pic_raise_irq(8);
|
||||
if (BX_CMOS_THIS s.irq_enabled) {
|
||||
DEV_pic_raise_irq(8);
|
||||
}
|
||||
}
|
||||
|
||||
// compare CMOS user copy of time/date to alarm time/date here
|
||||
@ -727,7 +735,9 @@ void bx_cmos_c::uip_timer()
|
||||
}
|
||||
if (alarm_match) {
|
||||
BX_CMOS_THIS s.reg[REG_STAT_C] |= 0xa0; // Interrupt Request, Alarm Int
|
||||
DEV_pic_raise_irq(8);
|
||||
if (BX_CMOS_THIS s.irq_enabled) {
|
||||
DEV_pic_raise_irq(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
BX_CMOS_THIS s.reg[REG_STAT_A] &= 0x7f; // clear UIP bit
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002-2012 The Bochs Project
|
||||
// Copyright (C) 2002-2017 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -55,6 +55,9 @@ public:
|
||||
virtual time_t get_timeval() {
|
||||
return s.timeval;
|
||||
}
|
||||
virtual void enable_irq(bx_bool enabled) {
|
||||
s.irq_enabled = enabled;
|
||||
}
|
||||
|
||||
struct {
|
||||
int periodic_timer_index;
|
||||
@ -67,6 +70,7 @@ public:
|
||||
bx_bool rtc_mode_12hour;
|
||||
bx_bool rtc_mode_binary;
|
||||
bx_bool rtc_sync;
|
||||
bx_bool irq_enabled;
|
||||
|
||||
Bit8u reg[128];
|
||||
} s; // state information
|
||||
|
@ -74,6 +74,7 @@ void bx_devices_c::init_stubs()
|
||||
pluginHardDrive = &stubHardDrive;
|
||||
pluginKeyboard = &stubKeyboard;
|
||||
pluginPicDevice = &stubPic;
|
||||
pluginPitDevice = &stubPit;
|
||||
pluginSpeaker = &stubSpeaker;
|
||||
pluginVgaDevice = &stubVga;
|
||||
#if BX_SUPPORT_IODEBUG
|
||||
|
@ -176,6 +176,16 @@ public:
|
||||
virtual void checksum_cmos(void) {
|
||||
STUBFUNC(cmos, checksum);
|
||||
}
|
||||
virtual void enable_irq(bx_bool enabled) {
|
||||
STUBFUNC(cmos, enable_irq);
|
||||
}
|
||||
};
|
||||
|
||||
class BOCHSAPI bx_pit_stub_c : public bx_devmodel_c {
|
||||
public:
|
||||
virtual void enable_irq(bx_bool enabled) {
|
||||
STUBFUNC(pit, enable_irq);
|
||||
}
|
||||
};
|
||||
|
||||
class BOCHSAPI bx_dma_stub_c : public bx_devmodel_c {
|
||||
@ -410,6 +420,7 @@ public:
|
||||
bx_hdimage_ctl_stub_c *pluginHDImageCtl;
|
||||
bx_keyb_stub_c *pluginKeyboard;
|
||||
bx_pic_stub_c *pluginPicDevice;
|
||||
bx_pit_stub_c *pluginPitDevice;
|
||||
bx_speaker_stub_c *pluginSpeaker;
|
||||
bx_vga_stub_c *pluginVgaDevice;
|
||||
#if BX_SUPPORT_IODEBUG
|
||||
@ -439,6 +450,7 @@ public:
|
||||
bx_hdimage_ctl_stub_c stubHDImage;
|
||||
bx_keyb_stub_c stubKeyboard;
|
||||
bx_pic_stub_c stubPic;
|
||||
bx_pit_stub_c stubPit;
|
||||
bx_speaker_stub_c stubSpeaker;
|
||||
bx_vga_stub_c stubVga;
|
||||
#if BX_SUPPORT_IODEBUG
|
||||
|
@ -227,7 +227,6 @@ private:
|
||||
void mouse_motion(int delta_x, int delta_y, int delta_z, unsigned button_state, bx_bool absxy);
|
||||
|
||||
static void timer_handler(void *);
|
||||
void timer(void);
|
||||
int timer_handle;
|
||||
int statusbar_id[3];
|
||||
bx_bool bxkey_state[BX_KEY_NBKEYS];
|
||||
|
@ -37,6 +37,7 @@ int CDECL libpit_LTX_plugin_init(plugin_t *plugin, plugintype_t type)
|
||||
{
|
||||
if (type == PLUGTYPE_CORE) {
|
||||
thePit = new bx_pit_c();
|
||||
bx_devices.pluginPitDevice = thePit;
|
||||
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePit, BX_PLUGIN_PIT);
|
||||
return 0; // Success
|
||||
} else {
|
||||
@ -101,6 +102,7 @@ void bx_pit_c::init(void)
|
||||
(clock_mode == BX_CLOCK_SYNC_BOTH);
|
||||
|
||||
DEV_register_irq(0, "8254 PIT");
|
||||
BX_PIT_THIS s.irq_enabled = 1;
|
||||
DEV_register_ioread_handler(this, read_handler, 0x0040, "8254 PIT", 1);
|
||||
DEV_register_ioread_handler(this, read_handler, 0x0041, "8254 PIT", 1);
|
||||
DEV_register_ioread_handler(this, read_handler, 0x0042, "8254 PIT", 1);
|
||||
@ -172,6 +174,7 @@ void bx_pit_c::register_state(void)
|
||||
new bx_shadow_num_c(list, "last_next_event_time", &BX_PIT_THIS s.last_next_event_time);
|
||||
new bx_shadow_num_c(list, "total_ticks", &BX_PIT_THIS s.total_ticks);
|
||||
new bx_shadow_num_c(list, "total_usec", &BX_PIT_THIS s.total_usec);
|
||||
BXRS_PARAM_BOOL(list, irq_enabled, BX_PIT_THIS s.irq_enabled);
|
||||
bx_list_c *counter = new bx_list_c(list, "counter");
|
||||
BX_PIT_THIS s.timer.register_state(counter);
|
||||
}
|
||||
@ -392,10 +395,12 @@ bx_bool bx_pit_c::periodic(Bit32u usec_delta)
|
||||
|
||||
void bx_pit_c::irq_handler(bx_bool value)
|
||||
{
|
||||
if (value == 1) {
|
||||
DEV_pic_raise_irq(0);
|
||||
} else {
|
||||
DEV_pic_lower_irq(0);
|
||||
if (BX_PIT_THIS s.irq_enabled) {
|
||||
if (value == 1) {
|
||||
DEV_pic_raise_irq(0);
|
||||
} else {
|
||||
DEV_pic_lower_irq(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2014 The Bochs Project
|
||||
// Copyright (C) 2001-2017 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -32,7 +32,7 @@
|
||||
# define BX_PIT_THIS this->
|
||||
#endif
|
||||
|
||||
class bx_pit_c : public bx_devmodel_c {
|
||||
class bx_pit_c : public bx_pit_stub_c {
|
||||
public:
|
||||
bx_pit_c();
|
||||
virtual ~bx_pit_c();
|
||||
@ -40,6 +40,9 @@ public:
|
||||
virtual void reset(unsigned type);
|
||||
virtual void register_state(void);
|
||||
virtual void after_restore_state(void);
|
||||
virtual void enable_irq(bx_bool enabled) {
|
||||
s.irq_enabled = enabled;
|
||||
}
|
||||
#if BX_DEBUGGER
|
||||
virtual void debug_dump(int argc, char **argv);
|
||||
#endif
|
||||
@ -61,6 +64,7 @@ private:
|
||||
Bit64u total_ticks;
|
||||
Bit64u total_usec;
|
||||
int timer_handle[3];
|
||||
bx_bool irq_enabled;
|
||||
} s;
|
||||
|
||||
bx_bool is_realtime;
|
||||
|
@ -526,8 +526,30 @@ void bx_pc_system_c::activate_timer(unsigned i, Bit32u useconds, bx_bool continu
|
||||
// If the timer frequency is rediculously low, make it more sane.
|
||||
// This happens when 'ips' is too low.
|
||||
if (ticks < MinAllowableTimerPeriod) {
|
||||
//BX_INFO(("activate_timer: adjusting ticks of %llu to min of %u",
|
||||
// ticks, MinAllowableTimerPeriod));
|
||||
ticks = MinAllowableTimerPeriod;
|
||||
}
|
||||
|
||||
timer[i].period = ticks;
|
||||
}
|
||||
|
||||
activate_timer_ticks(i, ticks, continuous);
|
||||
}
|
||||
|
||||
void bx_pc_system_c::activate_timer_nsec(unsigned i, Bit64u nseconds, bx_bool continuous)
|
||||
{
|
||||
Bit64u ticks;
|
||||
|
||||
// if nseconds = 0, use default stored in period field
|
||||
// else set new period from useconds
|
||||
if (nseconds==0) {
|
||||
ticks = timer[i].period;
|
||||
} else {
|
||||
// convert nseconds to number of ticks
|
||||
ticks = (Bit64u) (double(nseconds) * m_ips / 1000.0);
|
||||
|
||||
// If the timer frequency is rediculously low, make it more sane.
|
||||
// This happens when 'ips' is too low.
|
||||
if (ticks < MinAllowableTimerPeriod) {
|
||||
ticks = MinAllowableTimerPeriod;
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,7 @@ public:
|
||||
void setTimerParam(unsigned timerID, Bit32u param);
|
||||
void start_timers(void);
|
||||
void activate_timer(unsigned timer_index, Bit32u useconds, bx_bool continuous);
|
||||
void activate_timer_nsec(unsigned timer_index, Bit64u nseconds, bx_bool continuous);
|
||||
void deactivate_timer(unsigned timer_index);
|
||||
unsigned triggeredTimerID(void) {
|
||||
return triggeredTimer;
|
||||
|
@ -161,6 +161,10 @@ extern "C" {
|
||||
#define DEV_cmos_get_reg(a) (bx_devices.pluginCmosDevice->get_reg(a))
|
||||
#define DEV_cmos_set_reg(a,b) (bx_devices.pluginCmosDevice->set_reg(a,b))
|
||||
#define DEV_cmos_checksum() (bx_devices.pluginCmosDevice->checksum_cmos())
|
||||
#define DEV_cmos_enable_irq(a) (bx_devices.pluginCmosDevice->enable_irq(a))
|
||||
|
||||
///////// PIT macro
|
||||
#define DEV_pit_enable_irq(a) (bx_devices.pluginPitDevice->enable_irq(a))
|
||||
|
||||
///////// keyboard macros
|
||||
#define DEV_kbd_gen_scancode(key) (bx_devices.gen_scancode(key))
|
||||
|
Loading…
Reference in New Issue
Block a user