Skip to content

Commit

Permalink
Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf
Browse files Browse the repository at this point in the history
* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf: (72 commits)
  PPC: BookE206: Bump MAS2 to 64bit
  PPC: BookE: Support 32 and 64 bit wide MAS2
  PPC: Extract SPR dump generation into its own function
  PPC: Add e5500 CPU target
  PPC: BookE: Make ivpr selectable by CPU type
  PPC: BookE: Implement EPR SPR
  PPC: Add support for MSR_CM
  PPC: Add some booke SPR defines
  uImage: increase the gzip load size
  PPC: e500: allow users to set the /compatible property via -machine
  dt: make setprop argument static
  PPC: e500: Refactor serial dt generation
  dt: Add global option to set phandle start offset
  PPC: e500: Extend address/size of / to 64bit
  PPC: e500: Define addresses as always 64bit
  PPC: e500: Use new SOC dt format
  PPC: e500: Use new MPIC dt format
  Revert "dt: temporarily disable subtree creation failure check"
  PPC: e500: enable manual loading of dtb blob
  PPC: e500: dt: use target_phys_addr_t for ramsize
  ...
  • Loading branch information
blueswirl committed Jun 24, 2012
2 parents 959a255 + 9609169 commit 4e469a4
Show file tree
Hide file tree
Showing 35 changed files with 9,858 additions and 8,463 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
qemu-icon.bmp \
bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
mpc8544ds.dtb \
multiboot.bin linuxboot.bin kvmvapic.bin \
s390-zipl.rom \
spapr-rtas.bin slof.bin \
Expand Down
9 changes: 8 additions & 1 deletion block/raw-posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,6 @@ static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, int *pnum)
{
BDRVRawState *s = bs->opaque;
off_t start, data, hole;
int ret;

Expand All @@ -616,11 +615,15 @@ static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
}

start = sector_num * BDRV_SECTOR_SIZE;

#ifdef CONFIG_FIEMAP

BDRVRawState *s = bs->opaque;
struct {
struct fiemap fm;
struct fiemap_extent fe;
} f;

f.fm.fm_start = start;
f.fm.fm_length = (int64_t)nb_sectors * BDRV_SECTOR_SIZE;
f.fm.fm_flags = 0;
Expand All @@ -643,7 +646,11 @@ static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
data = f.fe.fe_logical;
hole = f.fe.fe_logical + f.fe.fe_length;
}

#elif defined SEEK_HOLE && defined SEEK_DATA

BDRVRawState *s = bs->opaque;

hole = lseek(s->fd, start, SEEK_HOLE);
if (hole == -1) {
/* -ENXIO indicates that sector_num was past the end of the file.
Expand Down
2 changes: 1 addition & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -3679,7 +3679,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"


case "$target_arch2" in
alpha | sparc* | xtensa*)
alpha | sparc* | xtensa* | ppc*)
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
;;
esac
Expand Down
9 changes: 9 additions & 0 deletions cpu-all.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,15 @@ extern unsigned long reserved_va;
#define stfl_kernel(p, v) stfl_raw(p, v)
#define stfq_kernel(p, vt) stfq_raw(p, v)

#ifdef CONFIG_TCG_PASS_AREG0
#define cpu_ldub_data(env, addr) ldub_raw(addr)
#define cpu_lduw_data(env, addr) lduw_raw(addr)
#define cpu_ldl_data(env, addr) ldl_raw(addr)

#define cpu_stb_data(env, addr, data) stb_raw(addr, data)
#define cpu_stw_data(env, addr, data) stw_raw(addr, data)
#define cpu_stl_data(env, addr, data) stl_raw(addr, data)
#endif
#endif /* defined(CONFIG_USER_ONLY) */

/* page related stuff */
Expand Down
108 changes: 106 additions & 2 deletions device_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,48 @@
#include "qemu-common.h"
#include "device_tree.h"
#include "hw/loader.h"
#include "qemu-option.h"
#include "qemu-config.h"

#include <libfdt.h>

#define FDT_MAX_SIZE 0x10000

void *create_device_tree(int *sizep)
{
void *fdt;
int ret;

*sizep = FDT_MAX_SIZE;
fdt = g_malloc0(FDT_MAX_SIZE);
ret = fdt_create(fdt, FDT_MAX_SIZE);
if (ret < 0) {
goto fail;
}
ret = fdt_begin_node(fdt, "");
if (ret < 0) {
goto fail;
}
ret = fdt_end_node(fdt);
if (ret < 0) {
goto fail;
}
ret = fdt_finish(fdt);
if (ret < 0) {
goto fail;
}
ret = fdt_open_into(fdt, fdt, *sizep);
if (ret) {
fprintf(stderr, "Unable to copy device tree in memory\n");
exit(1);
}

return fdt;
fail:
fprintf(stderr, "%s Couldn't create dt: %s\n", __func__, fdt_strerror(ret));
exit(1);
}

void *load_device_tree(const char *filename_path, int *sizep)
{
int dt_size;
Expand Down Expand Up @@ -88,7 +127,7 @@ static int findnode_nofail(void *fdt, const char *node_path)
}

int qemu_devtree_setprop(void *fdt, const char *node_path,
const char *property, void *val_array, int size)
const char *property, const void *val_array, int size)
{
int r;

Expand Down Expand Up @@ -117,6 +156,13 @@ int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
return r;
}

