Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
53462f4a
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
53462f4a
编写于
9月 08, 2010
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'agraf/ppc-next' into staging
上级
aab2e8f7
42a87658
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
136 addition
and
39 deletion
+136
-39
MAINTAINERS
MAINTAINERS
+4
-4
hw/ppc.c
hw/ppc.c
+11
-0
hw/ppce500_pci.c
hw/ppce500_pci.c
+73
-33
target-ppc/kvm.c
target-ppc/kvm.c
+35
-2
target-ppc/kvm_ppc.h
target-ppc/kvm_ppc.h
+13
-0
未找到文件。
MAINTAINERS
浏览文件 @
53462f4a
...
...
@@ -14,7 +14,7 @@ x86 Fabrice Bellard
ARM Paul Brook
SPARC Blue Swirl
MIPS ?
PowerPC
?
PowerPC
Alexander Graf
M68K Paul Brook
SH4 ?
CRIS Edgar E. Iglesias
...
...
@@ -48,9 +48,9 @@ MIPS
mips_mipssim.c ?
PowerPC
ppc_prep.c ?
ppc_oldworld.c
Fabrice Bellard
ppc_
chrp.c Fabrice Bellard
ppc405_boards.c
?
ppc_oldworld.c
Alexander Graf
ppc_
newworld.c Alexander Graf
ppc405_boards.c
Alexander Graf
M86K
mcf5208.c Paul Brook
an5206.c Paul Brook
...
...
hw/ppc.c
浏览文件 @
53462f4a
...
...
@@ -28,6 +28,8 @@
#include "nvram.h"
#include "qemu-log.h"
#include "loader.h"
#include "kvm.h"
#include "kvm_ppc.h"
//#define PPC_DEBUG_IRQ
//#define PPC_DEBUG_TB
...
...
@@ -50,6 +52,8 @@ static void cpu_ppc_tb_start (CPUState *env);
static
void
ppc_set_irq
(
CPUState
*
env
,
int
n_IRQ
,
int
level
)
{
unsigned
int
old_pending
=
env
->
pending_interrupts
;
if
(
level
)
{
env
->
pending_interrupts
|=
1
<<
n_IRQ
;
cpu_interrupt
(
env
,
CPU_INTERRUPT_HARD
);
...
...
@@ -58,6 +62,13 @@ static void ppc_set_irq (CPUState *env, int n_IRQ, int level)
if
(
env
->
pending_interrupts
==
0
)
cpu_reset_interrupt
(
env
,
CPU_INTERRUPT_HARD
);
}
if
(
old_pending
!=
env
->
pending_interrupts
)
{
#ifdef CONFIG_KVM
kvmppc_set_interrupt
(
env
,
n_IRQ
,
level
);
#endif
}
LOG_IRQ
(
"%s: %p n_IRQ %d level %d => pending %08"
PRIx32
"req %08x
\n
"
,
__func__
,
env
,
n_IRQ
,
level
,
env
->
pending_interrupts
,
env
->
interrupt_request
);
...
...
hw/ppce500_pci.c
浏览文件 @
53462f4a
...
...
@@ -73,11 +73,11 @@ struct pci_inbound {
};
struct
PPCE500PCIState
{
PCIHostState
pci_state
;
struct
pci_outbound
pob
[
PPCE500_PCI_NR_POBS
];
struct
pci_inbound
pib
[
PPCE500_PCI_NR_PIBS
];
uint32_t
gasket_time
;
PCIHostState
pci_state
;
PCIDevice
*
pci_dev
;
uint64_t
base_addr
;
};
typedef
struct
PPCE500PCIState
PPCE500PCIState
;
...
...
@@ -221,7 +221,7 @@ static void ppce500_pci_save(QEMUFile *f, void *opaque)
PPCE500PCIState
*
controller
=
opaque
;
int
i
;
pci_device_save
(
controller
->
pci_dev
,
f
);
/* pci_device_save(controller->pci_dev, f); */
for
(
i
=
0
;
i
<
PPCE500_PCI_NR_POBS
;
i
++
)
{
qemu_put_be32s
(
f
,
&
controller
->
pob
[
i
].
potar
);
...
...
@@ -247,7 +247,7 @@ static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
if
(
version_id
!=
1
)
return
-
EINVAL
;
pci_device_load
(
controller
->
pci_dev
,
f
);
/* pci_device_load(controller->pci_dev, f); */
for
(
i
=
0
;
i
<
PPCE500_PCI_NR_POBS
;
i
++
)
{
qemu_get_be32s
(
f
,
&
controller
->
pob
[
i
].
potar
);
...
...
@@ -269,55 +269,95 @@ static int ppce500_pci_load(QEMUFile *f, void *opaque, int version_id)
PCIBus
*
ppce500_pci_init
(
qemu_irq
pci_irqs
[
4
],
target_phys_addr_t
registers
)
{
PPCE500PCIState
*
controller
;
DeviceState
*
dev
;
PCIBus
*
b
;
PCIHostState
*
h
;
PPCE500PCIState
*
s
;
PCIDevice
*
d
;
int
index
;
static
int
ppce500_pci_id
;
controller
=
qemu_mallocz
(
sizeof
(
PPCE500PCIState
));
dev
=
qdev_create
(
NULL
,
"e500-pcihost"
);
h
=
FROM_SYSBUS
(
PCIHostState
,
sysbus_from_qdev
(
dev
));
s
=
DO_UPCAST
(
PPCE500PCIState
,
pci_state
,
h
);
qdev_prop_set_uint64
(
dev
,
"base_addr"
,
registers
);
b
=
pci_register_bus
(
&
s
->
pci_state
.
busdev
.
qdev
,
NULL
,
mpc85xx_pci_set_irq
,
mpc85xx_pci_map_irq
,
pci_irqs
,
PCI_DEVFN
(
0x11
,
0
),
4
);
s
->
pci_state
.
bus
=
b
;
qdev_init_nofail
(
dev
);
d
=
pci_create_simple
(
b
,
0
,
"e500-host-bridge"
);
/* XXX load/save code not tested. */
register_savevm
(
&
d
->
qdev
,
"ppce500_pci"
,
ppce500_pci_id
++
,
1
,
ppce500_pci_save
,
ppce500_pci_load
,
s
);
controller
->
pci_state
.
bus
=
pci_register_bus
(
NULL
,
"pci"
,
mpc85xx_pci_set_irq
,
mpc85xx_pci_map_irq
,
pci_irqs
,
PCI_DEVFN
(
0x11
,
0
),
4
);
d
=
pci_register_device
(
controller
->
pci_state
.
bus
,
"host bridge"
,
sizeof
(
PCIDevice
),
0
,
NULL
,
NULL
);
return
b
;
}
pci_config_set_vendor_id
(
d
->
config
,
PCI_VENDOR_ID_FREESCALE
);
pci_config_set_device_id
(
d
->
config
,
PCI_DEVICE_ID_MPC8533E
);
pci_config_set_class
(
d
->
config
,
PCI_CLASS_PROCESSOR_POWERPC
);
static
int
e500_pcihost_initfn
(
SysBusDevice
*
dev
)
{
PCIHostState
*
h
;
PPCE500PCIState
*
s
;
target_phys_addr_t
registers
;
int
index
;
controller
->
pci_dev
=
d
;
h
=
FROM_SYSBUS
(
PCIHostState
,
sysbus_from_qdev
(
dev
));
s
=
DO_UPCAST
(
PPCE500PCIState
,
pci_state
,
h
);
registers
=
(
target_phys_addr_t
)
s
->
base_addr
;
/* CFGADDR */
index
=
pci_host_conf_register_mmio
(
&
controller
->
pci_state
,
0
);
index
=
pci_host_conf_register_mmio
(
&
s
->
pci_state
,
0
);
if
(
index
<
0
)
goto
free
;
return
-
1
;
cpu_register_physical_memory
(
registers
+
PCIE500_CFGADDR
,
4
,
index
);
/* CFGDATA */
index
=
pci_host_data_register_mmio
(
&
controller
->
pci_state
,
0
);
index
=
pci_host_data_register_mmio
(
&
s
->
pci_state
,
1
);
if
(
index
<
0
)
goto
free
;
return
-
1
;
cpu_register_physical_memory
(
registers
+
PCIE500_CFGDATA
,
4
,
index
);
index
=
cpu_register_io_memory
(
e500_pci_reg_read
,
e500_pci_reg_write
,
controller
);
e500_pci_reg_write
,
s
);
if
(
index
<
0
)
goto
free
;
return
-
1
;
cpu_register_physical_memory
(
registers
+
PCIE500_REG_BASE
,
PCIE500_REG_SIZE
,
index
);
return
0
;
}
/* XXX load/save code not tested. */
register_savevm
(
&
d
->
qdev
,
"ppce500_pci"
,
ppce500_pci_id
++
,
1
,
ppce500_pci_save
,
ppce500_pci_load
,
controller
);
static
int
e500_host_bridge_initfn
(
PCIDevice
*
dev
)
{
pci_config_set_vendor_id
(
dev
->
config
,
PCI_VENDOR_ID_FREESCALE
);
pci_config_set_device_id
(
dev
->
config
,
PCI_DEVICE_ID_MPC8533E
);
pci_config_set_class
(
dev
->
config
,
PCI_CLASS_PROCESSOR_POWERPC
);
return
0
;
}
static
PCIDeviceInfo
e500_host_bridge_info
=
{
.
qdev
.
name
=
"e500-host-bridge"
,
.
qdev
.
desc
=
"Host bridge"
,
.
qdev
.
size
=
sizeof
(
PCIDevice
),
.
qdev
.
no_user
=
1
,
.
init
=
e500_host_bridge_initfn
,
};
return
controller
->
pci_state
.
bus
;
static
SysBusDeviceInfo
e500_pcihost_info
=
{
.
init
=
e500_pcihost_initfn
,
.
qdev
.
name
=
"e500-pcihost"
,
.
qdev
.
size
=
sizeof
(
PPCE500PCIState
),
.
qdev
.
no_user
=
1
,
.
qdev
.
props
=
(
Property
[])
{
DEFINE_PROP_UINT64
(
"base_addr"
,
PPCE500PCIState
,
base_addr
,
0
),
DEFINE_PROP_END_OF_LIST
(),
}
};
free:
printf
(
"%s error
\n
"
,
__func__
);
qemu_free
(
controller
);
return
NULL
;
static
void
e500_pci_register
(
void
)
{
sysbus_register_withprop
(
&
e500_pcihost_info
);
pci_qdev_register
(
&
e500_host_bridge_info
)
;
}
device_init
(
e500_pci_register
);
target-ppc/kvm.c
浏览文件 @
53462f4a
...
...
@@ -37,6 +37,9 @@
do { } while (0)
#endif
static
int
cap_interrupt_unset
=
false
;
static
int
cap_interrupt_level
=
false
;
/* XXX We have a race condition where we actually have a level triggered
* interrupt, but the infrastructure can't expose that yet, so the guest
* takes but ignores it, goes to sleep and never gets notified that there's
...
...
@@ -55,6 +58,18 @@ static void kvm_kick_env(void *env)
int
kvm_arch_init
(
KVMState
*
s
,
int
smp_cpus
)
{
#ifdef KVM_CAP_PPC_UNSET_IRQ
cap_interrupt_unset
=
kvm_check_extension
(
s
,
KVM_CAP_PPC_UNSET_IRQ
);
#endif
#ifdef KVM_CAP_PPC_IRQ_LEVEL
cap_interrupt_level
=
kvm_check_extension
(
s
,
KVM_CAP_PPC_IRQ_LEVEL
);
#endif
if
(
!
cap_interrupt_level
)
{
fprintf
(
stderr
,
"KVM: Couldn't find level irq capability. Expect the "
"VM to stall at times!
\n
"
);
}
return
0
;
}
...
...
@@ -178,6 +193,23 @@ int kvm_arch_get_registers(CPUState *env)
return
0
;
}
int
kvmppc_set_interrupt
(
CPUState
*
env
,
int
irq
,
int
level
)
{
unsigned
virq
=
level
?
KVM_INTERRUPT_SET_LEVEL
:
KVM_INTERRUPT_UNSET
;
if
(
irq
!=
PPC_INTERRUPT_EXT
)
{
return
0
;
}
if
(
!
kvm_enabled
()
||
!
cap_interrupt_unset
||
!
cap_interrupt_level
)
{
return
0
;
}
kvm_vcpu_ioctl
(
env
,
KVM_INTERRUPT
,
&
virq
);
return
0
;
}
#if defined(TARGET_PPCEMB)
#define PPC_INPUT_INT PPC40x_INPUT_INT
#elif defined(TARGET_PPC64)
...
...
@@ -193,7 +225,8 @@ int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
/* PowerPC Qemu tracks the various core input pins (interrupt, critical
* interrupt, reset, etc) in PPC-specific env->irq_input_state. */
if
(
run
->
ready_for_interrupt_injection
&&
if
(
!
cap_interrupt_level
&&
run
->
ready_for_interrupt_injection
&&
(
env
->
interrupt_request
&
CPU_INTERRUPT_HARD
)
&&
(
env
->
irq_input_state
&
(
1
<<
PPC_INPUT_INT
)))
{
...
...
@@ -201,7 +234,7 @@ int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
* future KVM could cache it in-kernel to avoid a heavyweight exit
* when reading the UIC.
*/
irq
=
-
1U
;
irq
=
KVM_INTERRUPT_SET
;
dprintf
(
"injected interrupt %d
\n
"
,
irq
);
r
=
kvm_vcpu_ioctl
(
env
,
KVM_INTERRUPT
,
&
irq
);
...
...
target-ppc/kvm_ppc.h
浏览文件 @
53462f4a
...
...
@@ -16,5 +16,18 @@ int kvmppc_read_host_property(const char *node_path, const char *prop,
uint32_t
kvmppc_get_tbfreq
(
void
);
int
kvmppc_get_hypercall
(
CPUState
*
env
,
uint8_t
*
buf
,
int
buf_len
);
int
kvmppc_set_interrupt
(
CPUState
*
env
,
int
irq
,
int
level
);
#ifndef KVM_INTERRUPT_SET
#define KVM_INTERRUPT_SET -1
#endif
#ifndef KVM_INTERRUPT_UNSET
#define KVM_INTERRUPT_UNSET -2
#endif
#ifndef KVM_INTERRUPT_SET_LEVEL
#define KVM_INTERRUPT_SET_LEVEL -3
#endif
#endif
/* __KVM_PPC_H__ */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录