Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
a7bd621d
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看板
提交
a7bd621d
编写于
1月 10, 2011
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'mst/for_anthony' into staging
上级
8aaf42ed
a6a7005d
变更
16
隐藏空白更改
内联
并排
Showing
16 changed file
with
410 addition
and
35 deletion
+410
-35
Makefile.objs
Makefile.objs
+1
-3
Makefile.target
Makefile.target
+2
-0
hmp-commands.hx
hmp-commands.hx
+25
-0
hw/pc_piix.c
hw/pc_piix.c
+4
-8
hw/pci-stub.c
hw/pci-stub.c
+50
-0
hw/pci.c
hw/pci.c
+75
-7
hw/pci.h
hw/pci.h
+2
-0
hw/pcie.c
hw/pcie.c
+5
-6
hw/pcie.h
hw/pcie.h
+0
-2
hw/pcie_aer.c
hw/pcie_aer.c
+223
-0
hw/qdev.c
hw/qdev.c
+10
-3
hw/qdev.h
hw/qdev.h
+4
-1
hw/xio3130_downstream.c
hw/xio3130_downstream.c
+1
-1
hw/xio3130_upstream.c
hw/xio3130_upstream.c
+0
-3
sysemu.h
sysemu.h
+5
-0
vl.c
vl.c
+3
-1
未找到文件。
Makefile.objs
浏览文件 @
a7bd621d
...
...
@@ -169,9 +169,7 @@ hw-obj-y =
hw-obj-y
+=
vl.o loader.o
hw-obj-$(CONFIG_VIRTIO)
+=
virtio.o virtio-console.o
hw-obj-y
+=
fw_cfg.o
# FIXME: Core PCI code and its direct dependencies are required by the
# QMP query-pci command.
hw-obj-y
+=
pci.o pci_bridge.o
hw-obj-$(CONFIG_PCI)
+=
pci.o pci_bridge.o
hw-obj-$(CONFIG_PCI)
+=
msix.o msi.o
hw-obj-$(CONFIG_PCI)
+=
pci_host.o pcie_host.o
hw-obj-$(CONFIG_PCI)
+=
ioh3420.o xio3130_upstream.o xio3130_downstream.o
...
...
Makefile.target
浏览文件 @
a7bd621d
# -*- Mode: makefile -*-
GENERATED_HEADERS
=
config-target.h
CONFIG_NO_PCI
=
$(
if
$(
subst
n,,
$(CONFIG_PCI)
)
,n,y
)
CONFIG_NO_KVM
=
$(
if
$(
subst
n,,
$(CONFIG_KVM)
)
,n,y
)
include
../config-host.mak
...
...
@@ -188,6 +189,7 @@ ifdef CONFIG_SOFTMMU
obj-y
=
arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o
# virtio has to be here due to weird dependency between PCI and virtio-net.
# need to fix this properly
obj-$(CONFIG_NO_PCI)
+=
pci-stub.o
obj-$(CONFIG_VIRTIO)
+=
virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
obj-$(CONFIG_VIRTIO_PCI)
+=
virtio-pci.o
obj-y
+=
vhost_net.o
...
...
hmp-commands.hx
浏览文件 @
a7bd621d
...
...
@@ -870,6 +870,31 @@ STEXI
@item pci_del
@findex pci_del
Hot remove PCI device.
ETEXI
{
.name = "pcie_aer_inject_error",
.args_type = "advisory_non_fatal:-a,correctable:-c,"
"id:s,error_status:s,"
"header0:i?,header1:i?,header2:i?,header3:i?,"
"prefix0:i?,prefix1:i?,prefix2:i?,prefix3:i?",
.params = "[-a] [-c] id "
"<error_status> [<tlp header> [<tlp header prefix>]]",
.help = "inject pcie aer error\n\t\t\t"
" -a for advisory non fatal error\n\t\t\t"
" -c for correctable error\n\t\t\t"
"<id> = qdev device id\n\t\t\t"
"<error_status> = error string or 32bit\n\t\t\t"
"<tlb header> = 32bit x 4\n\t\t\t"
"<tlb header prefix> = 32bit x 4",
.user_print = pcie_aer_inject_error_print,
.mhandler.cmd_new = do_pcie_aer_inejct_error,
},
STEXI
@item pcie_aer_inject_error
@findex pcie_aer_inject_error
Inject PCIe AER error
ETEXI
{
...
...
hw/pc_piix.c
浏览文件 @
a7bd621d
...
...
@@ -217,14 +217,6 @@ static QEMUMachine pc_machine = {
.
desc
=
"Standard PC"
,
.
init
=
pc_init_pci
,
.
max_cpus
=
255
,
.
compat_props
=
(
GlobalProperty
[])
{
{
.
driver
=
"PCI"
,
.
property
=
"command_serr_enable"
,
.
value
=
"off"
,
},
{
/* end of list */
}
},
.
is_default
=
1
,
};
...
...
@@ -246,6 +238,10 @@ static QEMUMachine pc_machine_v0_13 = {
.
driver
=
"vmware-svga"
,
.
property
=
"rombar"
,
.
value
=
stringify
(
0
),
},{
.
driver
=
"PCI"
,
.
property
=
"command_serr_enable"
,
.
value
=
"off"
,
},
{
/* end of list */
}
},
...
...
hw/pci-stub.c
0 → 100644
浏览文件 @
a7bd621d
/*
* PCI stubs for plathome that doesn't support pci bus.
*
* Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "sysemu.h"
#include "monitor.h"
#include "pci.h"
static
void
pci_error_message
(
Monitor
*
mon
)
{
monitor_printf
(
mon
,
"PCI devices not supported
\n
"
);
}
void
do_pci_info
(
Monitor
*
mon
,
QObject
**
ret_data
)
{
pci_error_message
(
mon
);
}
void
do_pci_info_print
(
Monitor
*
mon
,
const
QObject
*
data
)
{
pci_error_message
(
mon
);
}
int
do_pcie_aer_inejct_error
(
Monitor
*
mon
,
const
QDict
*
qdict
,
QObject
**
ret_data
)
{
pci_error_message
(
mon
);
return
-
ENOSYS
;
}
void
pcie_aer_inject_error_print
(
Monitor
*
mon
,
const
QObject
*
data
)
{
pci_error_message
(
mon
);
}
hw/pci.c
浏览文件 @
a7bd621d
...
...
@@ -137,7 +137,11 @@ static void pci_update_irq_status(PCIDevice *dev)
}
}
static
void
pci_device_reset
(
PCIDevice
*
dev
)
/*
* This function is called on #RST and FLR.
* FLR if PCI_EXP_DEVCTL_BCR_FLR is set
*/
void
pci_device_reset
(
PCIDevice
*
dev
)
{
int
r
;
/* TODO: call the below unconditionally once all pci devices
...
...
@@ -2010,13 +2014,77 @@ static char *pcibus_get_fw_dev_path(DeviceState *dev)
static
char
*
pcibus_get_dev_path
(
DeviceState
*
dev
)
{
PCIDevice
*
d
=
(
PCIDevice
*
)
dev
;
char
path
[
16
];
PCIDevice
*
d
=
container_of
(
dev
,
PCIDevice
,
qdev
);
PCIDevice
*
t
;
int
slot_depth
;
/* Path format: Domain:00:Slot.Function:Slot.Function....:Slot.Function.
* 00 is added here to make this format compatible with
* domain:Bus:Slot.Func for systems without nested PCI bridges.
* Slot.Function list specifies the slot and function numbers for all
* devices on the path from root to the specific device. */
int
domain_len
=
strlen
(
"DDDD:00"
);
int
slot_len
=
strlen
(
":SS.F"
);
int
path_len
;
char
*
path
,
*
p
;
snprintf
(
path
,
sizeof
(
path
),
"%04x:%02x:%02x.%x"
,
pci_find_domain
(
d
->
bus
),
d
->
config
[
PCI_SECONDARY_BUS
],
PCI_SLOT
(
d
->
devfn
),
PCI_FUNC
(
d
->
devfn
));
/* Calculate # of slots on path between device and root. */
;
slot_depth
=
0
;
for
(
t
=
d
;
t
;
t
=
t
->
bus
->
parent_dev
)
{
++
slot_depth
;
}
return
strdup
(
path
);
path_len
=
domain_len
+
slot_len
*
slot_depth
;
/* Allocate memory, fill in the terminating null byte. */
path
=
malloc
(
path_len
+
1
/* For '\0' */
);
path
[
path_len
]
=
'\0'
;
/* First field is the domain. */
snprintf
(
path
,
domain_len
,
"%04x:00"
,
pci_find_domain
(
d
->
bus
));
/* Fill in slot numbers. We walk up from device to root, so need to print
* them in the reverse order, last to first. */
p
=
path
+
path_len
;
for
(
t
=
d
;
t
;
t
=
t
->
bus
->
parent_dev
)
{
p
-=
slot_len
;
snprintf
(
p
,
slot_len
,
":%02x.%x"
,
PCI_SLOT
(
t
->
devfn
),
PCI_FUNC
(
d
->
devfn
));
}
return
path
;
}
static
int
pci_qdev_find_recursive
(
PCIBus
*
bus
,
const
char
*
id
,
PCIDevice
**
pdev
)
{
DeviceState
*
qdev
=
qdev_find_recursive
(
&
bus
->
qbus
,
id
);
if
(
!
qdev
)
{
return
-
ENODEV
;
}
/* roughly check if given qdev is pci device */
if
(
qdev
->
info
->
init
==
&
pci_qdev_init
&&
qdev
->
parent_bus
->
info
==
&
pci_bus_info
)
{
*
pdev
=
DO_UPCAST
(
PCIDevice
,
qdev
,
qdev
);
return
0
;
}
return
-
EINVAL
;
}
int
pci_qdev_find_device
(
const
char
*
id
,
PCIDevice
**
pdev
)
{
struct
PCIHostBus
*
host
;
int
rc
=
-
ENODEV
;
QLIST_FOREACH
(
host
,
&
host_buses
,
next
)
{
int
tmp
=
pci_qdev_find_recursive
(
host
->
bus
,
id
,
pdev
);
if
(
!
tmp
)
{
rc
=
0
;
break
;
}
if
(
tmp
!=
-
ENODEV
)
{
rc
=
tmp
;
}
}
return
rc
;
}
hw/pci.h
浏览文件 @
a7bd621d
...
...
@@ -237,6 +237,7 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev);
PCIBus
*
pci_register_bus
(
DeviceState
*
parent
,
const
char
*
name
,
pci_set_irq_fn
set_irq
,
pci_map_irq_fn
map_irq
,
void
*
irq_opaque
,
int
devfn_min
,
int
nirq
);
void
pci_device_reset
(
PCIDevice
*
dev
);
void
pci_bus_reset
(
PCIBus
*
bus
);
void
pci_bus_set_mem_base
(
PCIBus
*
bus
,
target_phys_addr_t
base
);
...
...
@@ -251,6 +252,7 @@ PCIBus *pci_find_root_bus(int domain);
int
pci_find_domain
(
const
PCIBus
*
bus
);
PCIBus
*
pci_find_bus
(
PCIBus
*
bus
,
int
bus_num
);
PCIDevice
*
pci_find_device
(
PCIBus
*
bus
,
int
bus_num
,
int
slot
,
int
function
);
int
pci_qdev_find_device
(
const
char
*
id
,
PCIDevice
**
pdev
);
PCIBus
*
pci_get_bus_devfn
(
int
*
devfnp
,
const
char
*
devaddr
);
int
pci_parse_devaddr
(
const
char
*
addr
,
int
*
domp
,
int
*
busp
,
...
...
hw/pcie.c
浏览文件 @
a7bd621d
...
...
@@ -380,10 +380,6 @@ void pcie_cap_root_reset(PCIDevice *dev)
pci_set_word
(
dev
->
config
+
dev
->
exp
.
exp_cap
+
PCI_EXP_RTCTL
,
0
);
}
/*
* TODO: implement FLR:
* Right now sets the bit which indicates FLR is supported.
*/
/* function level reset(FLR) */
void
pcie_cap_flr_init
(
PCIDevice
*
dev
)
{
...
...
@@ -403,8 +399,11 @@ void pcie_cap_flr_write_config(PCIDevice *dev,
uint32_t
addr
,
uint32_t
val
,
int
len
)
{
uint8_t
*
devctl
=
dev
->
config
+
dev
->
exp
.
exp_cap
+
PCI_EXP_DEVCTL
;
if
(
pci_word_test_and_clear_mask
(
devctl
,
PCI_EXP_DEVCTL_BCR_FLR
))
{
/* TODO: implement FLR */
if
(
pci_get_word
(
devctl
)
&
PCI_EXP_DEVCTL_BCR_FLR
)
{
/* Clear PCI_EXP_DEVCTL_BCR_FLR after invoking the reset handler
so the handler can detect FLR by looking at this bit. */
pci_device_reset
(
dev
);
pci_word_test_and_clear_mask
(
devctl
,
PCI_EXP_DEVCTL_BCR_FLR
);
}
}
...
...
hw/pcie.h
浏览文件 @
a7bd621d
...
...
@@ -63,8 +63,6 @@ struct PCIExpressDevice {
/* Offset of express capability in config space */
uint8_t
exp_cap
;
/* TODO FLR */
/* SLOT */
unsigned
int
hpev_intx
;
/* INTx for hot plug event (0-3:INT[A-D]#)
* default is 0 = INTA#
...
...
hw/pcie_aer.c
浏览文件 @
a7bd621d
...
...
@@ -19,6 +19,8 @@
*/
#include "sysemu.h"
#include "qemu-objects.h"
#include "monitor.h"
#include "pci_bridge.h"
#include "pcie.h"
#include "msix.h"
...
...
@@ -806,3 +808,224 @@ const VMStateDescription vmstate_pcie_aer_log = {
VMSTATE_END_OF_LIST
()
}
};
void
pcie_aer_inject_error_print
(
Monitor
*
mon
,
const
QObject
*
data
)
{
QDict
*
qdict
;
int
devfn
;
assert
(
qobject_type
(
data
)
==
QTYPE_QDICT
);
qdict
=
qobject_to_qdict
(
data
);
devfn
=
(
int
)
qdict_get_int
(
qdict
,
"devfn"
);
monitor_printf
(
mon
,
"OK id: %s domain: %x, bus: %x devfn: %x.%x
\n
"
,
qdict_get_str
(
qdict
,
"id"
),
(
int
)
qdict_get_int
(
qdict
,
"domain"
),
(
int
)
qdict_get_int
(
qdict
,
"bus"
),
PCI_SLOT
(
devfn
),
PCI_FUNC
(
devfn
));
}
typedef
struct
PCIEAERErrorName
{
const
char
*
name
;
uint32_t
val
;
bool
correctable
;
}
PCIEAERErrorName
;
/*
* AER error name -> value convertion table
* This naming scheme is same to linux aer-injection tool.
*/
static
const
struct
PCIEAERErrorName
pcie_aer_error_list
[]
=
{
{
.
name
=
"TRAIN"
,
.
val
=
PCI_ERR_UNC_TRAIN
,
.
correctable
=
false
,
},
{
.
name
=
"DLP"
,
.
val
=
PCI_ERR_UNC_DLP
,
.
correctable
=
false
,
},
{
.
name
=
"SDN"
,
.
val
=
PCI_ERR_UNC_SDN
,
.
correctable
=
false
,
},
{
.
name
=
"POISON_TLP"
,
.
val
=
PCI_ERR_UNC_POISON_TLP
,
.
correctable
=
false
,
},
{
.
name
=
"FCP"
,
.
val
=
PCI_ERR_UNC_FCP
,
.
correctable
=
false
,
},
{
.
name
=
"COMP_TIME"
,
.
val
=
PCI_ERR_UNC_COMP_TIME
,
.
correctable
=
false
,
},
{
.
name
=
"COMP_ABORT"
,
.
val
=
PCI_ERR_UNC_COMP_ABORT
,
.
correctable
=
false
,
},
{
.
name
=
"UNX_COMP"
,
.
val
=
PCI_ERR_UNC_UNX_COMP
,
.
correctable
=
false
,
},
{
.
name
=
"RX_OVER"
,
.
val
=
PCI_ERR_UNC_RX_OVER
,
.
correctable
=
false
,
},
{
.
name
=
"MALF_TLP"
,
.
val
=
PCI_ERR_UNC_MALF_TLP
,
.
correctable
=
false
,
},
{
.
name
=
"ECRC"
,
.
val
=
PCI_ERR_UNC_ECRC
,
.
correctable
=
false
,
},
{
.
name
=
"UNSUP"
,
.
val
=
PCI_ERR_UNC_UNSUP
,
.
correctable
=
false
,
},
{
.
name
=
"ACSV"
,
.
val
=
PCI_ERR_UNC_ACSV
,
.
correctable
=
false
,
},
{
.
name
=
"INTN"
,
.
val
=
PCI_ERR_UNC_INTN
,
.
correctable
=
false
,
},
{
.
name
=
"MCBTLP"
,
.
val
=
PCI_ERR_UNC_MCBTLP
,
.
correctable
=
false
,
},
{
.
name
=
"ATOP_EBLOCKED"
,
.
val
=
PCI_ERR_UNC_ATOP_EBLOCKED
,
.
correctable
=
false
,
},
{
.
name
=
"TLP_PRF_BLOCKED"
,
.
val
=
PCI_ERR_UNC_TLP_PRF_BLOCKED
,
.
correctable
=
false
,
},
{
.
name
=
"RCVR"
,
.
val
=
PCI_ERR_COR_RCVR
,
.
correctable
=
true
,
},
{
.
name
=
"BAD_TLP"
,
.
val
=
PCI_ERR_COR_BAD_TLP
,
.
correctable
=
true
,
},
{
.
name
=
"BAD_DLLP"
,
.
val
=
PCI_ERR_COR_BAD_DLLP
,
.
correctable
=
true
,
},
{
.
name
=
"REP_ROLL"
,
.
val
=
PCI_ERR_COR_REP_ROLL
,
.
correctable
=
true
,
},
{
.
name
=
"REP_TIMER"
,
.
val
=
PCI_ERR_COR_REP_TIMER
,
.
correctable
=
true
,
},
{
.
name
=
"ADV_NONFATAL"
,
.
val
=
PCI_ERR_COR_ADV_NONFATAL
,
.
correctable
=
true
,
},
{
.
name
=
"INTERNAL"
,
.
val
=
PCI_ERR_COR_INTERNAL
,
.
correctable
=
true
,
},
{
.
name
=
"HL_OVERFLOW"
,
.
val
=
PCI_ERR_COR_HL_OVERFLOW
,
.
correctable
=
true
,
},
};
static
int
pcie_aer_parse_error_string
(
const
char
*
error_name
,
uint32_t
*
status
,
bool
*
correctable
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
pcie_aer_error_list
);
i
++
)
{
const
PCIEAERErrorName
*
e
=
&
pcie_aer_error_list
[
i
];
if
(
strcmp
(
error_name
,
e
->
name
))
{
continue
;
}
*
status
=
e
->
val
;
*
correctable
=
e
->
correctable
;
return
0
;
}
return
-
EINVAL
;
}
int
do_pcie_aer_inejct_error
(
Monitor
*
mon
,
const
QDict
*
qdict
,
QObject
**
ret_data
)
{
const
char
*
id
=
qdict_get_str
(
qdict
,
"id"
);
const
char
*
error_name
;
uint32_t
error_status
;
bool
correctable
;
PCIDevice
*
dev
;
PCIEAERErr
err
;
int
ret
;
ret
=
pci_qdev_find_device
(
id
,
&
dev
);
if
(
ret
<
0
)
{
monitor_printf
(
mon
,
"id or pci device path is invalid or device not "
"found. %s
\n
"
,
id
);
return
ret
;
}
if
(
!
pci_is_express
(
dev
))
{
monitor_printf
(
mon
,
"the device doesn't support pci express. %s
\n
"
,
id
);
return
-
ENOSYS
;
}
error_name
=
qdict_get_str
(
qdict
,
"error_status"
);
if
(
pcie_aer_parse_error_string
(
error_name
,
&
error_status
,
&
correctable
))
{
char
*
e
=
NULL
;
error_status
=
strtoul
(
error_name
,
&
e
,
0
);
correctable
=
!!
qdict_get_int
(
qdict
,
"correctable"
);
if
(
!
e
||
*
e
!=
'\0'
)
{
monitor_printf
(
mon
,
"invalid error status value.
\"
%s
\"
"
,
error_name
);
return
-
EINVAL
;
}
}
err
.
source_id
=
(
pci_bus_num
(
dev
->
bus
)
<<
8
)
|
dev
->
devfn
;
err
.
flags
=
0
;
if
(
correctable
)
{
err
.
flags
|=
PCIE_AER_ERR_IS_CORRECTABLE
;
}
if
(
qdict_get_int
(
qdict
,
"advisory_non_fatal"
))
{
err
.
flags
|=
PCIE_AER_ERR_MAYBE_ADVISORY
;
}
if
(
qdict_haskey
(
qdict
,
"header0"
))
{
err
.
flags
|=
PCIE_AER_ERR_HEADER_VALID
;
}
if
(
qdict_haskey
(
qdict
,
"prefix0"
))
{
err
.
flags
|=
PCIE_AER_ERR_TLP_PREFIX_PRESENT
;
}
err
.
header
[
0
]
=
qdict_get_try_int
(
qdict
,
"header0"
,
0
);
err
.
header
[
1
]
=
qdict_get_try_int
(
qdict
,
"header1"
,
0
);
err
.
header
[
2
]
=
qdict_get_try_int
(
qdict
,
"header2"
,
0
);
err
.
header
[
3
]
=
qdict_get_try_int
(
qdict
,
"header3"
,
0
);
err
.
prefix
[
0
]
=
qdict_get_try_int
(
qdict
,
"prefix0"
,
0
);
err
.
prefix
[
1
]
=
qdict_get_try_int
(
qdict
,
"prefix1"
,
0
);
err
.
prefix
[
2
]
=
qdict_get_try_int
(
qdict
,
"prefix2"
,
0
);
err
.
prefix
[
3
]
=
qdict_get_try_int
(
qdict
,
"prefix3"
,
0
);
ret
=
pcie_aer_inject_error
(
dev
,
&
err
);
*
ret_data
=
qobject_from_jsonf
(
"{'id': %s, "
"'domain': %d, 'bus': %d, 'devfn': %d, "
"'ret': %d}"
,
id
,
pci_find_domain
(
dev
->
bus
),
pci_bus_num
(
dev
->
bus
),
dev
->
devfn
,
ret
);
assert
(
*
ret_data
);
return
0
;
}
hw/qdev.c
浏览文件 @
a7bd621d
...
...
@@ -328,8 +328,9 @@ void qdev_reset_all(DeviceState *dev)
qdev_walk_children
(
dev
,
qdev_reset_one
,
qbus_reset_one
,
NULL
);
}
void
qbus_reset_all
(
BusState
*
bus
)
void
qbus_reset_all
_fn
(
void
*
opaque
)
{
BusState
*
bus
=
opaque
;
qbus_walk_children
(
bus
,
qdev_reset_one
,
qbus_reset_one
,
NULL
);
}
...
...
@@ -547,7 +548,7 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
return
NULL
;
}
static
DeviceState
*
qdev_find_recursive
(
BusState
*
bus
,
const
char
*
id
)
DeviceState
*
qdev_find_recursive
(
BusState
*
bus
,
const
char
*
id
)
{
DeviceState
*
dev
,
*
ret
;
BusState
*
child
;
...
...
@@ -754,8 +755,11 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
if
(
parent
)
{
QLIST_INSERT_HEAD
(
&
parent
->
child_bus
,
bus
,
sibling
);
parent
->
num_child_bus
++
;
}
else
if
(
bus
!=
main_system_bus
)
{
/* TODO: once all bus devices are qdevified,
only reset handler for main_system_bus should be registered here. */
qemu_register_reset
(
qbus_reset_all_fn
,
bus
);
}
}
BusState
*
qbus_create
(
BusInfo
*
info
,
DeviceState
*
parent
,
const
char
*
name
)
...
...
@@ -778,6 +782,9 @@ void qbus_free(BusState *bus)
if
(
bus
->
parent
)
{
QLIST_REMOVE
(
bus
,
sibling
);
bus
->
parent
->
num_child_bus
--
;
}
else
{
assert
(
bus
!=
main_system_bus
);
/* main_system_bus is never freed */
qemu_unregister_reset
(
qbus_reset_all_fn
,
bus
);
}
qemu_free
((
void
*
)
bus
->
name
);
if
(
bus
->
qdev_allocated
)
{
...
...
hw/qdev.h
浏览文件 @
a7bd621d
...
...
@@ -183,6 +183,8 @@ BusState *qdev_get_parent_bus(DeviceState *dev);
/*** BUS API. ***/
DeviceState
*
qdev_find_recursive
(
BusState
*
bus
,
const
char
*
id
);
/* Returns 0 to walk children, > 0 to skip walk, < 0 to terminate walk. */
typedef
int
(
qbus_walkerfn
)(
BusState
*
bus
,
void
*
opaque
);
typedef
int
(
qdev_walkerfn
)(
DeviceState
*
dev
,
void
*
opaque
);
...
...
@@ -198,7 +200,8 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
int
qdev_walk_children
(
DeviceState
*
dev
,
qdev_walkerfn
*
devfn
,
qbus_walkerfn
*
busfn
,
void
*
opaque
);
void
qdev_reset_all
(
DeviceState
*
dev
);
void
qbus_reset_all
(
BusState
*
bus
);
void
qbus_reset_all_fn
(
void
*
opaque
);
void
qbus_free
(
BusState
*
bus
);
#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
...
...
hw/xio3130_downstream.c
浏览文件 @
a7bd621d
...
...
@@ -89,7 +89,7 @@ static int xio3130_downstream_initfn(PCIDevice *d)
if
(
rc
<
0
)
{
goto
err_msi
;
}
pcie_cap_flr_init
(
d
);
/* TODO: implement FLR */
pcie_cap_flr_init
(
d
);
pcie_cap_deverr_init
(
d
);
pcie_cap_slot_init
(
d
,
s
->
slot
);
pcie_chassis_create
(
s
->
chassis
);
...
...
hw/xio3130_upstream.c
浏览文件 @
a7bd621d
...
...
@@ -85,10 +85,7 @@ static int xio3130_upstream_initfn(PCIDevice *d)
if
(
rc
<
0
)
{
goto
err_msi
;
}
/* TODO: implement FLR */
pcie_cap_flr_init
(
d
);
pcie_cap_deverr_init
(
d
);
rc
=
pcie_aer_init
(
d
,
XIO3130_AER_OFFSET
);
if
(
rc
<
0
)
{
...
...
sysemu.h
浏览文件 @
a7bd621d
...
...
@@ -158,6 +158,11 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict);
void
drive_hot_add
(
Monitor
*
mon
,
const
QDict
*
qdict
);
void
do_pci_device_hot_remove
(
Monitor
*
mon
,
const
QDict
*
qdict
);
/* pcie aer error injection */
void
pcie_aer_inject_error_print
(
Monitor
*
mon
,
const
QObject
*
data
);
int
do_pcie_aer_inejct_error
(
Monitor
*
mon
,
const
QDict
*
qdict
,
QObject
**
ret_data
);
/* serial ports */
#define MAX_SERIAL_PORTS 4
...
...
vl.c
浏览文件 @
a7bd621d
...
...
@@ -3092,7 +3092,9 @@ int main(int argc, char **argv, char **envp)
exit
(
1
);
}
qemu_register_reset
((
void
*
)
qbus_reset_all
,
sysbus_get_default
());
/* TODO: once all bus devices are qdevified, this should be done
* when bus is created by qdev.c */
qemu_register_reset
(
qbus_reset_all_fn
,
sysbus_get_default
());
qemu_run_machine_init_done_notifiers
();
qemu_system_reset
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录