Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
9edf5051
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看板
提交
9edf5051
编写于
2月 19, 2010
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'mst/for_anthony' into staging
上级
2583ba97
a408b1de
变更
20
隐藏空白更改
内联
并排
Showing
20 changed file
with
511 addition
and
239 deletion
+511
-239
Makefile.target
Makefile.target
+1
-0
bswap.h
bswap.h
+6
-0
hw/mac_dbdma.c
hw/mac_dbdma.c
+7
-3
hw/pci.h
hw/pci.h
+0
-1
hw/pci_host.c
hw/pci_host.c
+70
-102
hw/pci_host.h
hw/pci_host.h
+4
-0
hw/pci_host_template.h
hw/pci_host_template.h
+0
-109
hw/pci_ids.h
hw/pci_ids.h
+1
-0
hw/ppc.h
hw/ppc.h
+2
-0
hw/ppc_mac.h
hw/ppc_mac.h
+1
-0
hw/ppc_newworld.c
hw/ppc_newworld.c
+65
-8
hw/ppc_oldworld.c
hw/ppc_oldworld.c
+9
-0
hw/unin_pci.c
hw/unin_pci.c
+147
-4
hw/versatile_pci.c
hw/versatile_pci.c
+3
-7
qemu-common.h
qemu-common.h
+2
-0
rwhandler.c
rwhandler.c
+91
-0
rwhandler.h
rwhandler.h
+27
-0
target-ppc/helper.c
target-ppc/helper.c
+4
-5
target-ppc/kvm.c
target-ppc/kvm.c
+69
-0
target-ppc/kvm_ppc.h
target-ppc/kvm_ppc.h
+2
-0
未找到文件。
Makefile.target
浏览文件 @
9edf5051
...
...
@@ -46,6 +46,7 @@ all: $(PROGS)
# cpu emulator library
libobj-y
=
exec.o translate-all.o cpu-exec.o translate.o
libobj-y
+=
tcg/tcg.o
libobj-y
+=
rwhandler.o
libobj-$(CONFIG_SOFTFLOAT)
+=
fpu/softfloat.o
libobj-$(CONFIG_NOSOFTFLOAT)
+=
fpu/softfloat-native.o
libobj-y
+=
op_helper.o helper.o
...
...
bswap.h
浏览文件 @
9edf5051
...
...
@@ -214,4 +214,10 @@ static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
#undef le_bswaps
#undef be_bswaps
/* len must be one of 1, 2, 4 */
static
inline
uint32_t
qemu_bswap_len
(
uint32_t
value
,
int
len
)
{
return
bswap32
(
value
)
>>
(
32
-
8
*
len
);
}
#endif
/* BSWAP_H */
hw/mac_dbdma.c
浏览文件 @
9edf5051
...
...
@@ -402,7 +402,9 @@ static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
ch
->
io
.
dma_end
=
dbdma_end
;
ch
->
io
.
is_dma_out
=
1
;
ch
->
processing
=
1
;
ch
->
rw
(
&
ch
->
io
);
if
(
ch
->
rw
)
{
ch
->
rw
(
&
ch
->
io
);
}
}
static
void
start_input
(
DBDMA_channel
*
ch
,
int
key
,
uint32_t
addr
,
...
...
@@ -425,7 +427,9 @@ static void start_input(DBDMA_channel *ch, int key, uint32_t addr,
ch
->
io
.
dma_end
=
dbdma_end
;
ch
->
io
.
is_dma_out
=
0
;
ch
->
processing
=
1
;
ch
->
rw
(
&
ch
->
io
);
if
(
ch
->
rw
)
{
ch
->
rw
(
&
ch
->
io
);
}
}
static
void
load_word
(
DBDMA_channel
*
ch
,
int
key
,
uint32_t
addr
,
...
...
@@ -688,7 +692,7 @@ dbdma_control_write(DBDMA_channel *ch)
if
(
status
&
ACTIVE
)
qemu_bh_schedule
(
dbdma_bh
);
if
(
status
&
FLUSH
)
if
(
(
status
&
FLUSH
)
&&
ch
->
flush
)
ch
->
flush
(
&
ch
->
io
);
}
...
...
hw/pci.h
浏览文件 @
9edf5051
...
...
@@ -70,7 +70,6 @@
#define PCI_DEVICE_ID_VIRTIO_BALLOON 0x1002
#define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003
typedef
uint64_t
pcibus_t
;
#define FMT_PCIBUS PRIx64
typedef
void
PCIConfigWriteFunc
(
PCIDevice
*
pci_dev
,
...
...
hw/pci_host.c
浏览文件 @
9edf5051
...
...
@@ -79,152 +79,120 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
return
val
;
}
static
void
pci_host_config_write
l
(
void
*
opaque
,
target_phys_addr_t
add
r
,
uint32_t
val
)
static
void
pci_host_config_write
(
ReadWriteHandler
*
handle
r
,
pcibus_t
addr
,
uint32_t
val
,
int
len
)
{
PCIHostState
*
s
=
opaque
;
PCIHostState
*
s
=
container_of
(
handler
,
PCIHostState
,
conf_handler
)
;
PCI_DPRINTF
(
"%s addr %"
FMT_PCIBUS
" %d val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
len
,
val
);
#ifdef TARGET_WORDS_BIGENDIAN
val
=
bswap32
(
val
);
val
=
qemu_bswap_len
(
val
,
len
);
#endif
PCI_DPRINTF
(
"%s addr "
TARGET_FMT_plx
" val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
val
);
s
->
config_reg
=
val
;
}
static
uint32_t
pci_host_config_readl
(
void
*
opaque
,
target_phys_addr_t
addr
)
static
uint32_t
pci_host_config_read
(
ReadWriteHandler
*
handler
,
pcibus_t
addr
,
int
len
)
{
PCIHostState
*
s
=
opaque
;
PCIHostState
*
s
=
container_of
(
handler
,
PCIHostState
,
conf_handler
)
;
uint32_t
val
=
s
->
config_reg
;
#ifdef TARGET_WORDS_BIGENDIAN
val
=
bswap32
(
val
);
val
=
qemu_bswap_len
(
val
,
len
);
#endif
PCI_DPRINTF
(
"%s addr
"
TARGET_FMT_plx
"
val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
val
);
PCI_DPRINTF
(
"%s addr
%"
FMT_PCIBUS
" len %d
val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
len
,
val
);
return
val
;
}
static
CPUWriteMemoryFunc
*
const
pci_host_config_write
[]
=
{
&
pci_host_config_writel
,
&
pci_host_config_writel
,
&
pci_host_config_writel
,
};
static
CPUReadMemoryFunc
*
const
pci_host_config_read
[]
=
{
&
pci_host_config_readl
,
&
pci_host_config_readl
,
&
pci_host_config_readl
,
};
int
pci_host_conf_register_mmio
(
PCIHostState
*
s
)
{
return
cpu_register_io_memory
(
pci_host_config_read
,
pci_host_config_write
,
s
);
}
static
void
pci_host_config_writel_noswap
(
void
*
opaque
,
target_phys_addr_t
addr
,
uint32_t
val
)
static
void
pci_host_config_write_noswap
(
ReadWriteHandler
*
handler
,
pcibus_t
addr
,
uint32_t
val
,
int
len
)
{
PCIHostState
*
s
=
opaque
;
PCIHostState
*
s
=
container_of
(
handler
,
PCIHostState
,
conf_noswap_handler
)
;
PCI_DPRINTF
(
"%s addr
"
TARGET_FMT_plx
"
val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
val
);
PCI_DPRINTF
(
"%s addr
%"
FMT_PCIBUS
" %d
val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
len
,
val
);
s
->
config_reg
=
val
;
}
static
uint32_t
pci_host_config_read
l_noswap
(
void
*
opaque
,
target_phys_addr_t
addr
)
static
uint32_t
pci_host_config_read
_noswap
(
ReadWriteHandler
*
handler
,
pcibus_t
addr
,
int
len
)
{
PCIHostState
*
s
=
opaque
;
PCIHostState
*
s
=
container_of
(
handler
,
PCIHostState
,
conf_noswap_handler
)
;
uint32_t
val
=
s
->
config_reg
;
PCI_DPRINTF
(
"%s addr
"
TARGET_FMT_plx
"
val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
val
);
PCI_DPRINTF
(
"%s addr
%"
FMT_PCIBUS
" len %d
val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
len
,
val
);
return
val
;
}
static
CPUWriteMemoryFunc
*
const
pci_host_config_write_noswap
[]
=
{
&
pci_host_config_writel_noswap
,
&
pci_host_config_writel_noswap
,
&
pci_host_config_writel_noswap
,
};
static
CPUReadMemoryFunc
*
const
pci_host_config_read_noswap
[]
=
{
&
pci_host_config_readl_noswap
,
&
pci_host_config_readl_noswap
,
&
pci_host_config_readl_noswap
,
};
int
pci_host_conf_register_mmio_noswap
(
PCIHostState
*
s
)
static
void
pci_host_data_write
(
ReadWriteHandler
*
handler
,
pcibus_t
addr
,
uint32_t
val
,
int
len
)
{
return
cpu_register_io_memory
(
pci_host_config_read_noswap
,
pci_host_config_write_noswap
,
s
);
PCIHostState
*
s
=
container_of
(
handler
,
PCIHostState
,
data_handler
);
#ifdef TARGET_WORDS_BIGENDIAN
val
=
qemu_bswap_len
(
val
,
len
);
#endif
PCI_DPRINTF
(
"write addr %"
FMT_PCIBUS
" len %d val %x
\n
"
,
addr
,
len
,
val
);
if
(
s
->
config_reg
&
(
1u
<<
31
))
pci_data_write
(
s
->
bus
,
s
->
config_reg
|
(
addr
&
3
),
val
,
len
);
}
static
void
pci_host_config_writel_ioport
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
val
)
static
uint32_t
pci_host_data_read
(
ReadWriteHandler
*
handler
,
pcibus_t
addr
,
int
len
)
{
PCIHostState
*
s
=
opaque
;
PCIHostState
*
s
=
container_of
(
handler
,
PCIHostState
,
data_handler
);
uint32_t
val
;
if
(
!
(
s
->
config_reg
&
(
1
<<
31
)))
return
0xffffffff
;
val
=
pci_data_read
(
s
->
bus
,
s
->
config_reg
|
(
addr
&
3
),
len
);
PCI_DPRINTF
(
"read addr %"
FMT_PCIBUS
" len %d val %x
\n
"
,
addr
,
len
,
val
);
#ifdef TARGET_WORDS_BIGENDIAN
val
=
qemu_bswap_len
(
val
,
len
);
#endif
return
val
;
}
PCI_DPRINTF
(
"%s addr %"
PRIx32
" val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
val
);
s
->
config_reg
=
val
;
static
void
pci_host_init
(
PCIHostState
*
s
)
{
s
->
conf_handler
.
write
=
pci_host_config_write
;
s
->
conf_handler
.
read
=
pci_host_config_read
;
s
->
conf_noswap_handler
.
write
=
pci_host_config_write_noswap
;
s
->
conf_noswap_handler
.
read
=
pci_host_config_read_noswap
;
s
->
data_handler
.
write
=
pci_host_data_write
;
s
->
data_handler
.
read
=
pci_host_data_read
;
}
static
uint32_t
pci_host_config_readl_ioport
(
void
*
opaque
,
uint32_t
addr
)
int
pci_host_conf_register_mmio
(
PCIHostState
*
s
)
{
PCIHostState
*
s
=
opaque
;
uint32_t
val
=
s
->
config_reg
;
pci_host_init
(
s
);
return
cpu_register_io_memory_simple
(
&
s
->
conf_handler
);
}
PCI_DPRINTF
(
"%s addr %"
PRIx32
" val %"
PRIx32
"
\n
"
,
__func__
,
addr
,
val
);
return
val
;
int
pci_host_conf_register_mmio_noswap
(
PCIHostState
*
s
)
{
pci_host_init
(
s
);
return
cpu_register_io_memory_simple
(
&
s
->
conf_noswap_handler
);
}
void
pci_host_conf_register_ioport
(
pio_addr_t
ioport
,
PCIHostState
*
s
)
{
register_ioport_write
(
ioport
,
4
,
4
,
pci_host_config_writel_ioport
,
s
);
register_ioport_
read
(
ioport
,
4
,
4
,
pci_host_config_readl_ioport
,
s
);
pci_host_init
(
s
);
register_ioport_
simple
(
&
s
->
conf_noswap_handler
,
ioport
,
4
,
4
);
}
#define PCI_ADDR_T target_phys_addr_t
#define PCI_HOST_SUFFIX _mmio
#include "pci_host_template.h"
static
CPUWriteMemoryFunc
*
const
pci_host_data_write_mmio
[]
=
{
pci_host_data_writeb_mmio
,
pci_host_data_writew_mmio
,
pci_host_data_writel_mmio
,
};
static
CPUReadMemoryFunc
*
const
pci_host_data_read_mmio
[]
=
{
pci_host_data_readb_mmio
,
pci_host_data_readw_mmio
,
pci_host_data_readl_mmio
,
};
int
pci_host_data_register_mmio
(
PCIHostState
*
s
)
{
return
cpu_register_io_memory
(
pci_host_data_read_mmio
,
pci_host_data_write_mmio
,
s
);
pci_host_init
(
s
);
return
cpu_register_io_memory_simple
(
&
s
->
data_handler
);
}
#undef PCI_ADDR_T
#undef PCI_HOST_SUFFIX
#define PCI_ADDR_T uint32_t
#define PCI_HOST_SUFFIX _ioport
#include "pci_host_template.h"
void
pci_host_data_register_ioport
(
pio_addr_t
ioport
,
PCIHostState
*
s
)
{
register_ioport_write
(
ioport
,
4
,
1
,
pci_host_data_writeb_ioport
,
s
);
register_ioport_write
(
ioport
,
4
,
2
,
pci_host_data_writew_ioport
,
s
);
register_ioport_write
(
ioport
,
4
,
4
,
pci_host_data_writel_ioport
,
s
);
register_ioport_read
(
ioport
,
4
,
1
,
pci_host_data_readb_ioport
,
s
);
register_ioport_read
(
ioport
,
4
,
2
,
pci_host_data_readw_ioport
,
s
);
register_ioport_read
(
ioport
,
4
,
4
,
pci_host_data_readl_ioport
,
s
);
pci_host_init
(
s
);
register_ioport_simple
(
&
s
->
data_handler
,
ioport
,
4
,
1
);
register_ioport_simple
(
&
s
->
data_handler
,
ioport
,
4
,
2
);
register_ioport_simple
(
&
s
->
data_handler
,
ioport
,
4
,
4
);
}
hw/pci_host.h
浏览文件 @
9edf5051
...
...
@@ -29,9 +29,13 @@
#define PCI_HOST_H
#include "sysbus.h"
#include "rwhandler.h"
struct
PCIHostState
{
SysBusDevice
busdev
;
ReadWriteHandler
conf_noswap_handler
;
ReadWriteHandler
conf_handler
;
ReadWriteHandler
data_handler
;
uint32_t
config_reg
;
PCIBus
*
bus
;
};
...
...
hw/pci_host_template.h
已删除
100644 → 0
浏览文件 @
2583ba97
/*
* QEMU Common PCI Host bridge configuration data space access routines.
*
* Copyright (c) 2006 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* Worker routines for a PCI host controller that uses an {address,data}
register pair to access PCI configuration space. */
static
void
glue
(
pci_host_data_writeb
,
PCI_HOST_SUFFIX
)(
void
*
opaque
,
PCI_ADDR_T
addr
,
uint32_t
val
)
{
PCIHostState
*
s
=
opaque
;
PCI_DPRINTF
(
"writeb addr "
TARGET_FMT_plx
" val %x
\n
"
,
(
target_phys_addr_t
)
addr
,
val
);
if
(
s
->
config_reg
&
(
1u
<<
31
))
pci_data_write
(
s
->
bus
,
s
->
config_reg
|
(
addr
&
3
),
val
,
1
);
}
static
void
glue
(
pci_host_data_writew
,
PCI_HOST_SUFFIX
)(
void
*
opaque
,
PCI_ADDR_T
addr
,
uint32_t
val
)
{
PCIHostState
*
s
=
opaque
;
#ifdef TARGET_WORDS_BIGENDIAN
val
=
bswap16
(
val
);
#endif
PCI_DPRINTF
(
"writew addr "
TARGET_FMT_plx
" val %x
\n
"
,
(
target_phys_addr_t
)
addr
,
val
);
if
(
s
->
config_reg
&
(
1u
<<
31
))
pci_data_write
(
s
->
bus
,
s
->
config_reg
|
(
addr
&
3
),
val
,
2
);
}
static
void
glue
(
pci_host_data_writel
,
PCI_HOST_SUFFIX
)(
void
*
opaque
,
PCI_ADDR_T
addr
,
uint32_t
val
)
{
PCIHostState
*
s
=
opaque
;
#ifdef TARGET_WORDS_BIGENDIAN
val
=
bswap32
(
val
);
#endif
PCI_DPRINTF
(
"writel addr "
TARGET_FMT_plx
" val %x
\n
"
,
(
target_phys_addr_t
)
addr
,
val
);
if
(
s
->
config_reg
&
(
1u
<<
31
))
pci_data_write
(
s
->
bus
,
s
->
config_reg
,
val
,
4
);
}
static
uint32_t
glue
(
pci_host_data_readb
,
PCI_HOST_SUFFIX
)(
void
*
opaque
,
PCI_ADDR_T
addr
)
{
PCIHostState
*
s
=
opaque
;
uint32_t
val
;
if
(
!
(
s
->
config_reg
&
(
1
<<
31
)))
return
0xff
;
val
=
pci_data_read
(
s
->
bus
,
s
->
config_reg
|
(
addr
&
3
),
1
);
PCI_DPRINTF
(
"readb addr "
TARGET_FMT_plx
" val %x
\n
"
,
(
target_phys_addr_t
)
addr
,
val
);
return
val
;
}
static
uint32_t
glue
(
pci_host_data_readw
,
PCI_HOST_SUFFIX
)(
void
*
opaque
,
PCI_ADDR_T
addr
)
{
PCIHostState
*
s
=
opaque
;
uint32_t
val
;
if
(
!
(
s
->
config_reg
&
(
1
<<
31
)))
return
0xffff
;
val
=
pci_data_read
(
s
->
bus
,
s
->
config_reg
|
(
addr
&
3
),
2
);
PCI_DPRINTF
(
"readw addr "
TARGET_FMT_plx
" val %x
\n
"
,
(
target_phys_addr_t
)
addr
,
val
);
#ifdef TARGET_WORDS_BIGENDIAN
val
=
bswap16
(
val
);
#endif
return
val
;
}
static
uint32_t
glue
(
pci_host_data_readl
,
PCI_HOST_SUFFIX
)(
void
*
opaque
,
PCI_ADDR_T
addr
)
{
PCIHostState
*
s
=
opaque
;
uint32_t
val
;
if
(
!
(
s
->
config_reg
&
(
1
<<
31
)))
return
0xffffffff
;
val
=
pci_data_read
(
s
->
bus
,
s
->
config_reg
|
(
addr
&
3
),
4
);
PCI_DPRINTF
(
"readl addr "
TARGET_FMT_plx
" val %x
\n
"
,
(
target_phys_addr_t
)
addr
,
val
);
#ifdef TARGET_WORDS_BIGENDIAN
val
=
bswap32
(
val
);
#endif
return
val
;
}
hw/pci_ids.h
浏览文件 @
9edf5051
...
...
@@ -63,6 +63,7 @@
#define PCI_VENDOR_ID_APPLE 0x106b
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020
#define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b
#define PCI_VENDOR_ID_SUN 0x108e
#define PCI_DEVICE_ID_SUN_EBUS 0x1000
...
...
hw/ppc.h
浏览文件 @
9edf5051
...
...
@@ -40,10 +40,12 @@ enum {
ARCH_PREP
=
0
,
ARCH_MAC99
,
ARCH_HEATHROW
,
ARCH_MAC99_U3
,
};
#define FW_CFG_PPC_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
#define FW_CFG_PPC_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
#define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02)
#define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03)
#define PPC_SERIAL_MM_BAUDBASE 399193
hw/ppc_mac.h
浏览文件 @
9edf5051
...
...
@@ -58,6 +58,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic);
/* UniNorth PCI */
PCIBus
*
pci_pmac_init
(
qemu_irq
*
pic
);
PCIBus
*
pci_pmac_u3_init
(
qemu_irq
*
pic
);
/* Mac NVRAM */
typedef
struct
MacIONVRAMState
MacIONVRAMState
;
...
...
hw/ppc_newworld.c
浏览文件 @
9edf5051
...
...
@@ -21,6 +21,30 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* PCI bus layout on a real G5 (U3 based):
*
* 0000:f0:0b.0 Host bridge [0600]: Apple Computer Inc. U3 AGP [106b:004b]
* 0000:f0:10.0 VGA compatible controller [0300]: ATI Technologies Inc RV350 AP [Radeon 9600] [1002:4150]
* 0001:00:00.0 Host bridge [0600]: Apple Computer Inc. CPC945 HT Bridge [106b:004a]
* 0001:00:01.0 PCI bridge [0604]: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge [1022:7450] (rev 12)
* 0001:00:02.0 PCI bridge [0604]: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge [1022:7450] (rev 12)
* 0001:00:03.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0045]
* 0001:00:04.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0046]
* 0001:00:05.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0047]
* 0001:00:06.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0048]
* 0001:00:07.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0049]
* 0001:01:07.0 Class [ff00]: Apple Computer Inc. K2 KeyLargo Mac/IO [106b:0041] (rev 20)
* 0001:01:08.0 USB Controller [0c03]: Apple Computer Inc. K2 KeyLargo USB [106b:0040]
* 0001:01:09.0 USB Controller [0c03]: Apple Computer Inc. K2 KeyLargo USB [106b:0040]
* 0001:02:0b.0 USB Controller [0c03]: NEC Corporation USB [1033:0035] (rev 43)
* 0001:02:0b.1 USB Controller [0c03]: NEC Corporation USB [1033:0035] (rev 43)
* 0001:02:0b.2 USB Controller [0c03]: NEC Corporation USB 2.0 [1033:00e0] (rev 04)
* 0001:03:0d.0 Class [ff00]: Apple Computer Inc. K2 ATA/100 [106b:0043]
* 0001:03:0e.0 FireWire (IEEE 1394) [0c00]: Apple Computer Inc. K2 FireWire [106b:0042]
* 0001:04:0f.0 Ethernet controller [0200]: Apple Computer Inc. K2 GMAC (Sun GEM) [106b:004c]
* 0001:05:0c.0 IDE interface [0101]: Broadcom K2 SATA [1166:0240]
*
*/
#include "hw.h"
#include "ppc.h"
...
...
@@ -40,6 +64,8 @@
#include "loader.h"
#include "elf.h"
#include "kvm.h"
#include "kvm_ppc.h"
#include "hw/usb.h"
#define MAX_IDE_BUS 2
#define VGA_BIOS_SIZE 65536
...
...
@@ -109,11 +135,13 @@ static void ppc_core99_init (ram_addr_t ram_size,
int
nvram_mem_index
;
int
vga_bios_size
,
bios_size
;
int
pic_mem_index
,
dbdma_mem_index
,
cuda_mem_index
,
escc_mem_index
;
int
ide_mem_index
[
3
];
int
ppc_boot_device
;
DriveInfo
*
hd
[
MAX_IDE_BUS
*
MAX_IDE_DEVS
];
void
*
fw_cfg
;
void
*
dbdma
;
uint8_t
*
vga_bios_ptr
;
int
machine_arch
;
linux_boot
=
(
kernel_filename
!=
NULL
);
...
...
@@ -317,7 +345,14 @@ static void ppc_core99_init (ram_addr_t ram_size,
}
}
pic
=
openpic_init
(
NULL
,
&
pic_mem_index
,
smp_cpus
,
openpic_irqs
,
NULL
);
pci_bus
=
pci_pmac_init
(
pic
);
if
(
PPC_INPUT
(
env
)
==
PPC_FLAGS_INPUT_970
)
{
/* 970 gets a U3 bus */
pci_bus
=
pci_pmac_u3_init
(
pic
);
machine_arch
=
ARCH_MAC99_U3
;
}
else
{
pci_bus
=
pci_pmac_init
(
pic
);
machine_arch
=
ARCH_MAC99
;
}
/* init basic PC hardware */
pci_vga_init
(
pci_bus
,
vga_bios_offset
,
vga_bios_size
);
...
...
@@ -331,27 +366,41 @@ static void ppc_core99_init (ram_addr_t ram_size,
fprintf
(
stderr
,
"qemu: too many IDE bus
\n
"
);
exit
(
1
);
}
for
(
i
=
0
;
i
<
MAX_IDE_BUS
*
MAX_IDE_DEVS
;
i
++
)
{
hd
[
i
]
=
drive_get
(
IF_IDE
,
i
/
MAX_IDE_DEVS
,
i
%
MAX_IDE_DEVS
);
}
dbdma
=
DBDMA_init
(
&
dbdma_mem_index
);
pci_cmd646_ide_init
(
pci_bus
,
hd
,
0
);
/* We only emulate 2 out of 3 IDE controllers for now */
ide_mem_index
[
0
]
=
-
1
;
hd
[
0
]
=
drive_get
(
IF_IDE
,
0
,
0
);
hd
[
1
]
=
drive_get
(
IF_IDE
,
0
,
1
);
ide_mem_index
[
1
]
=
pmac_ide_init
(
hd
,
pic
[
0x0d
],
dbdma
,
0x16
,
pic
[
0x02
]);
hd
[
0
]
=
drive_get
(
IF_IDE
,
1
,
0
);
hd
[
1
]
=
drive_get
(
IF_IDE
,
1
,
1
);
ide_mem_index
[
2
]
=
pmac_ide_init
(
hd
,
pic
[
0x0e
],
dbdma
,
0x1a
,
pic
[
0x02
]);
/* cuda also initialize ADB */
if
(
machine_arch
==
ARCH_MAC99_U3
)
{
usb_enabled
=
1
;
}
cuda_init
(
&
cuda_mem_index
,
pic
[
0x19
]);
adb_kbd_init
(
&
adb_bus
);
adb_mouse_init
(
&
adb_bus
);
macio_init
(
pci_bus
,
PCI_DEVICE_ID_APPLE_UNI_N_KEYL
,
0
,
pic_mem_index
,
dbdma_mem_index
,
cuda_mem_index
,
NULL
,
0
,
NULL
,
dbdma_mem_index
,
cuda_mem_index
,
NULL
,
3
,
ide_mem_index
,
escc_mem_index
);
if
(
usb_enabled
)
{
usb_ohci_init_pci
(
pci_bus
,
-
1
);
}
/* U3 needs to use USB for input because Linux doesn't support via-cuda
on PPC64 */
if
(
machine_arch
==
ARCH_MAC99_U3
)
{
usbdevice_create
(
"keyboard"
);
usbdevice_create
(
"mouse"
);
}
if
(
graphic_depth
!=
15
&&
graphic_depth
!=
32
&&
graphic_depth
!=
8
)
graphic_depth
=
15
;
...
...
@@ -364,7 +413,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
fw_cfg
=
fw_cfg_init
(
0
,
0
,
CFG_ADDR
,
CFG_ADDR
+
2
);
fw_cfg_add_i32
(
fw_cfg
,
FW_CFG_ID
,
1
);
fw_cfg_add_i64
(
fw_cfg
,
FW_CFG_RAM_SIZE
,
(
uint64_t
)
ram_size
);
fw_cfg_add_i16
(
fw_cfg
,
FW_CFG_MACHINE_ID
,
ARCH_MAC99
);
fw_cfg_add_i16
(
fw_cfg
,
FW_CFG_MACHINE_ID
,
machine_arch
);
fw_cfg_add_i32
(
fw_cfg
,
FW_CFG_KERNEL_ADDR
,
kernel_base
);
fw_cfg_add_i32
(
fw_cfg
,
FW_CFG_KERNEL_SIZE
,
kernel_size
);
if
(
kernel_cmdline
)
{
...
...
@@ -381,6 +430,14 @@ static void ppc_core99_init (ram_addr_t ram_size,
fw_cfg_add_i16
(
fw_cfg
,
FW_CFG_PPC_HEIGHT
,
graphic_height
);
fw_cfg_add_i16
(
fw_cfg
,
FW_CFG_PPC_DEPTH
,
graphic_depth
);
if
(
kvm_enabled
())
{
#ifdef CONFIG_KVM
fw_cfg_add_i32
(
fw_cfg
,
FW_CFG_PPC_TBFREQ
,
kvmppc_get_tbfreq
());
#endif
}
else
{
fw_cfg_add_i32
(
fw_cfg
,
FW_CFG_PPC_TBFREQ
,
get_ticks_per_sec
());
}
qemu_register_boot_set
(
fw_cfg_boot_set
,
fw_cfg
);
}
...
...
hw/ppc_oldworld.c
浏览文件 @
9edf5051
...
...
@@ -40,6 +40,7 @@
#include "loader.h"
#include "elf.h"
#include "kvm.h"
#include "kvm_ppc.h"
#define MAX_IDE_BUS 2
#define VGA_BIOS_SIZE 65536
...
...
@@ -401,6 +402,14 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
fw_cfg_add_i16
(
fw_cfg
,
FW_CFG_PPC_HEIGHT
,
graphic_height
);
fw_cfg_add_i16
(
fw_cfg
,
FW_CFG_PPC_DEPTH
,
graphic_depth
);
if
(
kvm_enabled
())
{
#ifdef CONFIG_KVM
fw_cfg_add_i32
(
fw_cfg
,
FW_CFG_PPC_TBFREQ
,
kvmppc_get_tbfreq
());
#endif
}
else
{
fw_cfg_add_i32
(
fw_cfg
,
FW_CFG_PPC_TBFREQ
,
get_ticks_per_sec
());
}
qemu_register_boot_set
(
fw_cfg_boot_set
,
fw_cfg
);
}
...
...
hw/unin_pci.c
浏览文件 @
9edf5051
...
...
@@ -36,22 +36,31 @@
#define UNIN_DPRINTF(fmt, ...)
#endif
static
const
int
unin_irq_line
[]
=
{
0x1b
,
0x1c
,
0x1d
,
0x1e
};
typedef
struct
UNINState
{
SysBusDevice
busdev
;
PCIHostState
host_state
;
ReadWriteHandler
data_handler
;
}
UNINState
;
/* Don't know if this matches real hardware, but it agrees with OHW. */
static
int
pci_unin_map_irq
(
PCIDevice
*
pci_dev
,
int
irq_num
)
{
return
(
irq_num
+
(
pci_dev
->
devfn
>>
3
))
&
3
;
int
retval
;
int
devfn
=
pci_dev
->
devfn
&
0x00FFFFFF
;
retval
=
(((
devfn
>>
11
)
&
0x1F
)
+
irq_num
)
&
3
;
return
retval
;
}
static
void
pci_unin_set_irq
(
void
*
opaque
,
int
irq_num
,
int
level
)
{
qemu_irq
*
pic
=
opaque
;
qemu_set_irq
(
pic
[
irq_num
+
8
],
level
);
UNIN_DPRINTF
(
"%s: setting INT %d = %d
\n
"
,
__func__
,
unin_irq_line
[
irq_num
],
level
);
qemu_set_irq
(
pic
[
unin_irq_line
[
irq_num
]],
level
);
}
static
void
pci_unin_save
(
QEMUFile
*
f
,
void
*
opaque
)
...
...
@@ -75,6 +84,68 @@ static void pci_unin_reset(void *opaque)
{
}
static
uint32_t
unin_get_config_reg
(
uint32_t
reg
,
uint32_t
addr
)
{
uint32_t
retval
;
if
(
reg
&
(
1u
<<
31
))
{
/* XXX OpenBIOS compatibility hack */
retval
=
reg
|
(
addr
&
3
);
}
else
if
(
reg
&
1
)
{
/* CFA1 style */
retval
=
(
reg
&
~
7u
)
|
(
addr
&
7
);
}
else
{
uint32_t
slot
,
func
;
/* Grab CFA0 style values */
slot
=
ffs
(
reg
&
0xfffff800
)
-
1
;
func
=
(
reg
>>
8
)
&
7
;
/* ... and then convert them to x86 format */
/* config pointer */
retval
=
(
reg
&
(
0xff
-
7
))
|
(
addr
&
7
);
/* slot */
retval
|=
slot
<<
11
;
/* fn */
retval
|=
func
<<
8
;
}
UNIN_DPRINTF
(
"Converted config space accessor %08x/%08x -> %08x
\n
"
,
reg
,
addr
,
retval
);
return
retval
;
}
static
void
unin_data_write
(
ReadWriteHandler
*
handler
,
pcibus_t
addr
,
uint32_t
val
,
int
len
)
{
UNINState
*
s
=
container_of
(
handler
,
UNINState
,
data_handler
);
#ifdef TARGET_WORDS_BIGENDIAN
val
=
qemu_bswap_len
(
val
,
len
);
#endif
UNIN_DPRINTF
(
"write addr %"
FMT_PCIBUS
" len %d val %x
\n
"
,
addr
,
len
,
val
);
pci_data_write
(
s
->
host_state
.
bus
,
unin_get_config_reg
(
s
->
host_state
.
config_reg
,
addr
),
val
,
len
);
}
static
uint32_t
unin_data_read
(
ReadWriteHandler
*
handler
,
pcibus_t
addr
,
int
len
)
{
UNINState
*
s
=
container_of
(
handler
,
UNINState
,
data_handler
);
uint32_t
val
;
val
=
pci_data_read
(
s
->
host_state
.
bus
,
unin_get_config_reg
(
s
->
host_state
.
config_reg
,
addr
),
len
);
UNIN_DPRINTF
(
"read addr %"
FMT_PCIBUS
" len %d val %x
\n
"
,
addr
,
len
,
val
);
#ifdef TARGET_WORDS_BIGENDIAN
val
=
qemu_bswap_len
(
val
,
len
);
#endif
return
val
;
}
static
int
pci_unin_main_init_device
(
SysBusDevice
*
dev
)
{
UNINState
*
s
;
...
...
@@ -85,7 +156,9 @@ static int pci_unin_main_init_device(SysBusDevice *dev)
s
=
FROM_SYSBUS
(
UNINState
,
dev
);
pci_mem_config
=
pci_host_conf_register_mmio
(
&
s
->
host_state
);
pci_mem_data
=
pci_host_data_register_mmio
(
&
s
->
host_state
);
s
->
data_handler
.
read
=
unin_data_read
;
s
->
data_handler
.
write
=
unin_data_write
;
pci_mem_data
=
cpu_register_io_memory_simple
(
&
s
->
data_handler
);
sysbus_init_mmio
(
dev
,
0x1000
,
pci_mem_config
);
sysbus_init_mmio
(
dev
,
0x1000
,
pci_mem_data
);
...
...
@@ -94,6 +167,27 @@ static int pci_unin_main_init_device(SysBusDevice *dev)
return
0
;
}
static
int
pci_u3_agp_init_device
(
SysBusDevice
*
dev
)
{
UNINState
*
s
;
int
pci_mem_config
,
pci_mem_data
;
/* Uninorth U3 AGP bus */
s
=
FROM_SYSBUS
(
UNINState
,
dev
);
pci_mem_config
=
pci_host_conf_register_mmio
(
&
s
->
host_state
);
s
->
data_handler
.
read
=
unin_data_read
;
s
->
data_handler
.
write
=
unin_data_write
;
pci_mem_data
=
cpu_register_io_memory_simple
(
&
s
->
data_handler
);
sysbus_init_mmio
(
dev
,
0x1000
,
pci_mem_config
);
sysbus_init_mmio
(
dev
,
0x1000
,
pci_mem_data
);
register_savevm
(
"uninorth"
,
0
,
1
,
pci_unin_save
,
pci_unin_load
,
&
s
->
host_state
);
qemu_register_reset
(
pci_unin_reset
,
&
s
->
host_state
);
return
0
;
}
static
int
pci_unin_agp_init_device
(
SysBusDevice
*
dev
)
{
UNINState
*
s
;
...
...
@@ -175,6 +269,31 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
return
d
->
host_state
.
bus
;
}
PCIBus
*
pci_pmac_u3_init
(
qemu_irq
*
pic
)
{
DeviceState
*
dev
;
SysBusDevice
*
s
;
UNINState
*
d
;
/* Uninorth AGP bus */
dev
=
qdev_create
(
NULL
,
"u3-agp"
);
qdev_init_nofail
(
dev
);
s
=
sysbus_from_qdev
(
dev
);
d
=
FROM_SYSBUS
(
UNINState
,
s
);
d
->
host_state
.
bus
=
pci_register_bus
(
&
d
->
busdev
.
qdev
,
"pci"
,
pci_unin_set_irq
,
pci_unin_map_irq
,
pic
,
11
<<
3
,
4
);
sysbus_mmio_map
(
s
,
0
,
0xf0800000
);
sysbus_mmio_map
(
s
,
1
,
0xf0c00000
);
pci_create_simple
(
d
->
host_state
.
bus
,
11
<<
3
,
"u3-agp"
);
return
d
->
host_state
.
bus
;
}
static
int
unin_main_pci_host_init
(
PCIDevice
*
d
)
{
pci_config_set_vendor_id
(
d
->
config
,
PCI_VENDOR_ID_APPLE
);
...
...
@@ -201,6 +320,21 @@ static int unin_agp_pci_host_init(PCIDevice *d)
return
0
;
}
static
int
u3_agp_pci_host_init
(
PCIDevice
*
d
)
{
pci_config_set_vendor_id
(
d
->
config
,
PCI_VENDOR_ID_APPLE
);
pci_config_set_device_id
(
d
->
config
,
PCI_DEVICE_ID_APPLE_U3_AGP
);
/* revision */
d
->
config
[
0x08
]
=
0x00
;
pci_config_set_class
(
d
->
config
,
PCI_CLASS_BRIDGE_HOST
);
/* cache line size */
d
->
config
[
0x0C
]
=
0x08
;
/* latency timer */
d
->
config
[
0x0D
]
=
0x10
;
d
->
config
[
PCI_HEADER_TYPE
]
=
PCI_HEADER_TYPE_NORMAL
;
return
0
;
}
static
int
unin_internal_pci_host_init
(
PCIDevice
*
d
)
{
pci_config_set_vendor_id
(
d
->
config
,
PCI_VENDOR_ID_APPLE
);
...
...
@@ -220,6 +354,12 @@ static PCIDeviceInfo unin_main_pci_host_info = {
.
init
=
unin_main_pci_host_init
,
};
static
PCIDeviceInfo
u3_agp_pci_host_info
=
{
.
qdev
.
name
=
"u3-agp"
,
.
qdev
.
size
=
sizeof
(
PCIDevice
),
.
init
=
u3_agp_pci_host_init
,
};
static
PCIDeviceInfo
unin_agp_pci_host_info
=
{
.
qdev
.
name
=
"uni-north-agp"
,
.
qdev
.
size
=
sizeof
(
PCIDevice
),
...
...
@@ -237,6 +377,9 @@ static void unin_register_devices(void)
sysbus_register_dev
(
"uni-north"
,
sizeof
(
UNINState
),
pci_unin_main_init_device
);
pci_qdev_register
(
&
unin_main_pci_host_info
);
sysbus_register_dev
(
"u3-agp"
,
sizeof
(
UNINState
),
pci_u3_agp_init_device
);
pci_qdev_register
(
&
u3_agp_pci_host_info
);
sysbus_register_dev
(
"uni-north-agp"
,
sizeof
(
UNINState
),
pci_unin_agp_init_device
);
pci_qdev_register
(
&
unin_agp_pci_host_info
);
...
...
hw/versatile_pci.c
浏览文件 @
9edf5051
...
...
@@ -147,14 +147,10 @@ static int versatile_pci_host_init(PCIDevice *d)
pci_config_set_vendor_id
(
d
->
config
,
PCI_VENDOR_ID_XILINX
);
/* Both boards have the same device ID. Oh well. */
pci_config_set_device_id
(
d
->
config
,
PCI_DEVICE_ID_XILINX_XC2VP30
);
d
->
config
[
0x04
]
=
0x00
;
d
->
config
[
0x05
]
=
0x00
;
d
->
config
[
0x06
]
=
0x20
;
d
->
config
[
0x07
]
=
0x02
;
d
->
config
[
0x08
]
=
0x00
;
// revision
d
->
config
[
0x09
]
=
0x00
;
// programming i/f
pci_set_word
(
d
->
config
+
PCI_STATUS
,
PCI_STATUS_66MHZ
|
PCI_STATUS_DEVSEL_MEDIUM
);
pci_config_set_class
(
d
->
config
,
PCI_CLASS_PROCESSOR_CO
);
d
->
config
[
0x0D
]
=
0x10
;
// latency_timer
pci_set_byte
(
d
->
config
+
PCI_LATENCY_TIMER
,
0x10
);
return
0
;
}
...
...
qemu-common.h
浏览文件 @
9edf5051
...
...
@@ -227,6 +227,8 @@ typedef struct I2SCodec I2SCodec;
typedef
struct
DeviceState
DeviceState
;
typedef
struct
SSIBus
SSIBus
;
typedef
uint64_t
pcibus_t
;
/* CPU save/load. */
void
cpu_save
(
QEMUFile
*
f
,
void
*
opaque
);
int
cpu_load
(
QEMUFile
*
f
,
void
*
opaque
,
int
version_id
);
...
...
rwhandler.c
0 → 100644
浏览文件 @
9edf5051
#include "rwhandler.h"
#include "ioport.h"
#include "cpu-all.h"
#if !defined(CONFIG_USER_ONLY)
#define RWHANDLER_WRITE(name, len, type) \
static void name(void *opaque, type addr, uint32_t value) \
{\
struct ReadWriteHandler *handler = opaque;\
handler->write(handler, addr, value, len);\
}
#define RWHANDLER_READ(name, len, type) \
static uint32_t name(void *opaque, type addr) \
{ \
struct ReadWriteHandler *handler = opaque; \
return handler->read(handler, addr, len); \
}
RWHANDLER_WRITE
(
cpu_io_memory_simple_writeb
,
1
,
target_phys_addr_t
);
RWHANDLER_READ
(
cpu_io_memory_simple_readb
,
1
,
target_phys_addr_t
);
RWHANDLER_WRITE
(
cpu_io_memory_simple_writew
,
2
,
target_phys_addr_t
);
RWHANDLER_READ
(
cpu_io_memory_simple_readw
,
2
,
target_phys_addr_t
);
RWHANDLER_WRITE
(
cpu_io_memory_simple_writel
,
4
,
target_phys_addr_t
);
RWHANDLER_READ
(
cpu_io_memory_simple_readl
,
4
,
target_phys_addr_t
);
static
CPUWriteMemoryFunc
*
const
cpu_io_memory_simple_write
[]
=
{
&
cpu_io_memory_simple_writeb
,
&
cpu_io_memory_simple_writew
,
&
cpu_io_memory_simple_writel
,
};
static
CPUReadMemoryFunc
*
const
cpu_io_memory_simple_read
[]
=
{
&
cpu_io_memory_simple_readb
,
&
cpu_io_memory_simple_readw
,
&
cpu_io_memory_simple_readl
,
};
int
cpu_register_io_memory_simple
(
struct
ReadWriteHandler
*
handler
)
{
if
(
!
handler
->
read
||
!
handler
->
write
)
{
return
-
1
;
}
return
cpu_register_io_memory
(
cpu_io_memory_simple_read
,
cpu_io_memory_simple_write
,
handler
);
}
RWHANDLER_WRITE
(
ioport_simple_writeb
,
1
,
uint32_t
);
RWHANDLER_READ
(
ioport_simple_readb
,
1
,
uint32_t
);
RWHANDLER_WRITE
(
ioport_simple_writew
,
2
,
uint32_t
);
RWHANDLER_READ
(
ioport_simple_readw
,
2
,
uint32_t
);
RWHANDLER_WRITE
(
ioport_simple_writel
,
4
,
uint32_t
);
RWHANDLER_READ
(
ioport_simple_readl
,
4
,
uint32_t
);
int
register_ioport_simple
(
ReadWriteHandler
*
handler
,
pio_addr_t
start
,
int
length
,
int
size
)
{
IOPortWriteFunc
*
write
;
IOPortReadFunc
*
read
;
int
r
;
switch
(
size
)
{
case
1
:
write
=
ioport_simple_writeb
;
read
=
ioport_simple_readb
;
break
;
case
2
:
write
=
ioport_simple_writew
;
read
=
ioport_simple_readw
;
break
;
default:
write
=
ioport_simple_writel
;
read
=
ioport_simple_readl
;
}
if
(
handler
->
write
)
{
r
=
register_ioport_write
(
start
,
length
,
size
,
write
,
handler
);
if
(
r
<
0
)
{
return
r
;
}
}
if
(
handler
->
read
)
{
r
=
register_ioport_read
(
start
,
length
,
size
,
read
,
handler
);
if
(
r
<
0
)
{
return
r
;
}
}
return
0
;
}
#endif
rwhandler.h
0 → 100644
浏览文件 @
9edf5051
#ifndef READ_WRITE_HANDLER_H
#define READ_WRITE_HANDLER_H
#include "qemu-common.h"
#include "ioport.h"
typedef
struct
ReadWriteHandler
ReadWriteHandler
;
/* len is guaranteed to be one of 1, 2 or 4, addr is guaranteed to fit in an
* appropriate type (io/memory/etc). They do not need to be range checked. */
typedef
void
WriteHandlerFunc
(
ReadWriteHandler
*
,
pcibus_t
addr
,
uint32_t
value
,
int
len
);
typedef
uint32_t
ReadHandlerFunc
(
ReadWriteHandler
*
,
pcibus_t
addr
,
int
len
);
struct
ReadWriteHandler
{
WriteHandlerFunc
*
write
;
ReadHandlerFunc
*
read
;
};
/* Helpers for when we want to use a single routine with length. */
/* CPU memory handler: both read and write must be present. */
int
cpu_register_io_memory_simple
(
ReadWriteHandler
*
);
/* io port handler: can supply only read or write handlers. */
int
register_ioport_simple
(
ReadWriteHandler
*
,
pio_addr_t
start
,
int
length
,
int
size
);
#endif
target-ppc/helper.c
浏览文件 @
9edf5051
...
...
@@ -736,14 +736,13 @@ static inline int slb_lookup(CPUPPCState *env, target_ulong eaddr,
PRIx32
"
\n
"
,
__func__
,
n
,
slb
->
tmp64
,
slb
->
tmp
);
if
(
slb_is_valid
(
slb
))
{
/* SLB entry is valid */
mask
=
0xFFFFFFFFF0000000ULL
;
if
(
slb
->
tmp
&
0x8
)
{
/* 1 TB Segment */
mask
=
0xFFFF000000000000ULL
;
/* 16 MB PTEs */
if
(
target_page_bits
)
*
target_page_bits
=
24
;
// XXX 16M pages?
*
target_page_bits
=
24
;
}
else
{
/* 256MB Segment */
mask
=
0xFFFFFFFFF0000000ULL
;
/* 4 KB PTEs */
if
(
target_page_bits
)
*
target_page_bits
=
TARGET_PAGE_BITS
;
}
...
...
target-ppc/kvm.c
浏览文件 @
9edf5051
...
...
@@ -37,6 +37,22 @@
do { } while (0)
#endif
/* XXX For some odd reason we sometimes hang inside KVM forever. I'd guess it's
* a race condition where we actually have a level triggered interrupt, but
* the infrastructure can't expose that yet, so the guest ACKs it, goes to
* sleep and never gets notified that there's still an interrupt pending.
*
* As a quick workaround, let's just wake up every 500 ms. That way we can
* assure that we're always reinjecting interrupts in time.
*/
static
QEMUTimer
*
idle_timer
;
static
void
do_nothing
(
void
*
opaque
)
{
qemu_mod_timer
(
idle_timer
,
qemu_get_clock
(
vm_clock
)
+
(
get_ticks_per_sec
()
/
2
));
}
int
kvm_arch_init
(
KVMState
*
s
,
int
smp_cpus
)
{
return
0
;
...
...
@@ -173,6 +189,12 @@ int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
int
r
;
unsigned
irq
;
if
(
!
idle_timer
)
{
idle_timer
=
qemu_new_timer
(
vm_clock
,
do_nothing
,
NULL
);
qemu_mod_timer
(
idle_timer
,
qemu_get_clock
(
vm_clock
)
+
(
get_ticks_per_sec
()
/
2
));
}
/* 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
&&
...
...
@@ -252,3 +274,50 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
return
ret
;
}
static
int
read_cpuinfo
(
const
char
*
field
,
char
*
value
,
int
len
)
{
FILE
*
f
;
int
ret
=
-
1
;
int
field_len
=
strlen
(
field
);
char
line
[
512
];
f
=
fopen
(
"/proc/cpuinfo"
,
"r"
);
if
(
!
f
)
{
return
-
1
;
}
do
{
if
(
!
fgets
(
line
,
sizeof
(
line
),
f
))
{
break
;
}
if
(
!
strncmp
(
line
,
field
,
field_len
))
{
strncpy
(
value
,
line
,
len
);
ret
=
0
;
break
;
}
}
while
(
*
line
);
fclose
(
f
);
return
ret
;
}
uint32_t
kvmppc_get_tbfreq
(
void
)
{
char
line
[
512
];
char
*
ns
;
uint32_t
retval
=
get_ticks_per_sec
();
if
(
read_cpuinfo
(
"timebase"
,
line
,
sizeof
(
line
)))
{
return
retval
;
}
if
(
!
(
ns
=
strchr
(
line
,
':'
)))
{
return
retval
;
}
ns
++
;
retval
=
atoi
(
ns
);
return
retval
;
}
target-ppc/kvm_ppc.h
浏览文件 @
9edf5051
...
...
@@ -14,4 +14,6 @@ void kvmppc_fdt_update(void *fdt);
int
kvmppc_read_host_property
(
const
char
*
node_path
,
const
char
*
prop
,
void
*
val
,
size_t
len
);
uint32_t
kvmppc_get_tbfreq
(
void
);
#endif
/* __KVM_PPC_H__ */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录