aboutsummaryrefslogtreecommitdiff
path: root/hw/spapr.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2011-04-01 15:15:21 +1100
committerAlexander Graf <agraf@suse.de>2011-04-01 18:34:55 +0200
commit4040ab72379f75fe171c03f93ceb75efb48c14a5 (patch)
tree0d7f11215e5032e24f10cca36d48aeff4d7b0edb /hw/spapr.c
parent9fdf0c2995d04a74a22ea4609b2931eef209e53d (diff)
Implement the bus structure for PAPR virtual IO
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 <dwg@au1.ibm.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw/spapr.c')
-rw-r--r--hw/spapr.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/hw/spapr.c b/hw/spapr.c
index 410213afc8..c24c92b1a0 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -25,7 +25,6 @@
*
*/
#include "sysemu.h"
-#include "qemu-char.h"
#include "hw.h"
#include "elf.h"
@@ -34,6 +33,7 @@
#include "hw/loader.h"
#include "hw/spapr.h"
+#include "hw/spapr_vio.h"
#include <libfdt.h>
@@ -60,6 +60,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 { \
@@ -159,9 +160,30 @@ 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) {
+ fprintf(stderr, "couldn't setup vio devices in fdt\n");
+ exit(1);
+ }
+
+ _FDT((fdt_pack(fdt)));
+
*fdt_size = fdt_totalsize(fdt);
return fdt;
@@ -177,21 +199,6 @@ static void emulate_spapr_hypercall(CPUState *env)
env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
}
-/* FIXME: hack until we implement the proper VIO console */
-static target_ulong h_put_term_char(CPUState *env, sPAPREnvironment *spapr,
- target_ulong opcode, target_ulong *args)
-{
- uint8_t buf[16];
-
- stq_p(buf, args[2]);
- stq_p(buf + 8, args[3]);
-
- qemu_chr_write(serial_hds[0], buf, args[1]);
-
- return 0;
-}
-
-
/* pSeries LPAR / sPAPR hardware init */
static void ppc_spapr_init(ram_addr_t ram_size,
const char *boot_device,
@@ -243,7 +250,13 @@ 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_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
+ spapr->vio_bus = spapr_vio_bus_init();
+
+ for (i = 0; i < MAX_SERIAL_PORTS; i++) {
+ if (serial_hds[i]) {
+ spapr_vty_create(spapr->vio_bus, i, serial_hds[i]);
+ }
+ }
if (kernel_filename) {
uint64_t lowaddr = 0;
@@ -276,7 +289,6 @@ static void ppc_spapr_init(ram_addr_t ram_size,
initrd_base = 0;
initrd_size = 0;
}
-
} else {
fprintf(stderr, "pSeries machine needs -kernel for now");
exit(1);