int qemu_devtree_setprop_u64(void *fdt, const char *node_path,
const char *property, uint64_t val)
{
val = cpu_to_be64(val);
return qemu_devtree_setprop(fdt, node_path, property, &val, sizeof(val));
}

int qemu_devtree_setprop_string(void *fdt, const char *node_path,
const char *property, const char *string)
{
Expand All @@ -132,6 +178,59 @@ int qemu_devtree_setprop_string(void *fdt, const char *node_path,
return r;
}

uint32_t qemu_devtree_get_phandle(void *fdt, const char *path)
{
uint32_t r;

r = fdt_get_phandle(fdt, findnode_nofail(fdt, path));
if (r <= 0) {
fprintf(stderr, "%s: Couldn't get phandle for %s: %s\n", __func__,
path, fdt_strerror(r));
exit(1);
}

return r;
}

int qemu_devtree_setprop_phandle(void *fdt, const char *node_path,
const char *property,
const char *target_node_path)
{
uint32_t phandle = qemu_devtree_get_phandle(fdt, target_node_path);
return qemu_devtree_setprop_cell(fdt, node_path, property, phandle);
}

uint32_t qemu_devtree_alloc_phandle(void *fdt)
{
static int phandle = 0x0;

/*
* We need to find out if the user gave us special instruction at
* which phandle id to start allocting phandles.
*/
if (!phandle) {
QemuOpts *machine_opts;
machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
if (machine_opts) {
const char *phandle_start;
phandle_start = qemu_opt_get(machine_opts, "phandle_start");
if (phandle_start) {
phandle = strtoul(phandle_start, NULL, 0);
}
}
}

if (!phandle) {
/*
* None or invalid phandle given on the command line, so fall back to
* default starting point.
*/
phandle = 0x8000;
}

return phandle++;
}

int qemu_devtree_nop_node(void *fdt, const char *node_path)
{
int r;
Expand All @@ -151,6 +250,7 @@ int qemu_devtree_add_subnode(void *fdt, const char *name)
char *dupname = g_strdup(name);
char *basename = strrchr(dupname, '/');
int retval;
int parent = 0;

if (!basename) {
g_free(dupname);
Expand All @@ -160,7 +260,11 @@ int qemu_devtree_add_subnode(void *fdt, const char *name)
basename[0] = '\0';
basename++;

retval = fdt_add_subnode(fdt, findnode_nofail(fdt, dupname), basename);
if (dupname[0]) {
parent = findnode_nofail(fdt, dupname);
}

retval = fdt_add_subnode(fdt, parent, basename);
if (retval < 0) {
fprintf(stderr, "FDT: Failed to create subnode %s: %s\n", name,
fdt_strerror(retval));
Expand Down
22 changes: 21 additions & 1 deletion device_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,35 @@
#ifndef __DEVICE_TREE_H__
#define __DEVICE_TREE_H__

void *create_device_tree(int *sizep);
void *load_device_tree(const char *filename_path, int *sizep);

int qemu_devtree_setprop(void *fdt, const char *node_path,
const char *property, void *val_array, int size);
const char *property, const void *val_array, int size);
int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
const char *property, uint32_t val);
int qemu_devtree_setprop_u64(void *fdt, const char *node_path,
const char *property, uint64_t val);
int qemu_devtree_setprop_string(void *fdt, const char *node_path,
const char *property, const char *string);
int qemu_devtree_setprop_phandle(void *fdt, const char *node_path,
const char *property,
const char *target_node_path);
uint32_t qemu_devtree_get_phandle(void *fdt, const char *path);
uint32_t qemu_devtree_alloc_phandle(void *fdt);
int qemu_devtree_nop_node(void *fdt, const char *node_path);
int qemu_devtree_add_subnode(void *fdt, const char *name);

#define qemu_devtree_setprop_cells(fdt, node_path, property, ...) \
do { \
uint32_t qdt_tmp[] = { __VA_ARGS__ }; \
int i; \
\
for (i = 0; i < ARRAY_SIZE(qdt_tmp); i++) { \
qdt_tmp[i] = cpu_to_be32(qdt_tmp[i]); \
} \
qemu_devtree_setprop(fdt, node_path, property, qdt_tmp, \
sizeof(qdt_tmp)); \
} while (0)

#endif /* __DEVICE_TREE_H__ */
78 changes: 78 additions & 0 deletions docs/specs/ppc-spapr-hcalls.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
When used with the "pseries" machine type, QEMU-system-ppc64 implements
a set of hypervisor calls using a subset of the server "PAPR" specification
(IBM internal at this point), which is also what IBM's proprietary hypervisor
adheres too.

The subset is selected based on the requirements of Linux as a guest.

In addition to those calls, we have added our own private hypervisor
calls which are mostly used as a private interface between the firmware
running in the guest and QEMU.

All those hypercalls start at hcall number 0xf000 which correspond
to a implementation specific range in PAPR.

- H_RTAS (0xf000)

RTAS is a set of runtime services generally provided by the firmware
inside the guest to the operating system. It predates the existence
of hypervisors (it was originally an extension to Open Firmware) and
is still used by PAPR to provide various services that aren't performance
sensitive.

We currently implement the RTAS services in QEMU itself. The actual RTAS
"firmware" blob in the guest is a small stub of a few instructions which
calls our private H_RTAS hypervisor call to pass the RTAS calls to QEMU.

Arguments:

r3 : H_RTAS (0xf000)
r4 : Guest physical address of RTAS parameter block

Returns:

H_SUCCESS : Successully called the RTAS function (RTAS result
will have been stored in the parameter block)
H_PARAMETER : Unknown token

- H_LOGICAL_MEMOP (0xf001)

When the guest runs in "real mode" (in powerpc lingua this means
with MMU disabled, ie guest effective == guest physical), it only
has access to a subset of memory and no IOs.

PAPR provides a set of hypervisor calls to perform cachable or
non-cachable accesses to any guest physical addresses that the
guest can use in order to access IO devices while in real mode.

This is typically used by the firmware running in the guest.

However, doing a hypercall for each access is extremely inefficient
(even more so when running KVM) when accessing the frame buffer. In
that case, things like scrolling become unusably slow.

This hypercall allows the guest to request a "memory op" to be applied
to memory. The supported memory ops at this point are to copy a range
of memory (supports overlap of source and destination) and XOR which
is used by our SLOF firmware to invert the screen.

Arguments:

r3: H_LOGICAL_MEMOP (0xf001)
r4: Guest physical address of destination
r5: Guest physical address of source
r6: Individual element size
0 = 1 byte
1 = 2 bytes
2 = 4 bytes
3 = 8 bytes
r7: Number of elements
r8: Operation
0 = copy
1 = xor

Returns:

H_SUCCESS : Success
H_PARAMETER : Invalid argument

4 changes: 2 additions & 2 deletions hw/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,9 @@ static void zfree(void *x, void *addr)

#define DEFLATED 8

/* This is the maximum in uboot, so if a uImage overflows this, it would
/* This is the usual maximum in uboot, so if a uImage overflows this, it would
* overflow on real hardware too. */
#define UBOOT_MAX_GUNZIP_BYTES 0x800000
#define UBOOT_MAX_GUNZIP_BYTES (64 << 20)

static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
size_t srclen)
Expand Down
2 changes: 1 addition & 1 deletion hw/ppc/Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ obj-$(CONFIG_PSERIES) += spapr_pci.o pci-hotplug.o
obj-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
obj-y += ppc440_bamboo.o
# PowerPC E500 boards
obj-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o
obj-$(CONFIG_FDT) += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o
# PowerPC 440 Xilinx ML507 reference board.
obj-y += virtex_ml507.o
# PowerPC OpenPIC
Expand Down
Loading

0 comments on commit 4e469a4

Please sign in to comment.