On Sat, Feb 12, 2011 at 6:47 PM, Alexander Graf <ag...@suse.de> wrote: > > On 12.02.2011, at 15:54, David Gibson wrote: > >> This extends the "pseries" (PAPR) machine to include a virtual IO bus >> supporting the PAPR defined hypercall based virtual IO mechanisms. >> >> So far only one VIO device is provided, the vty / vterm, providing >> a full console (polled only, for now). >> >> Signed-off-by: David Gibson <d...@au1.ibm.com> >> --- >> Makefile.target | 3 +- >> hw/spapr.c | 31 +++++++++- >> hw/spapr.h | 10 +++ >> hw/spapr_hcall.c | 19 ++---- >> hw/spapr_vio.c | 191 >> ++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> hw/spapr_vio.h | 49 ++++++++++++++ >> hw/spapr_vty.c | 132 +++++++++++++++++++++++++++++++++++++ >> 7 files changed, 419 insertions(+), 16 deletions(-) >> create mode 100644 hw/spapr_vio.c >> create mode 100644 hw/spapr_vio.h >> create mode 100644 hw/spapr_vty.c >> >> diff --git a/Makefile.target b/Makefile.target >> index e0796ba..fe232da 100644 >> --- a/Makefile.target >> +++ b/Makefile.target >> @@ -232,7 +232,8 @@ obj-ppc-y += ppc_oldworld.o >> # NewWorld PowerMac >> obj-ppc-y += ppc_newworld.o >> # IBM pSeries (sPAPR) >> -obj-ppc-y += spapr.o spapr_hcall.o >> +obj-ppc-y += spapr.o spapr_hcall.o spapr_vio.o >> +obj-ppc-y += spapr_vty.o >> # PowerPC 4xx boards >> obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o >> obj-ppc-y += ppc440.o ppc440_bamboo.o >> diff --git a/hw/spapr.c b/hw/spapr.c >> index 8aca4e0..da61061 100644 >> --- a/hw/spapr.c >> +++ b/hw/spapr.c >> @@ -37,6 +37,7 @@ >> #include "net.h" >> #include "blockdev.h" >> #include "hw/spapr.h" >> +#include "hw/spapr_vio.h" >> >> #include <libfdt.h> >> >> @@ -49,6 +50,7 @@ >> >> static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize, >> const char *cpu_model, CPUState *envs[], >> + sPAPREnvironment *spapr, >> target_phys_addr_t initrd_base, >> target_phys_addr_t initrd_size, >> const char *kernel_cmdline) >> @@ -59,6 +61,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t >> ramsize, >> uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size); >> int i; >> char *modelname; >> + int ret; >> >> #define _FDT(exp) \ >> do { \ >> @@ -151,9 +154,28 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t >> ramsize, >> >> _FDT((fdt_end_node(fdt))); >> >> + /* vdevice */ >> + _FDT((fdt_begin_node(fdt, "vdevice"))); >> + >> + _FDT((fdt_property_string(fdt, "device_type", "vdevice"))); >> + _FDT((fdt_property_string(fdt, "compatible", "IBM,vdevice"))); >> + _FDT((fdt_property_cell(fdt, "#address-cells", 0x1))); >> + _FDT((fdt_property_cell(fdt, "#size-cells", 0x0))); >> + >> + _FDT((fdt_end_node(fdt))); >> + >> _FDT((fdt_end_node(fdt))); /* close root node */ >> _FDT((fdt_finish(fdt))); >> >> + /* re-expand to allow for further tweaks */ >> + _FDT((fdt_open_into(fdt, fdt, FDT_MAX_SIZE))); >> + >> + ret = spapr_populate_vdevice(spapr->vio_bus, fdt); >> + if (ret < 0) > > Braces.. > >> + fprintf(stderr, "couldn't setup vio devices in fdt\n"); >> + >> + _FDT((fdt_pack(fdt))); >> + >> if (fdt_size) >> *fdt_size = fdt_totalsize(fdt); >> >> @@ -211,6 +233,12 @@ static void ppc_spapr_init (ram_addr_t ram_size, >> ram_offset = qemu_ram_alloc(NULL, "ppc_spapr.ram", ram_size); >> cpu_register_physical_memory(0, ram_size, ram_offset); >> >> + spapr->vio_bus = spapr_vio_bus_init(); >> + >> + for (i = 0; i < MAX_SERIAL_PORTS; i++) > > Braces.. > >> + if (serial_hds[i]) > > Braces.. > >> + spapr_vty_create(spapr->vio_bus, i, serial_hds[i]); > > There might be a qdev way to do this. Blue?
Actually I don't quite understand the need for vty layer, why not use the chardev here directly? > >> + >> if (kernel_filename) { >> uint64_t lowaddr = 0; >> >> @@ -242,7 +270,7 @@ static void ppc_spapr_init (ram_addr_t ram_size, >> } >> >> /* load fdt */ >> - fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, &env, >> + fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, &env, spapr, >> initrd_base, initrd_size, >> kernel_cmdline); >> if (!fdt) { >> @@ -267,6 +295,7 @@ static QEMUMachine spapr_machine = { >> .desc = "pSeries Logical Partition (PAPR compliant)", >> .init = ppc_spapr_init, >> .max_cpus = 1, >> + .no_parallel = 1, > > duplicate? > >> .no_vga = 1, >> .no_parallel = 1, >> }; >> diff --git a/hw/spapr.h b/hw/spapr.h >> index dae9617..168511f 100644 >> --- a/hw/spapr.h >> +++ b/hw/spapr.h >> @@ -1,7 +1,10 @@ >> #if !defined (__HW_SPAPR_H__) >> #define __HW_SPAPR_H__ >> >> +struct VIOsPAPRBus; >> + >> typedef struct sPAPREnvironment { >> + struct VIOsPAPRBus *vio_bus; >> } sPAPREnvironment; >> >> #define H_SUCCESS 0 >> @@ -237,4 +240,11 @@ typedef struct sPAPREnvironment { >> target_ulong spapr_hypercall(CPUState *env, sPAPREnvironment *spapr, >> target_ulong token, target_ulong *args); >> >> +target_ulong h_put_term_char(sPAPREnvironment *spapr, >> + target_ulong termno, target_ulong len, >> + target_ulong char0_7, target_ulong char8_15); >> +target_ulong h_get_term_char(sPAPREnvironment *spapr, >> + target_ulong termno, target_ulong *len, >> + target_ulong *char0_7, target_ulong *char8_15); >> + >> #endif /* !defined (__HW_SPAPR_H__) */ >> diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c >> index c99c345..e2ed9cf 100644 >> --- a/hw/spapr_hcall.c >> +++ b/hw/spapr_hcall.c >> @@ -3,19 +3,6 @@ >> #include "qemu-char.h" >> #include "hw/spapr.h" >> >> -static target_ulong h_put_term_char(target_ulong termno, target_ulong len, >> - target_ulong char0_7, target_ulong >> char8_15) >> -{ >> - uint8_t buf[16]; >> - >> - *((uint64_t *)buf) = cpu_to_be64(char0_7); >> - *((uint64_t *)buf + 1) = cpu_to_be64(char8_15); >> - >> - qemu_chr_write(serial_hds[0], buf, len); >> - >> - return 0; >> -} >> - >> target_ulong spapr_hypercall(CPUState *env, sPAPREnvironment *spapr, >> target_ulong token, target_ulong *args) >> { >> @@ -29,7 +16,11 @@ target_ulong spapr_hypercall(CPUState *env, >> sPAPREnvironment *spapr, >> >> switch (token) { >> case H_PUT_TERM_CHAR: >> - r = h_put_term_char(args[0], args[1], args[2], args[3]); >> + r = h_put_term_char(spapr, args[0], args[1], args[2], args[3]); >> + break; >> + >> + case H_GET_TERM_CHAR: >> + r = h_get_term_char(spapr, args[0], &args[0], &args[1], &args[2]); > > Slick and simple. Blue, do you think there's some random abstraction layer > necessary? Same here.