提交 f0d1d2c1 编写于 作者: X xiaoqiang zhao 提交者: Peter Maydell

hw/char: QOM'ify pl011 model

* drop qemu_char_get_next_serial and use chardev prop
* add pl011_create wrapper function to create pl011 uart device
* change affected board code to use the new way
Signed-off-by: Nxiaoqiang zhao <zxq_yx_007@163.com>
Message-id: 1465028065-5855-2-git-send-email-zxq_yx_007@163.com
Reviewed-by: NPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
上级 578c4b2f
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "hw/misc/bcm2835_mbox_defs.h" #include "hw/misc/bcm2835_mbox_defs.h"
#include "hw/arm/raspi_platform.h" #include "hw/arm/raspi_platform.h"
#include "sysemu/char.h" #include "sysemu/char.h"
#include "sysemu/sysemu.h"
/* Peripheral base address on the VC (GPU) system bus */ /* Peripheral base address on the VC (GPU) system bus */
#define BCM2835_VC_PERI_BASE 0x7e000000 #define BCM2835_VC_PERI_BASE 0x7e000000
...@@ -106,7 +107,6 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) ...@@ -106,7 +107,6 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
MemoryRegion *ram; MemoryRegion *ram;
Error *err = NULL; Error *err = NULL;
uint32_t ram_size, vcram_size; uint32_t ram_size, vcram_size;
CharDriverState *chr;
int n; int n;
obj = object_property_get_link(OBJECT(dev), "ram", &err); obj = object_property_get_link(OBJECT(dev), "ram", &err);
...@@ -147,6 +147,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) ...@@ -147,6 +147,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(&s->ic)); sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(&s->ic));
/* UART0 */ /* UART0 */
qdev_prop_set_chr(DEVICE(s->uart0), "chardev", serial_hds[0]);
object_property_set_bool(OBJECT(s->uart0), true, "realized", &err); object_property_set_bool(OBJECT(s->uart0), true, "realized", &err);
if (err) { if (err) {
error_propagate(errp, err); error_propagate(errp, err);
...@@ -158,17 +159,8 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) ...@@ -158,17 +159,8 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(s->uart0, 0, sysbus_connect_irq(s->uart0, 0,
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
INTERRUPT_UART)); INTERRUPT_UART));
/* AUX / UART1 */ /* AUX / UART1 */
/* TODO: don't call qemu_char_get_next_serial() here, instead set qdev_prop_set_chr(DEVICE(&s->aux), "chardev", serial_hds[1]);
* chardev properties for each uart at the board level, once pl011
* (uart0) has been updated to avoid qemu_char_get_next_serial()
*/
chr = qemu_char_get_next_serial();
if (chr == NULL) {
chr = qemu_chr_new("bcm2835.uart1", "null", NULL);
}
qdev_prop_set_chr(DEVICE(&s->aux), "chardev", chr);
object_property_set_bool(OBJECT(&s->aux), true, "realized", &err); object_property_set_bool(OBJECT(&s->aux), true, "realized", &err);
if (err) { if (err) {
...@@ -292,8 +284,6 @@ static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data) ...@@ -292,8 +284,6 @@ static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc);
dc->realize = bcm2835_peripherals_realize; dc->realize = bcm2835_peripherals_realize;
/* Reason: realize() method uses qemu_char_get_next_serial() */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo bcm2835_peripherals_type_info = { static const TypeInfo bcm2835_peripherals_type_info = {
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "hw/char/pl011.h"
#define SMP_BOOT_ADDR 0x100 #define SMP_BOOT_ADDR 0x100
#define SMP_BOOT_REG 0x40 #define SMP_BOOT_REG 0x40
...@@ -326,7 +327,7 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) ...@@ -326,7 +327,7 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
busdev = SYS_BUS_DEVICE(dev); busdev = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(busdev, 0, 0xfff34000); sysbus_mmio_map(busdev, 0, 0xfff34000);
sysbus_connect_irq(busdev, 0, pic[18]); sysbus_connect_irq(busdev, 0, pic[18]);
sysbus_create_simple("pl011", 0xfff36000, pic[20]); pl011_create(0xfff36000, pic[20], serial_hds[0]);
dev = qdev_create(NULL, "highbank-regs"); dev = qdev_create(NULL, "highbank-regs");
qdev_init_nofail(dev); qdev_init_nofail(dev);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "hw/char/pl011.h"
#define TYPE_INTEGRATOR_CM "integrator_core" #define TYPE_INTEGRATOR_CM "integrator_core"
#define INTEGRATOR_CM(obj) \ #define INTEGRATOR_CM(obj) \
...@@ -588,8 +589,8 @@ static void integratorcp_init(MachineState *machine) ...@@ -588,8 +589,8 @@ static void integratorcp_init(MachineState *machine)
sysbus_create_varargs("integrator_pit", 0x13000000, sysbus_create_varargs("integrator_pit", 0x13000000,
pic[5], pic[6], pic[7], NULL); pic[5], pic[6], pic[7], NULL);
sysbus_create_simple("pl031", 0x15000000, pic[8]); sysbus_create_simple("pl031", 0x15000000, pic[8]);
sysbus_create_simple("pl011", 0x16000000, pic[1]); pl011_create(0x16000000, pic[1], serial_hds[0]);
sysbus_create_simple("pl011", 0x17000000, pic[2]); pl011_create(0x17000000, pic[2], serial_hds[1]);
icp = sysbus_create_simple(TYPE_ICP_CONTROL_REGS, 0xcb000000, icp = sysbus_create_simple(TYPE_ICP_CONTROL_REGS, 0xcb000000,
qdev_get_gpio_in(sic, 3)); qdev_get_gpio_in(sic, 3));
sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]); sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "hw/char/pl011.h"
#define SMP_BOOT_ADDR 0xe0000000 #define SMP_BOOT_ADDR 0xe0000000
#define SMP_BOOTREG_ADDR 0x10000030 #define SMP_BOOTREG_ADDR 0x10000030
...@@ -202,10 +203,10 @@ static void realview_init(MachineState *machine, ...@@ -202,10 +203,10 @@ static void realview_init(MachineState *machine,
sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]); sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);
sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]); sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]);
sysbus_create_simple("pl011", 0x10009000, pic[12]); pl011_create(0x10009000, pic[12], serial_hds[0]);
sysbus_create_simple("pl011", 0x1000a000, pic[13]); pl011_create(0x1000a000, pic[13], serial_hds[1]);
sysbus_create_simple("pl011", 0x1000b000, pic[14]); pl011_create(0x1000b000, pic[14], serial_hds[2]);
sysbus_create_simple("pl011", 0x1000c000, pic[15]); pl011_create(0x1000c000, pic[15], serial_hds[3]);
/* DMA controller is optional, apparently. */ /* DMA controller is optional, apparently. */
sysbus_create_simple("pl081", 0x10030000, pic[24]); sysbus_create_simple("pl081", 0x10030000, pic[24]);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "qemu/log.h" #include "qemu/log.h"
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "hw/char/pl011.h"
#define GPIO_A 0 #define GPIO_A 0
#define GPIO_B 1 #define GPIO_B 1
...@@ -1303,8 +1304,9 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, ...@@ -1303,8 +1304,9 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (board->dc2 & (1 << i)) { if (board->dc2 & (1 << i)) {
sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000, pl011_luminary_create(0x4000c000 + i * 0x1000,
qdev_get_gpio_in(nvic, uart_irq[i])); qdev_get_gpio_in(nvic, uart_irq[i]),
serial_hds[i]);
} }
} }
if (board->dc2 & (1 << 4)) { if (board->dc2 & (1 << 4)) {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "hw/block/flash.h" #include "hw/block/flash.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "hw/char/pl011.h"
#define VERSATILE_FLASH_ADDR 0x34000000 #define VERSATILE_FLASH_ADDR 0x34000000
#define VERSATILE_FLASH_SIZE (64 * 1024 * 1024) #define VERSATILE_FLASH_SIZE (64 * 1024 * 1024)
...@@ -284,10 +285,10 @@ static void versatile_init(MachineState *machine, int board_id) ...@@ -284,10 +285,10 @@ static void versatile_init(MachineState *machine, int board_id)
n--; n--;
} }
sysbus_create_simple("pl011", 0x101f1000, pic[12]); pl011_create(0x101f1000, pic[12], serial_hds[0]);
sysbus_create_simple("pl011", 0x101f2000, pic[13]); pl011_create(0x101f2000, pic[13], serial_hds[1]);
sysbus_create_simple("pl011", 0x101f3000, pic[14]); pl011_create(0x101f3000, pic[14], serial_hds[2]);
sysbus_create_simple("pl011", 0x10009000, sic[6]); pl011_create(0x10009000, sic[6], serial_hds[3]);
sysbus_create_simple("pl080", 0x10130000, pic[17]); sysbus_create_simple("pl080", 0x10130000, pic[17]);
sysbus_create_simple("sp804", 0x101e2000, pic[4]); sysbus_create_simple("sp804", 0x101e2000, pic[4]);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "sysemu/device_tree.h" #include "sysemu/device_tree.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include <libfdt.h> #include <libfdt.h>
#include "hw/char/pl011.h"
#define VEXPRESS_BOARD_ID 0x8e0 #define VEXPRESS_BOARD_ID 0x8e0
#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024) #define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
...@@ -631,10 +632,10 @@ static void vexpress_common_init(MachineState *machine) ...@@ -631,10 +632,10 @@ static void vexpress_common_init(MachineState *machine)
sysbus_create_simple("pl050_keyboard", map[VE_KMI0], pic[12]); sysbus_create_simple("pl050_keyboard", map[VE_KMI0], pic[12]);
sysbus_create_simple("pl050_mouse", map[VE_KMI1], pic[13]); sysbus_create_simple("pl050_mouse", map[VE_KMI1], pic[13]);
sysbus_create_simple("pl011", map[VE_UART0], pic[5]); pl011_create(map[VE_UART0], pic[5], serial_hds[0]);
sysbus_create_simple("pl011", map[VE_UART1], pic[6]); pl011_create(map[VE_UART1], pic[6], serial_hds[1]);
sysbus_create_simple("pl011", map[VE_UART2], pic[7]); pl011_create(map[VE_UART2], pic[7], serial_hds[2]);
sysbus_create_simple("pl011", map[VE_UART3], pic[8]); pl011_create(map[VE_UART3], pic[8], serial_hds[3]);
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]); sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]); sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
......
...@@ -536,6 +536,7 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic, int uart, ...@@ -536,6 +536,7 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic, int uart,
DeviceState *dev = qdev_create(NULL, "pl011"); DeviceState *dev = qdev_create(NULL, "pl011");
SysBusDevice *s = SYS_BUS_DEVICE(dev); SysBusDevice *s = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", serial_hds[0]);
qdev_init_nofail(dev); qdev_init_nofail(dev);
memory_region_add_subregion(mem, base, memory_region_add_subregion(mem, base,
sysbus_mmio_get_region(s, 0)); sysbus_mmio_get_region(s, 0));
......
...@@ -274,6 +274,11 @@ static const VMStateDescription vmstate_pl011 = { ...@@ -274,6 +274,11 @@ static const VMStateDescription vmstate_pl011 = {
} }
}; };
static Property pl011_properties[] = {
DEFINE_PROP_CHR("chardev", PL011State, chr),
DEFINE_PROP_END_OF_LIST(),
};
static void pl011_init(Object *obj) static void pl011_init(Object *obj)
{ {
SysBusDevice *sbd = SYS_BUS_DEVICE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
...@@ -295,9 +300,6 @@ static void pl011_realize(DeviceState *dev, Error **errp) ...@@ -295,9 +300,6 @@ static void pl011_realize(DeviceState *dev, Error **errp)
{ {
PL011State *s = PL011(dev); PL011State *s = PL011(dev);
/* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
s->chr = qemu_char_get_next_serial();
if (s->chr) { if (s->chr) {
qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive, qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
pl011_event, s); pl011_event, s);
...@@ -310,8 +312,7 @@ static void pl011_class_init(ObjectClass *oc, void *data) ...@@ -310,8 +312,7 @@ static void pl011_class_init(ObjectClass *oc, void *data)
dc->realize = pl011_realize; dc->realize = pl011_realize;
dc->vmsd = &vmstate_pl011; dc->vmsd = &vmstate_pl011;
/* Reason: realize() method uses qemu_char_get_next_serial() */ dc->props = pl011_properties;
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo pl011_arm_info = { static const TypeInfo pl011_arm_info = {
......
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2 or later, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#ifndef PL011_UART_H
#define PL011_UART_H
static inline DeviceState *pl011_create(hwaddr addr,
qemu_irq irq,
CharDriverState *chr)
{
DeviceState *dev;
SysBusDevice *s;
dev = qdev_create(NULL, "pl011");
s = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", chr);
qdev_init_nofail(dev);
sysbus_mmio_map(s, 0, addr);
sysbus_connect_irq(s, 0, irq);
return dev;
}
static inline DeviceState *pl011_luminary_create(hwaddr addr,
qemu_irq irq,
CharDriverState *chr)
{
DeviceState *dev;
SysBusDevice *s;
dev = qdev_create(NULL, "pl011_luminary");
s = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", chr);
qdev_init_nofail(dev);
sysbus_mmio_map(s, 0, addr);
sysbus_connect_irq(s, 0, irq);
return dev;
}
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册