Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
b0a21b53
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看板
提交
b0a21b53
编写于
3月 31, 2004
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
use new timer API
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@689
c046a42c-6fe2-441c-8c8c-71466251a162
上级
dff38e7b
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
330 addition
and
80 deletion
+330
-80
hw/i8254.c
hw/i8254.c
+126
-46
hw/i8259.c
hw/i8259.c
+56
-6
hw/ne2000.c
hw/ne2000.c
+1
-1
hw/pc.c
hw/pc.c
+52
-26
hw/serial.c
hw/serial.c
+1
-1
hw/vga.c
hw/vga.c
+94
-0
未找到文件。
hw/i8254.c
浏览文件 @
b0a21b53
...
...
@@ -43,6 +43,8 @@
#include "cpu.h"
#include "vl.h"
//#define DEBUG_PIT
#define RW_STATE_LSB 0
#define RW_STATE_MSB 1
#define RW_STATE_WORD0 2
...
...
@@ -52,12 +54,14 @@
PITChannelState
pit_channels
[
3
];
static
void
pit_irq_timer_update
(
PITChannelState
*
s
,
int64_t
current_time
);
static
int
pit_get_count
(
PITChannelState
*
s
)
{
uint64_t
d
;
int
counter
;
d
=
muldiv64
(
cpu_get_ticks
(
)
-
s
->
count_load_time
,
PIT_FREQ
,
ticks_per_sec
);
d
=
muldiv64
(
qemu_get_clock
(
vm_clock
)
-
s
->
count_load_time
,
PIT_FREQ
,
ticks_per_sec
);
switch
(
s
->
mode
)
{
case
0
:
case
1
:
...
...
@@ -77,12 +81,12 @@ static int pit_get_count(PITChannelState *s)
}
/* get pit output bit */
int
pit_get_out
(
PITChannelState
*
s
)
int
pit_get_out
(
PITChannelState
*
s
,
int64_t
current_time
)
{
uint64_t
d
;
int
out
;
d
=
muldiv64
(
c
pu_get_ticks
()
-
s
->
count_load_time
,
PIT_FREQ
,
ticks_per_sec
);
d
=
muldiv64
(
c
urrent_time
-
s
->
count_load_time
,
PIT_FREQ
,
ticks_per_sec
);
switch
(
s
->
mode
)
{
default:
case
0
:
...
...
@@ -108,53 +112,51 @@ int pit_get_out(PITChannelState *s)
return
out
;
}
/* get the number of 0 to 1 transitions we had since we call this
function */
/* XXX: maybe better to use ticks precision to avoid getting edges
twice if checks are done at very small intervals */
int
pit_get_out_edges
(
PITChannelState
*
s
)
/* return -1 if no transition will occur. */
static
int64_t
pit_get_next_transition_time
(
PITChannelState
*
s
,
int64_t
current_time
)
{
uint64_t
d1
,
d2
;
int64_t
ticks
;
int
ret
,
v
;
uint64_t
d
,
next_time
,
base
;
int
period2
;
ticks
=
cpu_get_ticks
();
d1
=
muldiv64
(
s
->
count_last_edge_check_time
-
s
->
count_load_time
,
PIT_FREQ
,
ticks_per_sec
);
d2
=
muldiv64
(
ticks
-
s
->
count_load_time
,
PIT_FREQ
,
ticks_per_sec
);
s
->
count_last_edge_check_time
=
ticks
;
d
=
muldiv64
(
current_time
-
s
->
count_load_time
,
PIT_FREQ
,
ticks_per_sec
);
switch
(
s
->
mode
)
{
default:
case
0
:
if
(
d1
<
s
->
count
&&
d2
>=
s
->
count
)
ret
=
1
;
else
ret
=
0
;
break
;
case
1
:
ret
=
0
;
if
(
d
<
s
->
count
)
next_time
=
s
->
count
;
else
return
-
1
;
break
;
case
2
:
d1
/=
s
->
count
;
d2
/=
s
->
count
;
ret
=
d2
-
d1
;
base
=
(
d
/
s
->
count
)
*
s
->
count
;
if
((
d
-
base
)
==
0
&&
d
!=
0
)
next_time
=
base
+
s
->
count
;
else
next_time
=
base
+
s
->
count
+
1
;
break
;
case
3
:
v
=
s
->
count
-
((
s
->
count
+
1
)
>>
1
);
d1
=
(
d1
+
v
)
/
s
->
count
;
d2
=
(
d2
+
v
)
/
s
->
count
;
ret
=
d2
-
d1
;
base
=
(
d
/
s
->
count
)
*
s
->
count
;
period2
=
((
s
->
count
+
1
)
>>
1
);
if
((
d
-
base
)
<
period2
)
next_time
=
base
+
period2
;
else
next_time
=
base
+
s
->
count
;
break
;
case
4
:
case
5
:
if
(
d1
<
s
->
count
&&
d2
>=
s
->
count
)
ret
=
1
;
if
(
d
<
s
->
count
)
next_time
=
s
->
count
;
else
if
(
d
==
s
->
count
)
next_time
=
s
->
count
+
1
;
else
ret
=
0
;
ret
urn
-
1
;
break
;
}
return
ret
;
/* convert to timer units */
next_time
=
s
->
count_load_time
+
muldiv64
(
next_time
,
ticks_per_sec
,
PIT_FREQ
);
return
next_time
;
}
/* val must be 0 or 1 */
...
...
@@ -170,16 +172,16 @@ void pit_set_gate(PITChannelState *s, int val)
case
5
:
if
(
s
->
gate
<
val
)
{
/* restart counting on rising edge */
s
->
count_load_time
=
cpu_get_ticks
(
);
s
->
count_last_edge_check_time
=
s
->
count_load_time
;
s
->
count_load_time
=
qemu_get_clock
(
vm_clock
);
pit_irq_timer_update
(
s
,
s
->
count_load_time
)
;
}
break
;
case
2
:
case
3
:
if
(
s
->
gate
<
val
)
{
/* restart counting on rising edge */
s
->
count_load_time
=
cpu_get_ticks
(
);
s
->
count_last_edge_check_time
=
s
->
count_load_time
;
s
->
count_load_time
=
qemu_get_clock
(
vm_clock
);
pit_irq_timer_update
(
s
,
s
->
count_load_time
)
;
}
/* XXX: disable/enable counting */
break
;
...
...
@@ -191,14 +193,9 @@ static inline void pit_load_count(PITChannelState *s, int val)
{
if
(
val
==
0
)
val
=
0x10000
;
s
->
count_load_time
=
cpu_get_ticks
();
s
->
count_last_edge_check_time
=
s
->
count_load_time
;
s
->
count_load_time
=
qemu_get_clock
(
vm_clock
);
s
->
count
=
val
;
if
(
s
==
&
pit_channels
[
0
]
&&
val
<=
pit_min_timer_count
)
{
fprintf
(
stderr
,
"
\n
WARNING: qemu: on your system, accurate timer emulation is impossible if its frequency is more than %d Hz. If using a 2.6 guest Linux kernel, you must patch asm/param.h to change HZ from 1000 to 100.
\n\n
"
,
PIT_FREQ
/
pit_min_timer_count
);
}
pit_irq_timer_update
(
s
,
s
->
count_load_time
);
}
static
void
pit_ioport_write
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
val
)
...
...
@@ -222,6 +219,7 @@ static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
s
->
mode
=
(
val
>>
1
)
&
7
;
s
->
bcd
=
val
&
1
;
s
->
rw_state
=
access
-
1
+
RW_STATE_LSB
;
/* XXX: update irq timer ? */
break
;
}
}
else
{
...
...
@@ -279,18 +277,100 @@ static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
return
ret
;
}
void
pit_init
(
int
base
)
static
void
pit_irq_timer_update
(
PITChannelState
*
s
,
int64_t
current_time
)
{
int64_t
expire_time
;
int
irq_level
;
if
(
!
s
->
irq_timer
)
return
;
expire_time
=
pit_get_next_transition_time
(
s
,
current_time
);
irq_level
=
pit_get_out
(
s
,
current_time
);
pic_set_irq
(
s
->
irq
,
irq_level
);
#ifdef DEBUG_PIT
printf
(
"irq_level=%d next_delay=%f
\n
"
,
irq_level
,
(
double
)(
expire_time
-
current_time
)
/
ticks_per_sec
);
#endif
s
->
next_transition_time
=
expire_time
;
if
(
expire_time
!=
-
1
)
qemu_mod_timer
(
s
->
irq_timer
,
expire_time
);
else
qemu_del_timer
(
s
->
irq_timer
);
}
static
void
pit_irq_timer
(
void
*
opaque
)
{
PITChannelState
*
s
=
opaque
;
pit_irq_timer_update
(
s
,
s
->
next_transition_time
);
}
static
void
pit_save
(
QEMUFile
*
f
,
void
*
opaque
)
{
PITChannelState
*
s
;
int
i
;
for
(
i
=
0
;
i
<
3
;
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
->
mode
);
qemu_put_8s
(
f
,
&
s
->
bcd
);
qemu_put_8s
(
f
,
&
s
->
gate
);
qemu_put_be64s
(
f
,
&
s
->
count_load_time
);
if
(
s
->
irq_timer
)
{
qemu_put_be64s
(
f
,
&
s
->
next_transition_time
);
qemu_put_timer
(
f
,
s
->
irq_timer
);
}
}
}
static
int
pit_load
(
QEMUFile
*
f
,
void
*
opaque
,
int
version_id
)
{
PITChannelState
*
s
;
int
i
;
if
(
version_id
!=
1
)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
3
;
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
->
mode
);
qemu_get_8s
(
f
,
&
s
->
bcd
);
qemu_get_8s
(
f
,
&
s
->
gate
);
qemu_get_be64s
(
f
,
&
s
->
count_load_time
);
if
(
s
->
irq_timer
)
{
qemu_get_be64s
(
f
,
&
s
->
next_transition_time
);
qemu_get_timer
(
f
,
s
->
irq_timer
);
}
}
return
0
;
}
void
pit_init
(
int
base
,
int
irq
)
{
PITChannelState
*
s
;
int
i
;
for
(
i
=
0
;
i
<
3
;
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
);
s
->
irq
=
irq
;
}
s
->
mode
=
3
;
s
->
gate
=
(
i
!=
2
);
pit_load_count
(
s
,
0
);
}
register_savevm
(
"i8254"
,
base
,
1
,
pit_save
,
pit_load
,
NULL
);
register_ioport_write
(
base
,
4
,
1
,
pit_ioport_write
,
NULL
);
register_ioport_read
(
base
,
3
,
1
,
pit_ioport_read
,
NULL
);
}
...
...
hw/i8259.c
浏览文件 @
b0a21b53
...
...
@@ -122,7 +122,7 @@ static int pic_get_irq(PicState *s)
/* raise irq to CPU if necessary. must be called every time the active
irq may change */
void
pic_update_irq
(
void
)
static
void
pic_update_irq
(
void
)
{
int
irq2
,
irq
;
...
...
@@ -160,7 +160,6 @@ void pic_update_irq(void)
#ifdef DEBUG_IRQ_LATENCY
int64_t
irq_time
[
16
];
int64_t
cpu_get_ticks
(
void
);
#endif
#if defined(DEBUG_PIC)
int
irq_level
[
16
];
...
...
@@ -376,11 +375,62 @@ uint32_t pic_intack_read(CPUState *env)
return
ret
;
}
static
void
pic_save
(
QEMUFile
*
f
,
void
*
opaque
)
{
PicState
*
s
=
opaque
;
qemu_put_8s
(
f
,
&
s
->
last_irr
);
qemu_put_8s
(
f
,
&
s
->
irr
);
qemu_put_8s
(
f
,
&
s
->
imr
);
qemu_put_8s
(
f
,
&
s
->
isr
);
qemu_put_8s
(
f
,
&
s
->
priority_add
);
qemu_put_8s
(
f
,
&
s
->
irq_base
);
qemu_put_8s
(
f
,
&
s
->
read_reg_select
);
qemu_put_8s
(
f
,
&
s
->
poll
);
qemu_put_8s
(
f
,
&
s
->
special_mask
);
qemu_put_8s
(
f
,
&
s
->
init_state
);
qemu_put_8s
(
f
,
&
s
->
auto_eoi
);
qemu_put_8s
(
f
,
&
s
->
rotate_on_auto_eoi
);
qemu_put_8s
(
f
,
&
s
->
special_fully_nested_mode
);
qemu_put_8s
(
f
,
&
s
->
init4
);
}
static
int
pic_load
(
QEMUFile
*
f
,
void
*
opaque
,
int
version_id
)
{
PicState
*
s
=
opaque
;
if
(
version_id
!=
1
)
return
-
EINVAL
;
qemu_get_8s
(
f
,
&
s
->
last_irr
);
qemu_get_8s
(
f
,
&
s
->
irr
);
qemu_get_8s
(
f
,
&
s
->
imr
);
qemu_get_8s
(
f
,
&
s
->
isr
);
qemu_get_8s
(
f
,
&
s
->
priority_add
);
qemu_get_8s
(
f
,
&
s
->
irq_base
);
qemu_get_8s
(
f
,
&
s
->
read_reg_select
);
qemu_get_8s
(
f
,
&
s
->
poll
);
qemu_get_8s
(
f
,
&
s
->
special_mask
);
qemu_get_8s
(
f
,
&
s
->
init_state
);
qemu_get_8s
(
f
,
&
s
->
auto_eoi
);
qemu_get_8s
(
f
,
&
s
->
rotate_on_auto_eoi
);
qemu_get_8s
(
f
,
&
s
->
special_fully_nested_mode
);
qemu_get_8s
(
f
,
&
s
->
init4
);
return
0
;
}
/* XXX: add generic master/slave system */
static
void
pic_init1
(
int
io_addr
,
PicState
*
s
)
{
register_ioport_write
(
io_addr
,
2
,
1
,
pic_ioport_write
,
s
);
register_ioport_read
(
io_addr
,
2
,
1
,
pic_ioport_read
,
s
);
register_savevm
(
"i8259"
,
io_addr
,
1
,
pic_save
,
pic_load
,
s
);
}
void
pic_init
(
void
)
{
register_ioport_write
(
0x20
,
2
,
1
,
pic_ioport_write
,
&
pics
[
0
]);
register_ioport_read
(
0x20
,
2
,
1
,
pic_ioport_read
,
&
pics
[
0
]);
register_ioport_write
(
0xa0
,
2
,
1
,
pic_ioport_write
,
&
pics
[
1
]);
register_ioport_read
(
0xa0
,
2
,
1
,
pic_ioport_read
,
&
pics
[
1
]);
pic_init1
(
0x20
,
&
pics
[
0
]);
pic_init1
(
0xa0
,
&
pics
[
1
]);
}
hw/ne2000.c
浏览文件 @
b0a21b53
...
...
@@ -471,5 +471,5 @@ void ne2000_init(int base, int irq, NetDriverState *nd)
ne2000_reset
(
s
);
add_fd_read_handler
(
nd
->
fd
,
ne2000_can_receive
,
ne2000_receive
,
s
);
qemu_
add_fd_read_handler
(
nd
->
fd
,
ne2000_can_receive
,
ne2000_receive
,
s
);
}
hw/pc.c
浏览文件 @
b0a21b53
...
...
@@ -58,50 +58,69 @@
int
speaker_data_on
;
int
dummy_refresh_clock
;
static
fdctrl_t
*
floppy_controller
;
static
RTCState
*
rtc_state
;
static
void
ioport80_write
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
data
)
{
}
/* PC cmos mappings */
#define REG_EQUIPMENT_BYTE 0x14
#define REG_IBM_CENTURY_BYTE 0x32
#define REG_IBM_PS2_CENTURY_BYTE 0x37
static
inline
int
to_bcd
(
RTCState
*
s
,
int
a
)
{
return
((
a
/
10
)
<<
4
)
|
(
a
%
10
);
}
static
void
cmos_init
(
int
ram_size
,
int
boot_device
)
{
RTCState
*
s
=
&
rtc_state
;
RTCState
*
s
=
rtc_state
;
int
val
;
int
fd0
,
fd1
,
nb
;
/* various important CMOS locations needed by PC/Bochs bios */
time_t
ti
;
struct
tm
*
tm
;
/* set the CMOS date */
time
(
&
ti
);
tm
=
gmtime
(
&
ti
);
rtc_set_date
(
s
,
tm
);
val
=
to_bcd
(
s
,
(
tm
->
tm_year
/
100
)
+
19
);
rtc_set_memory
(
s
,
REG_IBM_CENTURY_BYTE
,
val
);
rtc_set_memory
(
s
,
REG_IBM_PS2_CENTURY_BYTE
,
val
);
s
->
cmos_data
[
REG_EQUIPMENT_BYTE
]
=
0x02
;
/* FPU is there */
s
->
cmos_data
[
REG_EQUIPMENT_BYTE
]
|=
0x04
;
/* PS/2 mouse installed */
/* various important CMOS locations needed by PC/Bochs bios */
/* memory size */
val
=
(
ram_size
/
1024
)
-
1024
;
if
(
val
>
65535
)
val
=
65535
;
s
->
cmos_data
[
0x17
]
=
val
;
s
->
cmos_data
[
0x18
]
=
val
>>
8
;
s
->
cmos_data
[
0x30
]
=
val
;
s
->
cmos_data
[
0x31
]
=
val
>>
8
;
rtc_set_memory
(
s
,
0x17
,
val
)
;
rtc_set_memory
(
s
,
0x18
,
val
>>
8
)
;
rtc_set_memory
(
s
,
0x30
,
val
)
;
rtc_set_memory
(
s
,
0x31
,
val
>>
8
)
;
val
=
(
ram_size
/
65536
)
-
((
16
*
1024
*
1024
)
/
65536
);
if
(
val
>
65535
)
val
=
65535
;
s
->
cmos_data
[
0x34
]
=
val
;
s
->
cmos_data
[
0x35
]
=
val
>>
8
;
rtc_set_memory
(
s
,
0x34
,
val
)
;
rtc_set_memory
(
s
,
0x35
,
val
>>
8
)
;
switch
(
boot_device
)
{
case
'a'
:
case
'b'
:
s
->
cmos_data
[
0x3d
]
=
0x01
;
/* floppy boot */
rtc_set_memory
(
s
,
0x3d
,
0x01
)
;
/* floppy boot */
break
;
default:
case
'c'
:
s
->
cmos_data
[
0x3d
]
=
0x02
;
/* hard drive boot */
rtc_set_memory
(
s
,
0x3d
,
0x02
)
;
/* hard drive boot */
break
;
case
'd'
:
s
->
cmos_data
[
0x3d
]
=
0x03
;
/* CD-ROM boot */
rtc_set_memory
(
s
,
0x3d
,
0x03
)
;
/* CD-ROM boot */
break
;
}
...
...
@@ -110,35 +129,38 @@ static void cmos_init(int ram_size, int boot_device)
fd0
=
fdctrl_get_drive_type
(
floppy_controller
,
0
);
fd1
=
fdctrl_get_drive_type
(
floppy_controller
,
1
);
s
->
cmos_data
[
0x10
]
=
0
;
val
=
0
;
switch
(
fd0
)
{
case
0
:
/* 1.44 Mb 3"5 drive */
s
->
cmos_data
[
0x10
]
|=
0x40
;
val
|=
0x40
;
break
;
case
1
:
/* 2.88 Mb 3"5 drive */
s
->
cmos_data
[
0x10
]
|=
0x60
;
val
|=
0x60
;
break
;
case
2
:
/* 1.2 Mb 5"5 drive */
s
->
cmos_data
[
0x10
]
|=
0x20
;
val
|=
0x20
;
break
;
}
switch
(
fd1
)
{
case
0
:
/* 1.44 Mb 3"5 drive */
s
->
cmos_data
[
0x10
]
|=
0x04
;
val
|=
0x04
;
break
;
case
1
:
/* 2.88 Mb 3"5 drive */
s
->
cmos_data
[
0x10
]
|=
0x06
;
val
|=
0x06
;
break
;
case
2
:
/* 1.2 Mb 5"5 drive */
s
->
cmos_data
[
0x10
]
|=
0x02
;
val
|=
0x02
;
break
;
}
rtc_set_memory
(
s
,
0x10
,
val
);
val
=
0
;
nb
=
0
;
if
(
fd0
<
3
)
nb
++
;
...
...
@@ -148,12 +170,16 @@ static void cmos_init(int ram_size, int boot_device)
case
0
:
break
;
case
1
:
s
->
cmos_data
[
REG_EQUIPMENT_BYTE
]
|=
0x01
;
/* 1 drive, ready for boot */
val
|=
0x01
;
/* 1 drive, ready for boot */
break
;
case
2
:
s
->
cmos_data
[
REG_EQUIPMENT_BYTE
]
|=
0x41
;
/* 2 drives, ready for boot */
val
|=
0x41
;
/* 2 drives, ready for boot */
break
;
}
val
|=
0x02
;
/* FPU is there */
val
|=
0x04
;
/* PS/2 mouse installed */
rtc_set_memory
(
s
,
REG_EQUIPMENT_BYTE
,
val
);
}
static
void
speaker_ioport_write
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
val
)
...
...
@@ -165,7 +191,7 @@ static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
static
uint32_t
speaker_ioport_read
(
void
*
opaque
,
uint32_t
addr
)
{
int
out
;
out
=
pit_get_out
(
&
pit_channels
[
2
]);
out
=
pit_get_out
(
&
pit_channels
[
2
]
,
qemu_get_clock
(
vm_clock
)
);
dummy_refresh_clock
^=
1
;
return
(
speaker_data_on
<<
1
)
|
pit_channels
[
2
].
gate
|
(
out
<<
5
)
|
(
dummy_refresh_clock
<<
4
);
...
...
@@ -345,12 +371,12 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
vga_initialize
(
ds
,
phys_ram_base
+
ram_size
,
ram_size
,
vga_ram_size
);
rtc_init
(
0x70
,
8
);
rtc_
state
=
rtc_
init
(
0x70
,
8
);
register_ioport_read
(
0x61
,
1
,
1
,
speaker_ioport_read
,
NULL
);
register_ioport_write
(
0x61
,
1
,
1
,
speaker_ioport_write
,
NULL
);
pic_init
();
pit_init
(
0x40
);
pit_init
(
0x40
,
0
);
fd
=
serial_open_device
();
serial_init
(
0x3f8
,
4
,
fd
);
...
...
hw/serial.c
浏览文件 @
b0a21b53
...
...
@@ -288,7 +288,7 @@ SerialState *serial_init(int base, int irq, int fd)
register_ioport_read
(
base
,
8
,
1
,
serial_ioport_read
,
s
);
if
(
fd
!=
0
)
{
add_fd_read_handler
(
fd
,
serial_can_receive1
,
serial_receive1
,
s
);
qemu_
add_fd_read_handler
(
fd
,
serial_can_receive1
,
serial_receive1
,
s
);
s
->
out_fd
=
fd
;
}
else
{
serial_console
=
s
;
...
...
hw/vga.c
浏览文件 @
b0a21b53
...
...
@@ -1578,6 +1578,98 @@ static CPUWriteMemoryFunc *vga_mem_write[3] = {
vga_mem_writel
,
};
static
void
vga_save
(
QEMUFile
*
f
,
void
*
opaque
)
{
VGAState
*
s
=
opaque
;
int
i
;
qemu_put_be32s
(
f
,
&
s
->
latch
);
qemu_put_8s
(
f
,
&
s
->
sr_index
);
qemu_put_buffer
(
f
,
s
->
sr
,
8
);
qemu_put_8s
(
f
,
&
s
->
gr_index
);
qemu_put_buffer
(
f
,
s
->
gr
,
16
);
qemu_put_8s
(
f
,
&
s
->
ar_index
);
qemu_put_buffer
(
f
,
s
->
ar
,
21
);
qemu_put_be32s
(
f
,
&
s
->
ar_flip_flop
);
qemu_put_8s
(
f
,
&
s
->
cr_index
);
qemu_put_buffer
(
f
,
s
->
cr
,
256
);
qemu_put_8s
(
f
,
&
s
->
msr
);
qemu_put_8s
(
f
,
&
s
->
fcr
);
qemu_put_8s
(
f
,
&
s
->
st00
);
qemu_put_8s
(
f
,
&
s
->
st01
);
qemu_put_8s
(
f
,
&
s
->
dac_state
);
qemu_put_8s
(
f
,
&
s
->
dac_sub_index
);
qemu_put_8s
(
f
,
&
s
->
dac_read_index
);
qemu_put_8s
(
f
,
&
s
->
dac_write_index
);
qemu_put_buffer
(
f
,
s
->
dac_cache
,
3
);
qemu_put_buffer
(
f
,
s
->
palette
,
768
);
qemu_put_be32s
(
f
,
&
s
->
bank_offset
);
#ifdef CONFIG_BOCHS_VBE
qemu_put_byte
(
f
,
1
);
qemu_put_be16s
(
f
,
&
s
->
vbe_index
);
for
(
i
=
0
;
i
<
VBE_DISPI_INDEX_NB
;
i
++
)
qemu_put_be16s
(
f
,
&
s
->
vbe_regs
[
i
]);
qemu_put_be32s
(
f
,
&
s
->
vbe_start_addr
);
qemu_put_be32s
(
f
,
&
s
->
vbe_line_offset
);
qemu_put_be32s
(
f
,
&
s
->
vbe_bank_mask
);
#else
qemu_put_byte
(
f
,
0
);
#endif
}
static
int
vga_load
(
QEMUFile
*
f
,
void
*
opaque
,
int
version_id
)
{
VGAState
*
s
=
opaque
;
int
is_vbe
,
i
;
if
(
version_id
!=
1
)
return
-
EINVAL
;
qemu_get_be32s
(
f
,
&
s
->
latch
);
qemu_get_8s
(
f
,
&
s
->
sr_index
);
qemu_get_buffer
(
f
,
s
->
sr
,
8
);
qemu_get_8s
(
f
,
&
s
->
gr_index
);
qemu_get_buffer
(
f
,
s
->
gr
,
16
);
qemu_get_8s
(
f
,
&
s
->
ar_index
);
qemu_get_buffer
(
f
,
s
->
ar
,
21
);
qemu_get_be32s
(
f
,
&
s
->
ar_flip_flop
);
qemu_get_8s
(
f
,
&
s
->
cr_index
);
qemu_get_buffer
(
f
,
s
->
cr
,
256
);
qemu_get_8s
(
f
,
&
s
->
msr
);
qemu_get_8s
(
f
,
&
s
->
fcr
);
qemu_get_8s
(
f
,
&
s
->
st00
);
qemu_get_8s
(
f
,
&
s
->
st01
);
qemu_get_8s
(
f
,
&
s
->
dac_state
);
qemu_get_8s
(
f
,
&
s
->
dac_sub_index
);
qemu_get_8s
(
f
,
&
s
->
dac_read_index
);
qemu_get_8s
(
f
,
&
s
->
dac_write_index
);
qemu_get_buffer
(
f
,
s
->
dac_cache
,
3
);
qemu_get_buffer
(
f
,
s
->
palette
,
768
);
qemu_get_be32s
(
f
,
&
s
->
bank_offset
);
is_vbe
=
qemu_get_byte
(
f
);
#ifdef CONFIG_BOCHS_VBE
if
(
!
is_vbe
)
return
-
EINVAL
;
qemu_get_be16s
(
f
,
&
s
->
vbe_index
);
for
(
i
=
0
;
i
<
VBE_DISPI_INDEX_NB
;
i
++
)
qemu_get_be16s
(
f
,
&
s
->
vbe_regs
[
i
]);
qemu_get_be32s
(
f
,
&
s
->
vbe_start_addr
);
qemu_get_be32s
(
f
,
&
s
->
vbe_line_offset
);
qemu_get_be32s
(
f
,
&
s
->
vbe_bank_mask
);
#else
if
(
is_vbe
)
return
-
EINVAL
;
#endif
/* force refresh */
s
->
graphic_mode
=
-
1
;
return
0
;
}
int
vga_initialize
(
DisplayState
*
ds
,
uint8_t
*
vga_ram_base
,
unsigned
long
vga_ram_offset
,
int
vga_ram_size
)
{
...
...
@@ -1614,6 +1706,8 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base,
s
->
vram_size
=
vga_ram_size
;
s
->
ds
=
ds
;
register_savevm
(
"vga"
,
0
,
1
,
vga_save
,
vga_load
,
s
);
register_ioport_write
(
0x3c0
,
16
,
1
,
vga_ioport_write
,
s
);
register_ioport_write
(
0x3b4
,
2
,
1
,
vga_ioport_write
,
s
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录