Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
f1a7104a
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看板
提交
f1a7104a
编写于
8月 21, 2011
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'pmaydell/armhw-for-upstream' into staging
上级
957f1f99
dc804ab7
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
415 addition
and
136 deletion
+415
-136
hw/arm_sysctl.c
hw/arm_sysctl.c
+46
-3
hw/pl061.c
hw/pl061.c
+86
-95
hw/pl110.c
hw/pl110.c
+96
-19
hw/pl110_template.h
hw/pl110_template.h
+95
-7
hw/realview.c
hw/realview.c
+1
-1
hw/stellaris.c
hw/stellaris.c
+68
-4
hw/syborg_fb.c
hw/syborg_fb.c
+12
-3
hw/versatilepb.c
hw/versatilepb.c
+10
-3
hw/vexpress.c
hw/vexpress.c
+1
-1
未找到文件。
hw/arm_sysctl.c
浏览文件 @
f1a7104a
...
...
@@ -17,6 +17,8 @@
typedef
struct
{
SysBusDevice
busdev
;
qemu_irq
pl110_mux_ctrl
;
uint32_t
sys_id
;
uint32_t
leds
;
uint16_t
lockval
;
...
...
@@ -30,11 +32,12 @@ typedef struct {
uint32_t
sys_cfgdata
;
uint32_t
sys_cfgctrl
;
uint32_t
sys_cfgstat
;
uint32_t
sys_clcd
;
}
arm_sysctl_state
;
static
const
VMStateDescription
vmstate_arm_sysctl
=
{
.
name
=
"realview_sysctl"
,
.
version_id
=
2
,
.
version_id
=
3
,
.
minimum_version_id
=
1
,
.
fields
=
(
VMStateField
[])
{
VMSTATE_UINT32
(
leds
,
arm_sysctl_state
),
...
...
@@ -48,6 +51,7 @@ static const VMStateDescription vmstate_arm_sysctl = {
VMSTATE_UINT32_V
(
sys_cfgdata
,
arm_sysctl_state
,
2
),
VMSTATE_UINT32_V
(
sys_cfgctrl
,
arm_sysctl_state
,
2
),
VMSTATE_UINT32_V
(
sys_cfgstat
,
arm_sysctl_state
,
2
),
VMSTATE_UINT32_V
(
sys_clcd
,
arm_sysctl_state
,
3
),
VMSTATE_END_OF_LIST
()
}
};
...
...
@@ -78,6 +82,13 @@ static void arm_sysctl_reset(DeviceState *d)
s
->
cfgdata2
=
0
;
s
->
flags
=
0
;
s
->
resetlevel
=
0
;
if
(
board_id
(
s
)
==
BOARD_ID_VEXPRESS
)
{
/* On VExpress this register will RAZ/WI */
s
->
sys_clcd
=
0
;
}
else
{
/* All others: CLCDID 0x1f, indicating VGA */
s
->
sys_clcd
=
0x1f00
;
}
}
static
uint32_t
arm_sysctl_read
(
void
*
opaque
,
target_phys_addr_t
offset
)
...
...
@@ -124,7 +135,7 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
case
0x4c
:
/* FLASH */
return
0
;
case
0x50
:
/* CLCD */
return
0x1000
;
return
s
->
sys_clcd
;
case
0x54
:
/* CLCDSER */
return
0
;
case
0x58
:
/* BOOTCS */
...
...
@@ -232,7 +243,39 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
/* nothing to do. */
break
;
case
0x4c
:
/* FLASH */
break
;
case
0x50
:
/* CLCD */
switch
(
board_id
(
s
))
{
case
BOARD_ID_PB926
:
/* On 926 bits 13:8 are R/O, bits 1:0 control
* the mux that defines how to interpret the PL110
* graphics format, and other bits are r/w but we
* don't implement them to do anything.
*/
s
->
sys_clcd
&=
0x3f00
;
s
->
sys_clcd
|=
val
&
~
0x3f00
;
qemu_set_irq
(
s
->
pl110_mux_ctrl
,
val
&
3
);
break
;
case
BOARD_ID_EB
:
/* The EB is the same except that there is no mux since
* the EB has a PL111.
*/
s
->
sys_clcd
&=
0x3f00
;
s
->
sys_clcd
|=
val
&
~
0x3f00
;
break
;
case
BOARD_ID_PBA8
:
case
BOARD_ID_PBX
:
/* On PBA8 and PBX bit 7 is r/w and all other bits
* are either r/o or RAZ/WI.
*/
s
->
sys_clcd
&=
(
1
<<
7
);
s
->
sys_clcd
|=
val
&
~
(
1
<<
7
);
break
;
case
BOARD_ID_VEXPRESS
:
default:
/* On VExpress this register is unimplemented and will RAZ/WI */
break
;
}
case
0x54
:
/* CLCDSER */
case
0x64
:
/* DMAPSR0 */
case
0x68
:
/* DMAPSR1 */
...
...
@@ -334,7 +377,7 @@ static int arm_sysctl_init1(SysBusDevice *dev)
DEVICE_NATIVE_ENDIAN
);
sysbus_init_mmio
(
dev
,
0x1000
,
iomemtype
);
qdev_init_gpio_in
(
&
s
->
busdev
.
qdev
,
arm_sysctl_gpio_set
,
2
);
/* ??? Save/restore. */
qdev_init_gpio_out
(
&
s
->
busdev
.
qdev
,
&
s
->
pl110_mux_ctrl
,
1
);
return
0
;
}
...
...
hw/pl061.c
浏览文件 @
f1a7104a
...
...
@@ -30,31 +30,62 @@ static const uint8_t pl061_id_luminary[12] =
typedef
struct
{
SysBusDevice
busdev
;
int
locked
;
uint8_t
data
;
uint8_t
old_data
;
uint8_t
dir
;
uint8_t
isense
;
uint8_t
ibe
;
uint8_t
iev
;
uint8_t
im
;
uint8_t
istate
;
uint8_t
afsel
;
uint8_t
dr2r
;
uint8_t
dr4r
;
uint8_t
dr8r
;
uint8_t
odr
;
uint8_t
pur
;
uint8_t
pdr
;
uint8_t
slr
;
uint8_t
den
;
uint8_t
cr
;
uint8_t
float_high
;
uint32_t
locked
;
uint32_t
data
;
uint32_t
old_data
;
uint32_t
dir
;
uint32_t
isense
;
uint32_t
ibe
;
uint32_t
iev
;
uint32_t
im
;
uint32_t
istate
;
uint32_t
afsel
;
uint32_t
dr2r
;
uint32_t
dr4r
;
uint32_t
dr8r
;
uint32_t
odr
;
uint32_t
pur
;
uint32_t
pdr
;
uint32_t
slr
;
uint32_t
den
;
uint32_t
cr
;
uint32_t
float_high
;
uint32_t
amsel
;
qemu_irq
irq
;
qemu_irq
out
[
8
];
const
unsigned
char
*
id
;
}
pl061_state
;
static
const
VMStateDescription
vmstate_pl061
=
{
.
name
=
"pl061"
,
.
version_id
=
2
,
.
minimum_version_id
=
1
,
.
fields
=
(
VMStateField
[])
{
VMSTATE_UINT32
(
locked
,
pl061_state
),
VMSTATE_UINT32
(
data
,
pl061_state
),
VMSTATE_UINT32
(
old_data
,
pl061_state
),
VMSTATE_UINT32
(
dir
,
pl061_state
),
VMSTATE_UINT32
(
isense
,
pl061_state
),
VMSTATE_UINT32
(
ibe
,
pl061_state
),
VMSTATE_UINT32
(
iev
,
pl061_state
),
VMSTATE_UINT32
(
im
,
pl061_state
),
VMSTATE_UINT32
(
istate
,
pl061_state
),
VMSTATE_UINT32
(
afsel
,
pl061_state
),
VMSTATE_UINT32
(
dr2r
,
pl061_state
),
VMSTATE_UINT32
(
dr4r
,
pl061_state
),
VMSTATE_UINT32
(
dr8r
,
pl061_state
),
VMSTATE_UINT32
(
odr
,
pl061_state
),
VMSTATE_UINT32
(
pur
,
pl061_state
),
VMSTATE_UINT32
(
pdr
,
pl061_state
),
VMSTATE_UINT32
(
slr
,
pl061_state
),
VMSTATE_UINT32
(
den
,
pl061_state
),
VMSTATE_UINT32
(
cr
,
pl061_state
),
VMSTATE_UINT32
(
float_high
,
pl061_state
),
VMSTATE_UINT32_V
(
amsel
,
pl061_state
,
2
),
VMSTATE_END_OF_LIST
()
}
};
static
void
pl061_update
(
pl061_state
*
s
)
{
uint8_t
changed
;
...
...
@@ -128,6 +159,8 @@ static uint32_t pl061_read(void *opaque, target_phys_addr_t offset)
return
s
->
locked
;
case
0x524
:
/* Commit */
return
s
->
cr
;
case
0x528
:
/* Analog mode select */
return
s
->
amsel
;
default:
hw_error
(
"pl061_read: Bad offset %x
\n
"
,
(
int
)
offset
);
return
0
;
...
...
@@ -148,19 +181,19 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
}
switch
(
offset
)
{
case
0x400
:
/* Direction */
s
->
dir
=
value
;
s
->
dir
=
value
&
0xff
;
break
;
case
0x404
:
/* Interrupt sense */
s
->
isense
=
value
;
s
->
isense
=
value
&
0xff
;
break
;
case
0x408
:
/* Interrupt both edges */
s
->
ibe
=
value
;
s
->
ibe
=
value
&
0xff
;
break
;
case
0x40c
:
/* Interrupt event */
s
->
iev
=
value
;
s
->
iev
=
value
&
0xff
;
break
;
case
0x410
:
/* Interrupt mask */
s
->
im
=
value
;
s
->
im
=
value
&
0xff
;
break
;
case
0x41c
:
/* Interrupt clear */
s
->
istate
&=
~
value
;
...
...
@@ -170,35 +203,38 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
s
->
afsel
=
(
s
->
afsel
&
~
mask
)
|
(
value
&
mask
);
break
;
case
0x500
:
/* 2mA drive */
s
->
dr2r
=
value
;
s
->
dr2r
=
value
&
0xff
;
break
;
case
0x504
:
/* 4mA drive */
s
->
dr4r
=
value
;
s
->
dr4r
=
value
&
0xff
;
break
;
case
0x508
:
/* 8mA drive */
s
->
dr8r
=
value
;
s
->
dr8r
=
value
&
0xff
;
break
;
case
0x50c
:
/* Open drain */
s
->
odr
=
value
;
s
->
odr
=
value
&
0xff
;
break
;
case
0x510
:
/* Pull-up */
s
->
pur
=
value
;
s
->
pur
=
value
&
0xff
;
break
;
case
0x514
:
/* Pull-down */
s
->
pdr
=
value
;
s
->
pdr
=
value
&
0xff
;
break
;
case
0x518
:
/* Slew rate control */
s
->
slr
=
value
;
s
->
slr
=
value
&
0xff
;
break
;
case
0x51c
:
/* Digital enable */
s
->
den
=
value
;
s
->
den
=
value
&
0xff
;
break
;
case
0x520
:
/* Lock */
s
->
locked
=
(
value
!=
0xacce551
);
break
;
case
0x524
:
/* Commit */
if
(
!
s
->
locked
)
s
->
cr
=
value
;
s
->
cr
=
value
&
0xff
;
break
;
case
0x528
:
s
->
amsel
=
value
&
0xff
;
break
;
default:
hw_error
(
"pl061_write: Bad offset %x
\n
"
,
(
int
)
offset
);
...
...
@@ -238,62 +274,6 @@ static CPUWriteMemoryFunc * const pl061_writefn[] = {
pl061_write
};
static
void
pl061_save
(
QEMUFile
*
f
,
void
*
opaque
)
{
pl061_state
*
s
=
(
pl061_state
*
)
opaque
;
qemu_put_be32
(
f
,
s
->
locked
);
qemu_put_be32
(
f
,
s
->
data
);
qemu_put_be32
(
f
,
s
->
old_data
);
qemu_put_be32
(
f
,
s
->
dir
);
qemu_put_be32
(
f
,
s
->
isense
);
qemu_put_be32
(
f
,
s
->
ibe
);
qemu_put_be32
(
f
,
s
->
iev
);
qemu_put_be32
(
f
,
s
->
im
);
qemu_put_be32
(
f
,
s
->
istate
);
qemu_put_be32
(
f
,
s
->
afsel
);
qemu_put_be32
(
f
,
s
->
dr2r
);
qemu_put_be32
(
f
,
s
->
dr4r
);
qemu_put_be32
(
f
,
s
->
dr8r
);
qemu_put_be32
(
f
,
s
->
odr
);
qemu_put_be32
(
f
,
s
->
pur
);
qemu_put_be32
(
f
,
s
->
pdr
);
qemu_put_be32
(
f
,
s
->
slr
);
qemu_put_be32
(
f
,
s
->
den
);
qemu_put_be32
(
f
,
s
->
cr
);
qemu_put_be32
(
f
,
s
->
float_high
);
}
static
int
pl061_load
(
QEMUFile
*
f
,
void
*
opaque
,
int
version_id
)
{
pl061_state
*
s
=
(
pl061_state
*
)
opaque
;
if
(
version_id
!=
1
)
return
-
EINVAL
;
s
->
locked
=
qemu_get_be32
(
f
);
s
->
data
=
qemu_get_be32
(
f
);
s
->
old_data
=
qemu_get_be32
(
f
);
s
->
dir
=
qemu_get_be32
(
f
);
s
->
isense
=
qemu_get_be32
(
f
);
s
->
ibe
=
qemu_get_be32
(
f
);
s
->
iev
=
qemu_get_be32
(
f
);
s
->
im
=
qemu_get_be32
(
f
);
s
->
istate
=
qemu_get_be32
(
f
);
s
->
afsel
=
qemu_get_be32
(
f
);
s
->
dr2r
=
qemu_get_be32
(
f
);
s
->
dr4r
=
qemu_get_be32
(
f
);
s
->
dr8r
=
qemu_get_be32
(
f
);
s
->
odr
=
qemu_get_be32
(
f
);
s
->
pur
=
qemu_get_be32
(
f
);
s
->
pdr
=
qemu_get_be32
(
f
);
s
->
slr
=
qemu_get_be32
(
f
);
s
->
den
=
qemu_get_be32
(
f
);
s
->
cr
=
qemu_get_be32
(
f
);
s
->
float_high
=
qemu_get_be32
(
f
);
return
0
;
}
static
int
pl061_init
(
SysBusDevice
*
dev
,
const
unsigned
char
*
id
)
{
int
iomemtype
;
...
...
@@ -307,7 +287,6 @@ static int pl061_init(SysBusDevice *dev, const unsigned char *id)
qdev_init_gpio_in
(
&
dev
->
qdev
,
pl061_set_irq
,
8
);
qdev_init_gpio_out
(
&
dev
->
qdev
,
s
->
out
,
8
);
pl061_reset
(
s
);
register_savevm
(
&
dev
->
qdev
,
"pl061_gpio"
,
-
1
,
1
,
pl061_save
,
pl061_load
,
s
);
return
0
;
}
...
...
@@ -321,12 +300,24 @@ static int pl061_init_arm(SysBusDevice *dev)
return
pl061_init
(
dev
,
pl061_id
);
}
static
SysBusDeviceInfo
pl061_info
=
{
.
init
=
pl061_init_arm
,
.
qdev
.
name
=
"pl061"
,
.
qdev
.
size
=
sizeof
(
pl061_state
),
.
qdev
.
vmsd
=
&
vmstate_pl061
,
};
static
SysBusDeviceInfo
pl061_luminary_info
=
{
.
init
=
pl061_init_luminary
,
.
qdev
.
name
=
"pl061_luminary"
,
.
qdev
.
size
=
sizeof
(
pl061_state
),
.
qdev
.
vmsd
=
&
vmstate_pl061
,
};
static
void
pl061_register_devices
(
void
)
{
sysbus_register_dev
(
"pl061"
,
sizeof
(
pl061_state
),
pl061_init_arm
);
sysbus_register_dev
(
"pl061_luminary"
,
sizeof
(
pl061_state
),
pl061_init_luminary
);
sysbus_register_withprop
(
&
pl061_info
);
sysbus_register_withprop
(
&
pl061_luminary_info
);
}
device_init
(
pl061_register_devices
)
hw/pl110.c
浏览文件 @
f1a7104a
...
...
@@ -24,15 +24,25 @@ enum pl110_bppmode
BPP_4
,
BPP_8
,
BPP_16
,
BPP_32
BPP_32
,
BPP_16_565
,
/* PL111 only */
BPP_12
/* PL111 only */
};
/* The Versatile/PB uses a slightly modified PL110 controller. */
enum
pl110_version
{
PL110
,
PL110_VERSATILE
,
PL111
};
typedef
struct
{
SysBusDevice
busdev
;
DisplayState
*
ds
;
/* The Versatile/PB uses a slightly modified PL110 controller. */
int
versatile
;
int
version
;
uint32_t
timing
[
4
];
uint32_t
cr
;
uint32_t
upbase
;
...
...
@@ -43,6 +53,7 @@ typedef struct {
int
rows
;
enum
pl110_bppmode
bpp
;
int
invalidate
;
uint32_t
mux_ctrl
;
uint32_t
pallette
[
256
];
uint32_t
raw_pallette
[
128
];
qemu_irq
irq
;
...
...
@@ -50,10 +61,10 @@ typedef struct {
static
const
VMStateDescription
vmstate_pl110
=
{
.
name
=
"pl110"
,
.
version_id
=
1
,
.
version_id
=
2
,
.
minimum_version_id
=
1
,
.
fields
=
(
VMStateField
[])
{
VMSTATE_INT32
(
vers
atile
,
pl110_state
),
VMSTATE_INT32
(
vers
ion
,
pl110_state
),
VMSTATE_UINT32_ARRAY
(
timing
,
pl110_state
,
4
),
VMSTATE_UINT32
(
cr
,
pl110_state
),
VMSTATE_UINT32
(
upbase
,
pl110_state
),
...
...
@@ -66,6 +77,7 @@ static const VMStateDescription vmstate_pl110 = {
VMSTATE_INT32
(
invalidate
,
pl110_state
),
VMSTATE_UINT32_ARRAY
(
pallette
,
pl110_state
,
256
),
VMSTATE_UINT32_ARRAY
(
raw_pallette
,
pl110_state
,
128
),
VMSTATE_UINT32_V
(
mux_ctrl
,
pl110_state
,
2
),
VMSTATE_END_OF_LIST
()
}
};
...
...
@@ -82,6 +94,17 @@ static const unsigned char pl110_versatile_id[] =
#define pl110_versatile_id pl110_id
#endif
static
const
unsigned
char
pl111_id
[]
=
{
0x11
,
0x11
,
0x24
,
0x00
,
0x0d
,
0xf0
,
0x05
,
0xb1
};
/* Indexed by pl110_version */
static
const
unsigned
char
*
idregs
[]
=
{
pl110_id
,
pl110_versatile_id
,
pl111_id
};
#include "pixel_ops.h"
#define BITS 8
...
...
@@ -144,12 +167,40 @@ static void pl110_update_display(void *opaque)
if
(
s
->
cr
&
PL110_CR_BGR
)
bpp_offset
=
0
;
else
bpp_offset
=
18
;
bpp_offset
=
24
;
if
((
s
->
version
!=
PL111
)
&&
(
s
->
bpp
==
BPP_16
))
{
/* The PL110's native 16 bit mode is 5551; however
* most boards with a PL110 implement an external
* mux which allows bits to be reshuffled to give
* 565 format. The mux is typically controlled by
* an external system register.
* This is controlled by a GPIO input pin
* so boards can wire it up to their register.
*
* The PL111 straightforwardly implements both
* 5551 and 565 under control of the bpp field
* in the LCDControl register.
*/
switch
(
s
->
mux_ctrl
)
{
case
3
:
/* 565 BGR */
bpp_offset
=
(
BPP_16_565
-
BPP_16
);
break
;
case
1
:
/* 5551 */
break
;
case
0
:
/* 888; also if we have loaded vmstate from an old version */
case
2
:
/* 565 RGB */
default:
/* treat as 565 but honour BGR bit */
bpp_offset
+=
(
BPP_16_565
-
BPP_16
);
break
;
}
}
if
(
s
->
cr
&
PL110_CR_BEBO
)
fn
=
fntable
[
s
->
bpp
+
6
+
bpp_offset
];
fn
=
fntable
[
s
->
bpp
+
8
+
bpp_offset
];
else
if
(
s
->
cr
&
PL110_CR_BEPO
)
fn
=
fntable
[
s
->
bpp
+
1
2
+
bpp_offset
];
fn
=
fntable
[
s
->
bpp
+
1
6
+
bpp_offset
];
else
fn
=
fntable
[
s
->
bpp
+
bpp_offset
];
...
...
@@ -167,6 +218,8 @@ static void pl110_update_display(void *opaque)
case
BPP_8
:
break
;
case
BPP_16
:
case
BPP_16_565
:
case
BPP_12
:
src_width
<<=
1
;
break
;
case
BPP_32
:
...
...
@@ -253,10 +306,7 @@ static uint32_t pl110_read(void *opaque, target_phys_addr_t offset)
pl110_state
*
s
=
(
pl110_state
*
)
opaque
;
if
(
offset
>=
0xfe0
&&
offset
<
0x1000
)
{
if
(
s
->
versatile
)
return
pl110_versatile_id
[(
offset
-
0xfe0
)
>>
2
];
else
return
pl110_id
[(
offset
-
0xfe0
)
>>
2
];
return
idregs
[
s
->
version
][(
offset
-
0xfe0
)
>>
2
];
}
if
(
offset
>=
0x200
&&
offset
<
0x400
)
{
return
s
->
raw_pallette
[(
offset
-
0x200
)
>>
2
];
...
...
@@ -275,12 +325,14 @@ static uint32_t pl110_read(void *opaque, target_phys_addr_t offset)
case
5
:
/* LCDLPBASE */
return
s
->
lpbase
;
case
6
:
/* LCDIMSC */
if
(
s
->
versatile
)
return
s
->
cr
;
if
(
s
->
version
!=
PL110
)
{
return
s
->
cr
;
}
return
s
->
int_mask
;
case
7
:
/* LCDControl */
if
(
s
->
versatile
)
return
s
->
int_mask
;
if
(
s
->
version
!=
PL110
)
{
return
s
->
int_mask
;
}
return
s
->
cr
;
case
8
:
/* LCDRIS */
return
s
->
int_status
;
...
...
@@ -337,15 +389,17 @@ static void pl110_write(void *opaque, target_phys_addr_t offset,
s
->
lpbase
=
val
;
break
;
case
6
:
/* LCDIMSC */
if
(
s
->
vers
atile
)
if
(
s
->
vers
ion
!=
PL110
)
{
goto
control
;
}
imsc:
s
->
int_mask
=
val
;
pl110_update
(
s
);
break
;
case
7
:
/* LCDControl */
if
(
s
->
vers
atile
)
if
(
s
->
vers
ion
!=
PL110
)
{
goto
imsc
;
}
control:
s
->
cr
=
val
;
s
->
bpp
=
(
val
>>
1
)
&
7
;
...
...
@@ -374,6 +428,12 @@ static CPUWriteMemoryFunc * const pl110_writefn[] = {
pl110_write
};
static
void
pl110_mux_ctrl_set
(
void
*
opaque
,
int
line
,
int
level
)
{
pl110_state
*
s
=
(
pl110_state
*
)
opaque
;
s
->
mux_ctrl
=
level
;
}
static
int
pl110_init
(
SysBusDevice
*
dev
)
{
pl110_state
*
s
=
FROM_SYSBUS
(
pl110_state
,
dev
);
...
...
@@ -384,6 +444,7 @@ static int pl110_init(SysBusDevice *dev)
DEVICE_NATIVE_ENDIAN
);
sysbus_init_mmio
(
dev
,
0x1000
,
iomemtype
);
sysbus_init_irq
(
dev
,
&
s
->
irq
);
qdev_init_gpio_in
(
&
s
->
busdev
.
qdev
,
pl110_mux_ctrl_set
,
1
);
s
->
ds
=
graphic_console_init
(
pl110_update_display
,
pl110_invalidate_display
,
NULL
,
NULL
,
s
);
...
...
@@ -393,7 +454,14 @@ static int pl110_init(SysBusDevice *dev)
static
int
pl110_versatile_init
(
SysBusDevice
*
dev
)
{
pl110_state
*
s
=
FROM_SYSBUS
(
pl110_state
,
dev
);
s
->
versatile
=
1
;
s
->
version
=
PL110_VERSATILE
;
return
pl110_init
(
dev
);
}
static
int
pl111_init
(
SysBusDevice
*
dev
)
{
pl110_state
*
s
=
FROM_SYSBUS
(
pl110_state
,
dev
);
s
->
version
=
PL111
;
return
pl110_init
(
dev
);
}
...
...
@@ -413,10 +481,19 @@ static SysBusDeviceInfo pl110_versatile_info = {
.
qdev
.
no_user
=
1
,
};
static
SysBusDeviceInfo
pl111_info
=
{
.
init
=
pl111_init
,
.
qdev
.
name
=
"pl111"
,
.
qdev
.
size
=
sizeof
(
pl110_state
),
.
qdev
.
vmsd
=
&
vmstate_pl110
,
.
qdev
.
no_user
=
1
,
};
static
void
pl110_register_devices
(
void
)
{
sysbus_register_withprop
(
&
pl110_info
);
sysbus_register_withprop
(
&
pl110_versatile_info
);
sysbus_register_withprop
(
&
pl111_info
);
}
device_init
(
pl110_register_devices
)
hw/pl110_template.h
浏览文件 @
f1a7104a
...
...
@@ -43,49 +43,61 @@
#include "pl110_template.h"
#undef BORDER
static
drawfn
glue
(
pl110_draw_fn_
,
BITS
)[
36
]
=
static
drawfn
glue
(
pl110_draw_fn_
,
BITS
)[
48
]
=
{
glue
(
pl110_draw_line1_lblp_bgr
,
BITS
),
glue
(
pl110_draw_line2_lblp_bgr
,
BITS
),
glue
(
pl110_draw_line4_lblp_bgr
,
BITS
),
glue
(
pl110_draw_line8_lblp_bgr
,
BITS
),
glue
(
pl110_draw_line16_lblp_bgr
,
BITS
),
glue
(
pl110_draw_line16_
555_
lblp_bgr
,
BITS
),
glue
(
pl110_draw_line32_lblp_bgr
,
BITS
),
glue
(
pl110_draw_line16_lblp_bgr
,
BITS
),
glue
(
pl110_draw_line12_lblp_bgr
,
BITS
),
glue
(
pl110_draw_line1_bbbp_bgr
,
BITS
),
glue
(
pl110_draw_line2_bbbp_bgr
,
BITS
),
glue
(
pl110_draw_line4_bbbp_bgr
,
BITS
),
glue
(
pl110_draw_line8_bbbp_bgr
,
BITS
),
glue
(
pl110_draw_line16_bbbp_bgr
,
BITS
),
glue
(
pl110_draw_line16_
555_
bbbp_bgr
,
BITS
),
glue
(
pl110_draw_line32_bbbp_bgr
,
BITS
),
glue
(
pl110_draw_line16_bbbp_bgr
,
BITS
),
glue
(
pl110_draw_line12_bbbp_bgr
,
BITS
),
glue
(
pl110_draw_line1_lbbp_bgr
,
BITS
),
glue
(
pl110_draw_line2_lbbp_bgr
,
BITS
),
glue
(
pl110_draw_line4_lbbp_bgr
,
BITS
),
glue
(
pl110_draw_line8_lbbp_bgr
,
BITS
),
glue
(
pl110_draw_line16_lbbp_bgr
,
BITS
),
glue
(
pl110_draw_line16_
555_
lbbp_bgr
,
BITS
),
glue
(
pl110_draw_line32_lbbp_bgr
,
BITS
),
glue
(
pl110_draw_line16_lbbp_bgr
,
BITS
),
glue
(
pl110_draw_line12_lbbp_bgr
,
BITS
),
glue
(
pl110_draw_line1_lblp_rgb
,
BITS
),
glue
(
pl110_draw_line2_lblp_rgb
,
BITS
),
glue
(
pl110_draw_line4_lblp_rgb
,
BITS
),
glue
(
pl110_draw_line8_lblp_rgb
,
BITS
),
glue
(
pl110_draw_line16_lblp_rgb
,
BITS
),
glue
(
pl110_draw_line16_
555_
lblp_rgb
,
BITS
),
glue
(
pl110_draw_line32_lblp_rgb
,
BITS
),
glue
(
pl110_draw_line16_lblp_rgb
,
BITS
),
glue
(
pl110_draw_line12_lblp_rgb
,
BITS
),
glue
(
pl110_draw_line1_bbbp_rgb
,
BITS
),
glue
(
pl110_draw_line2_bbbp_rgb
,
BITS
),
glue
(
pl110_draw_line4_bbbp_rgb
,
BITS
),
glue
(
pl110_draw_line8_bbbp_rgb
,
BITS
),
glue
(
pl110_draw_line16_bbbp_rgb
,
BITS
),
glue
(
pl110_draw_line16_
555_
bbbp_rgb
,
BITS
),
glue
(
pl110_draw_line32_bbbp_rgb
,
BITS
),
glue
(
pl110_draw_line16_bbbp_rgb
,
BITS
),
glue
(
pl110_draw_line12_bbbp_rgb
,
BITS
),
glue
(
pl110_draw_line1_lbbp_rgb
,
BITS
),
glue
(
pl110_draw_line2_lbbp_rgb
,
BITS
),
glue
(
pl110_draw_line4_lbbp_rgb
,
BITS
),
glue
(
pl110_draw_line8_lbbp_rgb
,
BITS
),
glue
(
pl110_draw_line16_lbbp_rgb
,
BITS
),
glue
(
pl110_draw_line16_
555_
lbbp_rgb
,
BITS
),
glue
(
pl110_draw_line32_lbbp_rgb
,
BITS
),
glue
(
pl110_draw_line16_lbbp_rgb
,
BITS
),
glue
(
pl110_draw_line12_lbbp_rgb
,
BITS
),
};
#undef BITS
...
...
@@ -299,6 +311,82 @@ static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_
}
}
static
void
glue
(
pl110_draw_line16_555_
,
NAME
)(
void
*
opaque
,
uint8_t
*
d
,
const
uint8_t
*
src
,
int
width
,
int
deststep
)
{
/* RGB 555 plus an intensity bit (which we ignore) */
uint32_t
data
;
unsigned
int
r
,
g
,
b
;
while
(
width
>
0
)
{
data
=
*
(
uint32_t
*
)
src
;
#ifdef SWAP_WORDS
data
=
bswap32
(
data
);
#endif
#ifdef RGB
#define LSB r
#define MSB b
#else
#define LSB b
#define MSB r
#endif
LSB
=
(
data
&
0x1f
)
<<
3
;
data
>>=
5
;
g
=
(
data
&
0x1f
)
<<
3
;
data
>>=
5
;
MSB
=
(
data
&
0x1f
)
<<
3
;
data
>>=
5
;
COPY_PIXEL
(
d
,
glue
(
rgb_to_pixel
,
BITS
)(
r
,
g
,
b
));
LSB
=
(
data
&
0x1f
)
<<
3
;
data
>>=
5
;
g
=
(
data
&
0x1f
)
<<
3
;
data
>>=
5
;
MSB
=
(
data
&
0x1f
)
<<
3
;
data
>>=
6
;
COPY_PIXEL
(
d
,
glue
(
rgb_to_pixel
,
BITS
)(
r
,
g
,
b
));
#undef MSB
#undef LSB
width
-=
2
;
src
+=
4
;
}
}
static
void
glue
(
pl110_draw_line12_
,
NAME
)(
void
*
opaque
,
uint8_t
*
d
,
const
uint8_t
*
src
,
int
width
,
int
deststep
)
{
/* RGB 444 with 4 bits of zeroes at the top of each halfword */
uint32_t
data
;
unsigned
int
r
,
g
,
b
;
while
(
width
>
0
)
{
data
=
*
(
uint32_t
*
)
src
;
#ifdef SWAP_WORDS
data
=
bswap32
(
data
);
#endif
#ifdef RGB
#define LSB r
#define MSB b
#else
#define LSB b
#define MSB r
#endif
LSB
=
(
data
&
0xf
)
<<
4
;
data
>>=
4
;
g
=
(
data
&
0xf
)
<<
4
;
data
>>=
4
;
MSB
=
(
data
&
0xf
)
<<
4
;
data
>>=
8
;
COPY_PIXEL
(
d
,
glue
(
rgb_to_pixel
,
BITS
)(
r
,
g
,
b
));
LSB
=
(
data
&
0xf
)
<<
4
;
data
>>=
4
;
g
=
(
data
&
0xf
)
<<
4
;
data
>>=
4
;
MSB
=
(
data
&
0xf
)
<<
4
;
data
>>=
8
;
COPY_PIXEL
(
d
,
glue
(
rgb_to_pixel
,
BITS
)(
r
,
g
,
b
));
#undef MSB
#undef LSB
width
-=
2
;
src
+=
4
;
}
}
#undef SWAP_PIXELS
#undef NAME
#undef SWAP_WORDS
...
...
hw/realview.c
浏览文件 @
f1a7104a
...
...
@@ -251,7 +251,7 @@ static void realview_init(ram_addr_t ram_size,
sysbus_create_simple
(
"pl061"
,
0x10014000
,
pic
[
7
]);
gpio2
=
sysbus_create_simple
(
"pl061"
,
0x10015000
,
pic
[
8
]);
sysbus_create_simple
(
"pl11
0_versatile
"
,
0x10020000
,
pic
[
23
]);
sysbus_create_simple
(
"pl11
1
"
,
0x10020000
,
pic
[
23
]);
dev
=
sysbus_create_varargs
(
"pl181"
,
0x10005000
,
pic
[
17
],
pic
[
18
],
NULL
);
/* Wire up MMC card detect and read-only signals. These have
...
...
hw/stellaris.c
浏览文件 @
f1a7104a
...
...
@@ -332,6 +332,7 @@ typedef struct {
uint32_t
int_mask
;
uint32_t
resc
;
uint32_t
rcc
;
uint32_t
rcc2
;
uint32_t
rcgc
[
3
];
uint32_t
scgc
[
3
];
uint32_t
dcgc
[
3
];
...
...
@@ -386,6 +387,32 @@ static uint32_t pllcfg_fury[16] = {
0xb11c
/* 8.192 Mhz */
};
#define DID0_VER_MASK 0x70000000
#define DID0_VER_0 0x00000000
#define DID0_VER_1 0x10000000
#define DID0_CLASS_MASK 0x00FF0000
#define DID0_CLASS_SANDSTORM 0x00000000
#define DID0_CLASS_FURY 0x00010000
static
int
ssys_board_class
(
const
ssys_state
*
s
)
{
uint32_t
did0
=
s
->
board
->
did0
;
switch
(
did0
&
DID0_VER_MASK
)
{
case
DID0_VER_0
:
return
DID0_CLASS_SANDSTORM
;
case
DID0_VER_1
:
switch
(
did0
&
DID0_CLASS_MASK
)
{
case
DID0_CLASS_SANDSTORM
:
case
DID0_CLASS_FURY
:
return
did0
&
DID0_CLASS_MASK
;
}
/* for unknown classes, fall through */
default:
hw_error
(
"ssys_board_class: Unknown class 0x%08x
\n
"
,
did0
);
}
}
static
uint32_t
ssys_read
(
void
*
opaque
,
target_phys_addr_t
offset
)
{
ssys_state
*
s
=
(
ssys_state
*
)
opaque
;
...
...
@@ -429,12 +456,18 @@ static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
{
int
xtal
;
xtal
=
(
s
->
rcc
>>
6
)
&
0xf
;
if
(
s
->
board
->
did0
&
(
1
<<
16
))
{
switch
(
ssys_board_class
(
s
))
{
case
DID0_CLASS_FURY
:
return
pllcfg_fury
[
xtal
];
}
else
{
case
DID0_CLASS_SANDSTORM
:
return
pllcfg_sandstorm
[
xtal
];
default:
hw_error
(
"ssys_read: Unhandled class for PLLCFG read.
\n
"
);
return
0
;
}
}
case
0x070
:
/* RCC2 */
return
s
->
rcc2
;
case
0x100
:
/* RCGC0 */
return
s
->
rcgc
[
0
];
case
0x104
:
/* RCGC1 */
...
...
@@ -467,9 +500,21 @@ static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
}
}
static
bool
ssys_use_rcc2
(
ssys_state
*
s
)
{
return
(
s
->
rcc2
>>
31
)
&
0x1
;
}
/*
* Caculate the sys. clock period in ms.
*/
static
void
ssys_calculate_system_clock
(
ssys_state
*
s
)
{
system_clock_scale
=
5
*
(((
s
->
rcc
>>
23
)
&
0xf
)
+
1
);
if
(
ssys_use_rcc2
(
s
))
{
system_clock_scale
=
5
*
(((
s
->
rcc2
>>
23
)
&
0x3f
)
+
1
);
}
else
{
system_clock_scale
=
5
*
(((
s
->
rcc
>>
23
)
&
0xf
)
+
1
);
}
}
static
void
ssys_write
(
void
*
opaque
,
target_phys_addr_t
offset
,
uint32_t
value
)
...
...
@@ -505,6 +550,18 @@ static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
s
->
rcc
=
value
;
ssys_calculate_system_clock
(
s
);
break
;
case
0x070
:
/* RCC2 */
if
(
ssys_board_class
(
s
)
==
DID0_CLASS_SANDSTORM
)
{
break
;
}
if
((
s
->
rcc2
&
(
1
<<
13
))
!=
0
&&
(
value
&
(
1
<<
13
))
==
0
)
{
/* PLL enable. */
s
->
int_status
|=
(
1
<<
6
);
}
s
->
rcc2
=
value
;
ssys_calculate_system_clock
(
s
);
break
;
case
0x100
:
/* RCGC0 */
s
->
rcgc
[
0
]
=
value
;
break
;
...
...
@@ -562,6 +619,12 @@ static void ssys_reset(void *opaque)
s
->
pborctl
=
0x7ffd
;
s
->
rcc
=
0x078e3ac0
;
if
(
ssys_board_class
(
s
)
==
DID0_CLASS_SANDSTORM
)
{
s
->
rcc2
=
0
;
}
else
{
s
->
rcc2
=
0x07802810
;
}
s
->
rcgc
[
0
]
=
1
;
s
->
scgc
[
0
]
=
1
;
s
->
dcgc
[
0
]
=
1
;
...
...
@@ -578,7 +641,7 @@ static int stellaris_sys_post_load(void *opaque, int version_id)
static
const
VMStateDescription
vmstate_stellaris_sys
=
{
.
name
=
"stellaris_sys"
,
.
version_id
=
1
,
.
version_id
=
2
,
.
minimum_version_id
=
1
,
.
minimum_version_id_old
=
1
,
.
post_load
=
stellaris_sys_post_load
,
...
...
@@ -589,6 +652,7 @@ static const VMStateDescription vmstate_stellaris_sys = {
VMSTATE_UINT32
(
int_status
,
ssys_state
),
VMSTATE_UINT32
(
resc
,
ssys_state
),
VMSTATE_UINT32
(
rcc
,
ssys_state
),
VMSTATE_UINT32_V
(
rcc2
,
ssys_state
,
2
),
VMSTATE_UINT32_ARRAY
(
rcgc
,
ssys_state
,
3
),
VMSTATE_UINT32_ARRAY
(
scgc
,
ssys_state
,
3
),
VMSTATE_UINT32_ARRAY
(
dcgc
,
ssys_state
,
3
),
...
...
hw/syborg_fb.c
浏览文件 @
f1a7104a
...
...
@@ -217,15 +217,24 @@ static void syborg_fb_update_display(void *opaque)
}
if
(
s
->
rgb
)
{
bpp_offset
=
18
;
bpp_offset
=
24
;
}
else
{
bpp_offset
=
0
;
}
if
(
s
->
endian
)
{
bpp_offset
+=
8
;
}
/* Our bpp constants mostly match the PL110/PL111 but
* not for the 16 bit case
*/
switch
(
s
->
bpp
)
{
case
BPP_SRC_16
:
bpp_offset
+=
6
;
break
;
default:
bpp_offset
+=
s
->
bpp
;
}
fn
=
fntable
[
s
->
bpp
+
bpp_offset
];
fn
=
fntable
[
bpp_offset
];
if
(
s
->
pitch
)
{
src_width
=
s
->
pitch
;
...
...
hw/versatilepb.c
浏览文件 @
f1a7104a
...
...
@@ -180,7 +180,7 @@ static void versatile_init(ram_addr_t ram_size,
qemu_irq
*
cpu_pic
;
qemu_irq
pic
[
32
];
qemu_irq
sic
[
32
];
DeviceState
*
dev
;
DeviceState
*
dev
,
*
sysctl
;
PCIBus
*
pci_bus
;
NICInfo
*
nd
;
int
n
;
...
...
@@ -198,7 +198,12 @@ static void versatile_init(ram_addr_t ram_size,
/* SDRAM at address zero. */
cpu_register_physical_memory
(
0
,
ram_size
,
ram_offset
|
IO_MEM_RAM
);
arm_sysctl_init
(
0x10000000
,
0x41007004
,
0x02000000
);
sysctl
=
qdev_create
(
NULL
,
"realview_sysctl"
);
qdev_prop_set_uint32
(
sysctl
,
"sys_id"
,
0x41007004
);
qdev_init_nofail
(
sysctl
);
qdev_prop_set_uint32
(
sysctl
,
"proc_id"
,
0x02000000
);
sysbus_mmio_map
(
sysbus_from_qdev
(
sysctl
),
0
,
0x10000000
);
cpu_pic
=
arm_pic_init_cpu
(
env
);
dev
=
sysbus_create_varargs
(
"pl190"
,
0x10140000
,
cpu_pic
[
0
],
cpu_pic
[
1
],
NULL
);
...
...
@@ -250,7 +255,9 @@ static void versatile_init(ram_addr_t ram_size,
/* The versatile/PB actually has a modified Color LCD controller
that includes hardware cursor support from the PL111. */
sysbus_create_simple
(
"pl110_versatile"
,
0x10120000
,
pic
[
16
]);
dev
=
sysbus_create_simple
(
"pl110_versatile"
,
0x10120000
,
pic
[
16
]);
/* Wire up the mux control signals from the SYS_CLCD register */
qdev_connect_gpio_out
(
sysctl
,
0
,
qdev_get_gpio_in
(
dev
,
0
));
sysbus_create_varargs
(
"pl181"
,
0x10005000
,
sic
[
22
],
sic
[
1
],
NULL
);
sysbus_create_varargs
(
"pl181"
,
0x1000b000
,
sic
[
23
],
sic
[
2
],
NULL
);
...
...
hw/vexpress.c
浏览文件 @
f1a7104a
...
...
@@ -150,7 +150,7 @@ static void vexpress_a9_init(ram_addr_t ram_size,
/* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
/* 0x10020000 PL111 CLCD (daughterboard) */
sysbus_create_simple
(
"pl11
0
"
,
0x10020000
,
pic
[
44
]);
sysbus_create_simple
(
"pl11
1
"
,
0x10020000
,
pic
[
44
]);
/* 0x10060000 AXI RAM */
/* 0x100e0000 PL341 Dynamic Memory Controller */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录