Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
ec844b96
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ec844b96
编写于
5月 03, 2004
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
pit fixes
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@781
c046a42c-6fe2-441c-8c8c-71466251a162
上级
f72e8ff4
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
175 addition
and
88 deletion
+175
-88
Changelog
Changelog
+1
-0
hw/i8254.c
hw/i8254.c
+163
-64
hw/pc.c
hw/pc.c
+5
-4
vl.h
vl.h
+6
-20
未找到文件。
Changelog
浏览文件 @
ec844b96
...
...
@@ -3,6 +3,7 @@ version 0.5.5:
- SDL full screen support (initial patch by malc)
- VGA support on PowerPC PREP
- VBE fixes (Matthew Mastracci)
- PIT fixes (aka Win98 hardware probe and timer bug)
version 0.5.4:
...
...
hw/i8254.c
浏览文件 @
ec844b96
...
...
@@ -25,14 +25,36 @@
//#define DEBUG_PIT
#define RW_STATE_LSB 0
#define RW_STATE_MSB 1
#define RW_STATE_WORD0 2
#define RW_STATE_WORD1 3
#define RW_STATE_LATCHED_WORD0 4
#define RW_STATE_LATCHED_WORD1 5
#define RW_STATE_LSB 1
#define RW_STATE_MSB 2
#define RW_STATE_WORD0 3
#define RW_STATE_WORD1 4
PITChannelState
pit_channels
[
3
];
typedef
struct
PITChannelState
{
int
count
;
/* can be 65536 */
uint16_t
latched_count
;
uint8_t
count_latched
;
uint8_t
status_latched
;
uint8_t
status
;
uint8_t
read_state
;
uint8_t
write_state
;
uint8_t
write_latch
;
uint8_t
rw_mode
;
uint8_t
mode
;
uint8_t
bcd
;
/* not supported */
uint8_t
gate
;
/* timer start */
int64_t
count_load_time
;
/* irq handling */
int64_t
next_transition_time
;
QEMUTimer
*
irq_timer
;
int
irq
;
}
PITChannelState
;
struct
PITState
{
PITChannelState
channels
[
3
];
};
static
PITState
pit_state
;
static
void
pit_irq_timer_update
(
PITChannelState
*
s
,
int64_t
current_time
);
...
...
@@ -61,7 +83,7 @@ static int pit_get_count(PITChannelState *s)
}
/* get pit output bit */
int
pit_get_out
(
PITChannelState
*
s
,
int64_t
current_time
)
static
int
pit_get_out1
(
PITChannelState
*
s
,
int64_t
current_time
)
{
uint64_t
d
;
int
out
;
...
...
@@ -92,6 +114,12 @@ int pit_get_out(PITChannelState *s, int64_t current_time)
return
out
;
}
int
pit_get_out
(
PITState
*
pit
,
int
channel
,
int64_t
current_time
)
{
PITChannelState
*
s
=
&
pit
->
channels
[
channel
];
return
pit_get_out1
(
s
,
current_time
);
}
/* return -1 if no transition will occur. */
static
int64_t
pit_get_next_transition_time
(
PITChannelState
*
s
,
int64_t
current_time
)
...
...
@@ -144,8 +172,10 @@ static int64_t pit_get_next_transition_time(PITChannelState *s,
}
/* val must be 0 or 1 */
void
pit_set_gate
(
PIT
ChannelState
*
s
,
int
val
)
void
pit_set_gate
(
PIT
State
*
pit
,
int
channel
,
int
val
)
{
PITChannelState
*
s
=
&
pit
->
channels
[
channel
];
switch
(
s
->
mode
)
{
default:
case
0
:
...
...
@@ -173,6 +203,12 @@ void pit_set_gate(PITChannelState *s, int val)
s
->
gate
=
val
;
}
int
pit_get_gate
(
PITState
*
pit
,
int
channel
)
{
PITChannelState
*
s
=
&
pit
->
channels
[
channel
];
return
s
->
gate
;
}
static
inline
void
pit_load_count
(
PITChannelState
*
s
,
int
val
)
{
if
(
val
==
0
)
...
...
@@ -182,33 +218,62 @@ static inline void pit_load_count(PITChannelState *s, int val)
pit_irq_timer_update
(
s
,
s
->
count_load_time
);
}
/* if already latched, do not latch again */
static
void
pit_latch_count
(
PITChannelState
*
s
)
{
if
(
!
s
->
count_latched
)
{
s
->
latched_count
=
pit_get_count
(
s
);
s
->
count_latched
=
s
->
rw_mode
;
}
}
static
void
pit_ioport_write
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
val
)
{
PITState
*
pit
=
opaque
;
int
channel
,
access
;
PITChannelState
*
s
;
addr
&=
3
;
if
(
addr
==
3
)
{
channel
=
val
>>
6
;
if
(
channel
==
3
)
return
;
s
=
&
pit_channels
[
channel
];
access
=
(
val
>>
4
)
&
3
;
switch
(
access
)
{
case
0
:
s
->
latched_count
=
pit_get_count
(
s
);
s
->
rw_state
=
RW_STATE_LATCHED_WORD0
;
break
;
default:
s
->
mode
=
(
val
>>
1
)
&
7
;
s
->
bcd
=
val
&
1
;
s
->
rw_state
=
access
-
1
+
RW_STATE_LSB
;
/* XXX: update irq timer ? */
break
;
if
(
channel
==
3
)
{
/* read back command */
for
(
channel
=
0
;
channel
<
3
;
channel
++
)
{
s
=
&
pit
->
channels
[
channel
];
if
(
val
&
(
2
<<
channel
))
{
if
(
!
(
val
&
0x20
))
{
pit_latch_count
(
s
);
}
if
(
!
(
val
&
0x10
)
&&
!
s
->
status_latched
)
{
/* status latch */
/* XXX: add BCD and null count */
s
->
status
=
(
pit_get_out1
(
s
,
qemu_get_clock
(
vm_clock
))
<<
7
)
|
(
s
->
rw_mode
<<
4
)
|
(
s
->
mode
<<
1
)
|
s
->
bcd
;
s
->
status_latched
=
1
;
}
}
}
}
else
{
s
=
&
pit
->
channels
[
channel
];
access
=
(
val
>>
4
)
&
3
;
if
(
access
==
0
)
{
pit_latch_count
(
s
);
}
else
{
s
->
rw_mode
=
access
;
s
->
read_state
=
access
;
s
->
write_state
=
access
;
s
->
mode
=
(
val
>>
1
)
&
7
;
s
->
bcd
=
val
&
1
;
/* XXX: update irq timer ? */
}
}
}
else
{
s
=
&
pit_channels
[
addr
];
switch
(
s
->
rw_state
)
{
s
=
&
pit
->
channels
[
addr
];
switch
(
s
->
write_state
)
{
default:
case
RW_STATE_LSB
:
pit_load_count
(
s
,
val
);
break
;
...
...
@@ -216,13 +281,12 @@ static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
pit_load_count
(
s
,
val
<<
8
);
break
;
case
RW_STATE_WORD0
:
s
->
write_latch
=
val
;
s
->
write_state
=
RW_STATE_WORD1
;
break
;
case
RW_STATE_WORD1
:
if
(
s
->
rw_state
&
1
)
{
pit_load_count
(
s
,
(
s
->
latched_count
&
0xff
)
|
(
val
<<
8
));
}
else
{
s
->
latched_count
=
val
;
}
s
->
rw_state
^=
1
;
pit_load_count
(
s
,
s
->
write_latch
|
(
val
<<
8
));
s
->
write_state
=
RW_STATE_WORD0
;
break
;
}
}
...
...
@@ -230,33 +294,53 @@ static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
static
uint32_t
pit_ioport_read
(
void
*
opaque
,
uint32_t
addr
)
{
PITState
*
pit
=
opaque
;
int
ret
,
count
;
PITChannelState
*
s
;
addr
&=
3
;
s
=
&
pit_channels
[
addr
];
switch
(
s
->
rw_state
)
{
case
RW_STATE_LSB
:
case
RW_STATE_MSB
:
case
RW_STATE_WORD0
:
case
RW_STATE_WORD1
:
count
=
pit_get_count
(
s
);
if
(
s
->
rw_state
&
1
)
ret
=
(
count
>>
8
)
&
0xff
;
else
ret
=
count
&
0xff
;
if
(
s
->
rw_state
&
2
)
s
->
rw_state
^=
1
;
break
;
default:
case
RW_STATE_LATCHED_WORD0
:
case
RW_STATE_LATCHED_WORD1
:
if
(
s
->
rw_state
&
1
)
s
=
&
pit
->
channels
[
addr
];
if
(
s
->
status_latched
)
{
s
->
status_latched
=
0
;
ret
=
s
->
status
;
}
else
if
(
s
->
count_latched
)
{
switch
(
s
->
count_latched
)
{
default:
case
RW_STATE_LSB
:
ret
=
s
->
latched_count
&
0xff
;
s
->
count_latched
=
0
;
break
;
case
RW_STATE_MSB
:
ret
=
s
->
latched_count
>>
8
;
else
s
->
count_latched
=
0
;
break
;
case
RW_STATE_WORD0
:
ret
=
s
->
latched_count
&
0xff
;
s
->
rw_state
^=
1
;
break
;
s
->
count_latched
=
RW_STATE_MSB
;
break
;
}
}
else
{
switch
(
s
->
read_state
)
{
default:
case
RW_STATE_LSB
:
count
=
pit_get_count
(
s
);
ret
=
count
&
0xff
;
break
;
case
RW_STATE_MSB
:
count
=
pit_get_count
(
s
);
ret
=
(
count
>>
8
)
&
0xff
;
break
;
case
RW_STATE_WORD0
:
count
=
pit_get_count
(
s
);
ret
=
count
&
0xff
;
s
->
read_state
=
RW_STATE_WORD1
;
break
;
case
RW_STATE_WORD1
:
count
=
pit_get_count
(
s
);
ret
=
(
count
>>
8
)
&
0xff
;
s
->
read_state
=
RW_STATE_WORD0
;
break
;
}
}
return
ret
;
}
...
...
@@ -269,7 +353,7 @@ static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
if
(
!
s
->
irq_timer
)
return
;
expire_time
=
pit_get_next_transition_time
(
s
,
current_time
);
irq_level
=
pit_get_out
(
s
,
current_time
);
irq_level
=
pit_get_out
1
(
s
,
current_time
);
pic_set_irq
(
s
->
irq
,
irq_level
);
#ifdef DEBUG_PIT
printf
(
"irq_level=%d next_delay=%f
\n
"
,
...
...
@@ -292,14 +376,21 @@ static void pit_irq_timer(void *opaque)
static
void
pit_save
(
QEMUFile
*
f
,
void
*
opaque
)
{
PITState
*
pit
=
opaque
;
PITChannelState
*
s
;
int
i
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
s
=
&
pit
_
channels
[
i
];
s
=
&
pit
->
channels
[
i
];
qemu_put_be32s
(
f
,
&
s
->
count
);
qemu_put_be16s
(
f
,
&
s
->
latched_count
);
qemu_put_8s
(
f
,
&
s
->
rw_state
);
qemu_put_8s
(
f
,
&
s
->
count_latched
);
qemu_put_8s
(
f
,
&
s
->
status_latched
);
qemu_put_8s
(
f
,
&
s
->
status
);
qemu_put_8s
(
f
,
&
s
->
read_state
);
qemu_put_8s
(
f
,
&
s
->
write_state
);
qemu_put_8s
(
f
,
&
s
->
write_latch
);
qemu_put_8s
(
f
,
&
s
->
rw_mode
);
qemu_put_8s
(
f
,
&
s
->
mode
);
qemu_put_8s
(
f
,
&
s
->
bcd
);
qemu_put_8s
(
f
,
&
s
->
gate
);
...
...
@@ -313,6 +404,7 @@ static void pit_save(QEMUFile *f, void *opaque)
static
int
pit_load
(
QEMUFile
*
f
,
void
*
opaque
,
int
version_id
)
{
PITState
*
pit
=
opaque
;
PITChannelState
*
s
;
int
i
;
...
...
@@ -320,10 +412,16 @@ static int pit_load(QEMUFile *f, void *opaque, int version_id)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
s
=
&
pit
_
channels
[
i
];
s
=
&
pit
->
channels
[
i
];
qemu_get_be32s
(
f
,
&
s
->
count
);
qemu_get_be16s
(
f
,
&
s
->
latched_count
);
qemu_get_8s
(
f
,
&
s
->
rw_state
);
qemu_get_8s
(
f
,
&
s
->
count_latched
);
qemu_get_8s
(
f
,
&
s
->
status_latched
);
qemu_get_8s
(
f
,
&
s
->
status
);
qemu_get_8s
(
f
,
&
s
->
read_state
);
qemu_get_8s
(
f
,
&
s
->
write_state
);
qemu_get_8s
(
f
,
&
s
->
write_latch
);
qemu_get_8s
(
f
,
&
s
->
rw_mode
);
qemu_get_8s
(
f
,
&
s
->
mode
);
qemu_get_8s
(
f
,
&
s
->
bcd
);
qemu_get_8s
(
f
,
&
s
->
gate
);
...
...
@@ -336,13 +434,14 @@ static int pit_load(QEMUFile *f, void *opaque, int version_id)
return
0
;
}
void
pit_init
(
int
base
,
int
irq
)
PITState
*
pit_init
(
int
base
,
int
irq
)
{
PITState
*
pit
=
&
pit_state
;
PITChannelState
*
s
;
int
i
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
s
=
&
pit
_
channels
[
i
];
s
=
&
pit
->
channels
[
i
];
if
(
i
==
0
)
{
/* the timer 0 is connected to an IRQ */
s
->
irq_timer
=
qemu_new_timer
(
vm_clock
,
pit_irq_timer
,
s
);
...
...
@@ -353,9 +452,9 @@ void pit_init(int base, int irq)
pit_load_count
(
s
,
0
);
}
register_savevm
(
"i8254"
,
base
,
1
,
pit_save
,
pit_load
,
NULL
);
register_savevm
(
"i8254"
,
base
,
1
,
pit_save
,
pit_load
,
pit
);
register_ioport_write
(
base
,
4
,
1
,
pit_ioport_write
,
NULL
);
register_ioport_read
(
base
,
3
,
1
,
pit_ioport_read
,
NULL
);
register_ioport_write
(
base
,
4
,
1
,
pit_ioport_write
,
pit
);
register_ioport_read
(
base
,
3
,
1
,
pit_ioport_read
,
pit
);
return
pit
;
}
hw/pc.c
浏览文件 @
ec844b96
...
...
@@ -39,6 +39,7 @@ int speaker_data_on;
int
dummy_refresh_clock
;
static
fdctrl_t
*
floppy_controller
;
static
RTCState
*
rtc_state
;
static
PITState
*
pit
;
static
void
ioport80_write
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
data
)
{
...
...
@@ -169,15 +170,15 @@ static void cmos_init(int ram_size, int boot_device)
static
void
speaker_ioport_write
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
val
)
{
speaker_data_on
=
(
val
>>
1
)
&
1
;
pit_set_gate
(
&
pit_channels
[
2
]
,
val
&
1
);
pit_set_gate
(
pit
,
2
,
val
&
1
);
}
static
uint32_t
speaker_ioport_read
(
void
*
opaque
,
uint32_t
addr
)
{
int
out
;
out
=
pit_get_out
(
&
pit_channels
[
2
]
,
qemu_get_clock
(
vm_clock
));
out
=
pit_get_out
(
pit
,
2
,
qemu_get_clock
(
vm_clock
));
dummy_refresh_clock
^=
1
;
return
(
speaker_data_on
<<
1
)
|
pit_
channels
[
2
].
gate
|
(
out
<<
5
)
|
return
(
speaker_data_on
<<
1
)
|
pit_
get_gate
(
pit
,
2
)
|
(
out
<<
5
)
|
(
dummy_refresh_clock
<<
4
);
}
...
...
@@ -381,7 +382,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
register_ioport_write
(
0x92
,
1
,
1
,
ioport92_write
,
NULL
);
pic_init
();
pit_init
(
0x40
,
0
);
pit
=
pit
_init
(
0x40
,
0
);
fd
=
serial_open_device
();
serial_init
(
0x3f8
,
4
,
fd
);
...
...
vl.h
浏览文件 @
ec844b96
...
...
@@ -481,26 +481,12 @@ void pic_info(void);
#define PIT_FREQ 1193182
typedef
struct
PITChannelState
{
int
count
;
/* can be 65536 */
uint16_t
latched_count
;
uint8_t
rw_state
;
uint8_t
mode
;
uint8_t
bcd
;
/* not supported */
uint8_t
gate
;
/* timer start */
int64_t
count_load_time
;
/* irq handling */
int64_t
next_transition_time
;
QEMUTimer
*
irq_timer
;
int
irq
;
}
PITChannelState
;
extern
PITChannelState
pit_channels
[
3
];
void
pit_init
(
int
base
,
int
irq
);
void
pit_set_gate
(
PITChannelState
*
s
,
int
val
);
int
pit_get_out
(
PITChannelState
*
s
,
int64_t
current_time
);
int
pit_get_out_edges
(
PITChannelState
*
s
);
typedef
struct
PITState
PITState
;
PITState
*
pit_init
(
int
base
,
int
irq
);
void
pit_set_gate
(
PITState
*
pit
,
int
channel
,
int
val
);
int
pit_get_gate
(
PITState
*
pit
,
int
channel
);
int
pit_get_out
(
PITState
*
pit
,
int
channel
,
int64_t
current_time
);
/* pc.c */
void
pc_init
(
int
ram_size
,
int
vga_ram_size
,
int
boot_device
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录