Skip to contentSkip to conversation

PowerPC kvm-userspace patches

PATCH Superseded Jerone Young 2 participants 17 messages Mar 12, 2008 – Mar 13, 2008

Subsystems (2)

v1 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 PowerPC kvm-userspace patches

This set of patches enables the following:
-Device tree Support
- Add libfdt to kvm-userspace
- Add bamboo device tree to qemu source
- Detection of host Device Tree attributes
- Device tree loading
- Ability to specify initrd on the command line
- Ability to add kernel arguments on the command line
- Ability to load compressed uImages
- Ability to specify memory on the command line

So now when running powerpc code on a 440board.

Known Issues:
There is an issue currently where guest kernel is not mounting the initrd. Working it now!

But these changes should go in anyway.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#1 lore raw

PATCH 1/1 Add libfdt to KVM userspace

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID cb3ca3805e7735fffcf42032b917cc761b145fb3 # Parent c8f0f8c7d872cc909bdc32c14a9e3c49d632c6e6 Add libfdt to KVM userspace

This patch adds libfdt to allow for motification of device tree entries into the KVM userspace tree.

Makefile +7 -2
@@ -5,7 +5,7 @@ DESTDIR=
 
 rpmrelease = devel
 
-.PHONY: kernel user libkvm qemu bios vgabios extboot clean
+.PHONY: kernel user libkvm qemu bios vgabios extboot clean libfdt
 
 all: libkvm qemu
 ifneq '$(filter $(ARCH), x86_64 i386 ia64)' ''
@@ -20,6 +20,9 @@ qemu: libkvm
 qemu: libkvm
 ifneq '$(filter $(ARCH), i386 x86_64)' ''
     qemu: extboot
+endif
+ifneq '$(filter $(ARCH), powerpc)' ''
+    qemu: libfdt
 endif
 user: libkvm
 
@@ -38,6 +41,8 @@ extboot:
            || ! cmp -s qemu/pc-bios/extboot.bin extboot/extboot.bin; then \
 		cp extboot/extboot.bin qemu/pc-bios/extboot.bin; \
 	fi
+libfdt:
+	$(MAKE) -C $@
 
 
 bindir = /usr/bin
@@ -88,7 +93,7 @@ srpm:
 	$(RM) $(tmpspec)
 
 clean:
-	for i in $(if $(WANT_MODULE), kernel) user libkvm qemu; do \
+	for i in $(if $(WANT_MODULE), kernel) user libkvm qemu libfdt; do \
 		make -C $$i clean; \
 	done
 	rm -f config.mak user/config.mak
configure +3 -0
@@ -103,6 +103,9 @@ fi
 
 if [ "$arch" = "powerpc" ]; then
     target_exec="ppcemb-softmmu"
+    qemu_cflags="$qemu_cflags -I $PWD/libfdt"
+    qemu_ldflags="$qemu_ldflags -L $PWD/libfdt"
+    qemu_opts="$qemu_opts --enable-libfdt"
 fi
 
 #configure user dir
libfdt/Makefile new file +19 -0
new file mode 100644
@@ -0,0 +1,19 @@
+include ../config.mak
+include ../user/config.mak
+
+LIBFDT_OBJS = fdt.o fdt_ro.o fdt_wip.o fdt_sw.o fdt_rw.o fdt_strerror.o
+
+LIBFDT_INCLUDES = fdt.h libfdt.h
+LIBFDT_EXTRA = libfdt_internal.h
+
+LIBFDT_LIB = libfdt.a
+
+CFLAGS += -I .
+
+all: libfdt.a
+
+libfdt.a: $(LIBFDT_OBJS)
+	$(AR) rcs $@ $^
+
+clean: 
+	rm -rf *.o *.a
libfdt/Makefile.libfdt new file +14 -0
new file mode 100644
@@ -0,0 +1,14 @@
+# Makefile.libfdt
+#
+# This is not a complete Makefile of itself.  Instead, it is designed to
+# be easily embeddable into other systems of Makefiles.
+#
+LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
+LIBFDT_INCLUDES = fdt.h libfdt.h
+LIBFDT_EXTRA = libfdt_internal.h
+LIBFDT_LIB = libfdt/libfdt.a
+
+LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
+
+$(LIBFDT_objdir)/$(LIBFDT_LIB): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
+
libfdt/README new file +2 -0
new file mode 100644
@@ -0,0 +1,2 @@
+libfdt was grabbed from dtc source. It can be found here:
+http://www.jdl.com/git_repos/?p=dtc.git;a=summary
libfdt/fdt.c new file +194 -0

194 lines not on this page · raw message

libfdt/fdt.h new file +60 -0

60 lines not on this page · raw message

libfdt/fdt_ro.c new file +476 -0

476 lines not on this page · raw message

libfdt/fdt_rw.c new file +467 -0

467 lines not on this page · raw message

libfdt/fdt_strerror.c new file +96 -0

96 lines not on this page · raw message

libfdt/fdt_sw.c new file +258 -0

258 lines not on this page · raw message

libfdt/fdt_wip.c new file +144 -0

144 lines not on this page · raw message

libfdt/libfdt.h new file +1076 -0

1,076 lines not on this page · raw message

libfdt/libfdt_env.h new file +22 -0
new file mode 100644
@@ -0,0 +1,22 @@
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <endian.h>
+#include <byteswap.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define fdt32_to_cpu(x)		(x)
+#define cpu_to_fdt32(x)		(x)
+#define fdt64_to_cpu(x)		(x)
+#define cpu_to_fdt64(x)		(x)
+#else
+#define fdt32_to_cpu(x)		(bswap_32((x)))
+#define cpu_to_fdt32(x)		(bswap_32((x)))
+#define fdt64_to_cpu(x)		(bswap_64((x)))
+#define cpu_to_fdt64(x)		(bswap_64((x)))
+#endif
+
+#endif /* _LIBFDT_ENV_H */
libfdt/libfdt_internal.h new file +96 -0

96 lines not on this page · raw message

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#2 lore raw

Re: [kvm-ppc-devel] [PATCH 1 of 7] Add libfdt to KVM userspace

Quoted 33 lines · Jerone Young
libfdt/Makefile new file +19 -0
new file mode 100644
@@ -0,0 +1,19 @@
+include ../config.mak
+include ../user/config.mak
+
+LIBFDT_OBJS = fdt.o fdt_ro.o fdt_wip.o fdt_sw.o fdt_rw.o fdt_strerror.o
+
+LIBFDT_INCLUDES = fdt.h libfdt.h
+LIBFDT_EXTRA = libfdt_internal.h
+
+LIBFDT_LIB = libfdt.a
+
+CFLAGS += -I .
+
+all: libfdt.a
+
+libfdt.a: $(LIBFDT_OBJS)
+	$(AR) rcs $@ $^
+
+clean: 
+	rm -rf *.o *.a
libfdt/Makefile.libfdt new file +4 -0
new file mode 100644
@@ -0,0 +1,14 @@
+# Makefile.libfdt
+#
+# This is not a complete Makefile of itself.  Instead, it is designed to
+# be easily embeddable into other systems of Makefiles.

libfdt/Makefile.libfdt line 14

Quoted 10 lines
libfdt/Makefile.libfdt new file +10 -0
+#
+LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
+LIBFDT_INCLUDES = fdt.h libfdt.h
+LIBFDT_EXTRA = libfdt_internal.h
+LIBFDT_LIB = libfdt/libfdt.a
+
+LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
+
+$(LIBFDT_objdir)/$(LIBFDT_LIB): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
+

Why are you duplicating Makefile.libfdt instead of including it?

Signature · 8 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#3 lore raw

PATCH 1/1 Add libfdt support to qemu

In reply to Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 36d2646a3c3d42021425febf3d14f0500ebbaace # Parent cb3ca3805e7735fffcf42032b917cc761b145fb3 Add libfdt support to qemu

This patch adds needed configuration options to compile in libfdt support into qemu.

qemu/Makefile.target +5 -0
@@ -555,6 +555,11 @@ ifdef CONFIG_VNC_TLS
 ifdef CONFIG_VNC_TLS
 CPPFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
 LIBS += $(CONFIG_VNC_TLS_LIBS)
+endif
+
+ifdef CONFIG_LIBFDT
+LIBS += -lfdt
+DEPLIBS += libfdt.a
 endif
 
 # SCSI layer
qemu/configure +8 -0
@@ -112,6 +112,7 @@ uname_release=""
 uname_release=""
 curses="yes"
 cpu_emulation="yes"
+device_tree_support="no"
 
 # OS specific
 targetos=`uname -s`
@@ -345,6 +346,8 @@ for opt do
   ;;
   --disable-cpu-emulation) cpu_emulation="no"
   ;;
+  --enable-libfdt) device_tree_support="yes"
+  ;;
   *) echo "ERROR: unknown option $opt"; exit 1
   ;;
   esac
@@ -449,6 +452,7 @@ echo "  --enable-uname-release=R Return 
 echo "  --enable-uname-release=R Return R for uname -r in usermode emulation"
 echo "  --sparc_cpu=V            Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9"
 echo "  --disable-cpu-emulation  disables use of qemu cpu emulation code"
+echo "  --enable-libfdt 	 enable libfdt support for device tree support"
 echo ""
 echo "NOTE: The object files are built at the place where configure is launched"
 exit 1
@@ -1186,6 +1190,10 @@ elif test "$target_cpu" = "ppcemb" ; the
   echo "#define TARGET_ARCH \"ppcemb\"" >> $config_h
   echo "#define TARGET_PPC 1" >> $config_h
   echo "#define TARGET_PPCEMB 1" >> $config_h
+  if test "$device_tree_support" = "yes" ; then
+      echo "#define CONFIG_LIBFDT 1" >> $config_h
+      echo "CONFIG_LIBFDT=1" >> $config_mak
+  fi
   configure_kvm
 elif test "$target_cpu" = "ppc64" ; then
   echo "TARGET_ARCH=ppc64" >> $config_mak

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#4 lore raw

PATCH 1/1 Create new load_uboot() & gunzip support to uboot loader in Qemu

In reply to Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 48651677b7d05254d6acf03551bfea05cef8aa47
# Parent 36d2646a3c3d42021425febf3d14f0500ebbaace Create new load_uboot() & gunzip support to uboot loader in Qemu

This patch adds the ability for the load address to be caputred when loading a uImage or cuImage. It also adds a better return code as the size can be an usigned long. This is done by creating a new function prototype and calling it load_uboot_l . To keep compatibility with code already using the old load_uboot a wrapper function has been created so current callers will not break them.

Also added is gunzip support to allow for loading of uimages with a compressed kenrel imagexs.

qemu/loader.c +138 -9
@@ -26,6 +26,8 @@
 #include "sysemu.h"
 #include "uboot_image.h"
 
+#include <zlib.h>
+
 /* return the size or -1 if error */
 int get_image_size(const char *filename)
 {
@@ -263,14 +265,103 @@ static void bswap_uboot_header(uboot_ima
 }
 
 /* Load a U-Boot image.  */
-int load_uboot(const char *filename, target_ulong *ep, int *is_linux)
-{
-
+
+/* gunzip functionality is derived from gunzip function 
+ * in uboot source code 
+ */
+
+#define	ZALLOC_ALIGNMENT	16
+
+static void *zalloc(void *x, unsigned items, unsigned size)
+{
+	void *p;
+
+	size *= items;
+	size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
+
+	p = malloc (size);
+
+	return (p);
+}
+
+static void zfree(void *x, void *addr, unsigned nb)
+{
+	free (addr);
+}
+
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+static int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
+{
+	z_stream s;
+	int r, i, flags;
+
+	/* skip header */
+	i = 10;
+	flags = src[3];
+	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+		puts ("Error: Bad gzipped data\n");
+		return -1;
+	}
+	if ((flags & EXTRA_FIELD) != 0)
+		i = 12 + src[10] + (src[11] << 8);
+	if ((flags & ORIG_NAME) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & COMMENT) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & HEAD_CRC) != 0)
+		i += 2;
+	if (i >= *lenp) {
+		puts ("Error: gunzip out of data in header\n");
+		return -1;
+	}
+
+	s.zalloc = zalloc;
+	s.zfree = zfree;
+
+	r = inflateInit2(&s, -MAX_WBITS);
+	if (r != Z_OK) {
+		printf ("Error: inflateInit2() returned %d\n", r);
+		return (-1);
+	}
+	s.next_in = src + i;
+	s.avail_in = *lenp - i;
+	s.next_out = dst;
+	s.avail_out = dstlen;
+	r = inflate(&s, Z_FINISH);
+	if (r != Z_OK && r != Z_STREAM_END) {
+		printf ("Error: inflate() returned %d\n", r);
+		return -1;
+	}
+	*lenp = s.next_out - (unsigned char *) dst;
+	inflateEnd(&s);
+
+	return 0;
+}
+
+
+#define MAX_KERNEL_SIZE 8*1024*1024  //8MB
+int load_uboot_l(const char *filename, target_ulong *ep,
+                  target_ulong *la, 
+                  target_ulong *loaded_image_size,
+                  int *is_linux)
+{
     int fd;
     int size;
+    int ret;
     uboot_image_header_t h;
     uboot_image_header_t *hdr = &h;
     uint8_t *data = NULL;
+    uint8_t *uncompressed_data = NULL;
 
     fd = open(filename, O_RDONLY | O_BINARY);
     if (fd < 0)
@@ -291,13 +382,14 @@ int load_uboot(const char *filename, tar
         goto fail;
     }
 
-    /* TODO: Implement compressed images.  */
-    if (hdr->ih_comp != IH_COMP_NONE) {
-        fprintf(stderr, "Unable to load compressed u-boot images\n");
+    /* TODO bzip2 support */
+    if (hdr->ih_comp == IH_COMP_BZIP2) {
+        fprintf(stderr, "Unable to load bzip2 compressed u-boot images\n");
         goto fail;
     }
 
     /* TODO: Check CPU type.  */
+
     if (is_linux) {
         if (hdr->ih_type == IH_TYPE_KERNEL && hdr->ih_os == IH_OS_LINUX)
             *is_linux = 1;
@@ -306,6 +398,8 @@ int load_uboot(const char *filename, tar
     }
 
     *ep = hdr->ih_ep;
+    *la = hdr->ih_load;
+
     data = qemu_malloc(hdr->ih_size);
     if (!data)
         goto fail;
@@ -315,9 +409,29 @@ int load_uboot(const char *filename, tar
         goto fail;
     }
 
-    cpu_physical_memory_write_rom(hdr->ih_load, data, hdr->ih_size);
-
-    return hdr->ih_size;
+    *loaded_image_size = hdr->ih_size;
+    
+    if (hdr->ih_comp == IH_COMP_GZIP) {
+	uncompressed_data = qemu_malloc(MAX_KERNEL_SIZE);
+	ret = gunzip(uncompressed_data, MAX_KERNEL_SIZE,
+                    (unsigned char *) data, 
+                    loaded_image_size);
+
+	if (ret < 0) {
+            fprintf(stderr, "Unable to decompress gziped image!\n");
+            goto fail;
+        }
+
+        qemu_free(data);
+        cpu_physical_memory_write_rom(hdr->ih_load, uncompressed_data,
+                                      *loaded_image_size);
+
+    }
+    else {
+        cpu_physical_memory_write_rom(hdr->ih_load, data, *loaded_image_size);
+    }
+
+    return 0;
 
 fail:
     if (data)
@@ -325,3 +439,18 @@ fail:
     close(fd);
     return -1;
 }
+
+
+int load_uboot(const char *filename, target_ulong *ep, int *is_linux)
+{
+    target_ulong la;
+    target_ulong size;
+    int ret;
+
+    ret = load_uboot_l(filename, ep, &la, &size, is_linux);
+
+    if (ret < 0)
+	return ret;
+    else
+	return (int)size;
+}
qemu/sysemu.h +3 -0
@@ -182,6 +182,9 @@ int load_elf(const char *filename, int64
              uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr);
 int load_aout(const char *filename, uint8_t *addr);
 int load_uboot(const char *filename, target_ulong *ep, int *is_linux);
+int load_uboot_l(const char *filename, target_ulong *ep, 
+             target_ulong *la, target_ulong *loaded_image_size,
+             int *is_linux);
 #endif
 
 #ifdef HAS_AUDIO

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#5 lore raw

Re: [kvm-ppc-devel] [PATCH 3 of 7] Create new load_uboot() & gunzip support to uboot loader in Qemu

qemu/sysemu.h int load_elf(const char *filename, int64 · line 190

Quoted 13 lines · Jerone Young
qemu/sysemu.h +3 -0
@@ -182,6 +182,9 @@ int load_elf(const char *filename, int64
              uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr);
 int load_aout(const char *filename, uint8_t *addr);
 int load_uboot(const char *filename, target_ulong *ep, int *is_linux);
+int load_uboot_l(const char *filename, target_ulong *ep, 
+             target_ulong *la, target_ulong *loaded_image_size,
+             int *is_linux);
 #endif
 
 #ifdef HAS_AUDIO

I don't like the "_l" name, nor "la". Without reading the code I have no idea what those mean.

Can't you just update the other load_uboot() callers? There are only 4 of them... and while you're at it, you should rename the function to load_uimage(). Pass NULL for whatever you rename "la" to, just like "is_linux" is handled already.

Signature · 8 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#6 lore raw

Re: [kvm-ppc-devel] [PATCH 3 of 7] Create new load_uboot() & gunzip support to uboot loader in Qemu

Quoted 18 lines · Hollis Blanchard

qemu/sysemu.h int load_elf(const char *filename, int64 · line 190

Quoted 13 lines · Jerone Young
qemu/sysemu.h +3 -0
@@ -182,6 +182,9 @@ int load_elf(const char *filename, int64
              uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr);
 int load_aout(const char *filename, uint8_t *addr);
 int load_uboot(const char *filename, target_ulong *ep, int *is_linux);
+int load_uboot_l(const char *filename, target_ulong *ep, 
+             target_ulong *la, target_ulong *loaded_image_size,
+             int *is_linux);
 #endif
 
 #ifdef HAS_AUDIO

I don't like the "_l" name, nor "la". Without reading the code I have no idea what those mean.

Quoted 4 lines

Can't you just update the other load_uboot() callers? There are only 4 of them... and while you're at it, you should rename the function to load_uimage(). Pass NULL for whatever you rename "la" to, just like "is_linux" is handled already.

I changed the name to load_uimage() .. but still going to keep load_uboot() wrapper until this actually makes it to upstream qemu. Then it will make since to add changing all the others and then removing the wrapper.

Quoted 1 line

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#7 lore raw

PATCH 1/1 Add PPC 440EP bamboo board device tree source & binary into qemu

In reply to Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 9c15709640cd55bf6f782d6856423363312493bb
# Parent 48651677b7d05254d6acf03551bfea05cef8aa47
Add PPC 440EP bamboo board device tree source & binary into qemu

This patch places the bamboo device tree for the PPC 440EP bamboo board into the pc-bios directory of the qemu source. This also adds a rule into the pc-bios/Makefile to build device tree files.

qemu/pc-bios/Makefile +4 -1
@@ -12,6 +12,9 @@ all: $(TARGETS)
 %.o: %.S
 	$(CC) $(DEFINES) -c -o $@ $<
 
+%.dtb: %.dts 
+	dtc -O dtb -I dts -o $@ $< 
+
 clean:
-	rm -f $(TARGETS) *.o *~
+	rm -f $(TARGETS) *.o *~ *.dtb
 
qemu/pc-bios/bamboo.dts new file +310 -0

310 lines not on this page · raw message

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#8 lore raw

Re: [kvm-ppc-devel] [PATCH 4 of 7] Add PPC 440EP bamboo board device tree source & binary into qemu

Quoted 33 lines · Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 9c15709640cd55bf6f782d6856423363312493bb
# Parent 48651677b7d05254d6acf03551bfea05cef8aa47
Add PPC 440EP bamboo board device tree source & binary into qemu

This patch places the bamboo device tree for the PPC 440EP bamboo board into the pc-bios directory of the qemu source. This also adds a rule into the pc-bios/Makefile to build device tree files.

qemu/pc-bios/Makefile +4 -1
@@ -12,6 +12,9 @@ all: $(TARGETS)
 %.o: %.S
 	$(CC) $(DEFINES) -c -o $@ $<
 
+%.dtb: %.dts 
+	dtc -O dtb -I dts -o $@ $< 
+
 clean:
-	rm -f $(TARGETS) *.o *~
+	rm -f $(TARGETS) *.o *~ *.dtb
 
qemu/pc-bios/bamboo.dts new file +0 -0
new file mode 100644

qemu/pc-bios/bamboo.dts line 7

Quoted 7 lines
qemu/pc-bios/bamboo.dts new file +7 -0
@@ -0,0 +1,310 @@
+/*
+ * Device Tree Source for AMCC Bamboo
+ *
+ * Copyright (c) 2006, 2007 IBM Corp.
+ * Josh Boyer <[email protected]>
+ *
+ * FIXME: Draft only!

Might as well remove this. In its place, add a little blurb explaining how this file is used, and how qemu modifies the binary device tree at runtime.

Quoted 10 lines
qemu/pc-bios/bamboo.dts new file +10 -0
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <1>;
+	model = "amcc,bamboo";
+	compatible = "amcc,bamboo";

qemu/pc-bios/bamboo.dts line 28

Quoted 10 lines
qemu/pc-bios/bamboo.dts new file +10 -0
+	dcr-parent = <&/cpus/cpu@0>;
+
+	aliases {
+/*		ethernet0 = &EMAC0;  */
+/*		ethernet1 = &EMAC1;  *
+		serial0 = &UART0;
+ 		serial1 = &UART1;   
+/*		serial2 = &UART2;    */
+/*		serial3 = &UART3;    */
+	};

Please just remove all the stuff you've commented out.

Quoted 12 lines
qemu/pc-bios/bamboo.dts new file +12 -0
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			model = "PowerPC,440EP";
+			reg = <0>;
+			clock-frequency = <1fca0550>; /* Filled in by zImage */
+			timebase-frequency = <017d7840>; /* Filled in by zImage */
+			i-cache-line-size = <20>;
+			d-cache-line-size = <20>;

qemu/pc-bios/bamboo.dts line 52

Quoted 10 lines
qemu/pc-bios/bamboo.dts new file +10 -0
+			i-cache-size = <8000>;
+			d-cache-size = <8000>;
+			dcr-controller;
+			dcr-access-method = "native";
+		};
+	};
+	memory {
+		device_type = "memory";
+		reg = <0 0 9000000>; /* Filled in by zImage */
+	};

Also remove all references to "zImage".

Quoted 12 lines
qemu/pc-bios/bamboo.dts new file +12 -0
+	UIC0: interrupt-controller0 {
+		compatible = "ibm,uic-440ep","ibm,uic";
+		interrupt-controller;
+		cell-index = <0>;
+		dcr-reg = <0c0 009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+	};
+/*
+	UIC1: interrupt-controller1 {
+		compatible = "ibm,uic-440ep","ibm,uic";

qemu/pc-bios/bamboo.dts line 75

Quoted 10 lines
qemu/pc-bios/bamboo.dts new file +10 -0
+		interrupt-controller;
+		cell-index = <1>;
+		dcr-reg = <0d0 009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <1e 4 1f 4>; 
+		interrupt-parent = <&UIC0>;
+	};
+*/

Is it difficult to add UIC1 to our 440EP init code?

Quoted 30 lines
qemu/pc-bios/bamboo.dts new file +30 -0
+
+		PCI0: pci@ec000000 {
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			compatible = "ibm,plb440ep-pci", "ibm,plb-pci";
+			primary;
+			reg = <0 eec00000 8	/* Config space access */
+			       0 eed00000 4	/* IACK */
+			       0 eed00000 4	/* Special cycle */
+			       0 ef400000 40>;	/* Internal registers */
+
+			/* Outbound ranges, one memory and one IO,
+			 * later cannot be changed. Chip supports a second
+			 * IO range but we don't use it for now
+			 */
+			ranges = <02000000 0 a0000000 0 a0000000 0 20000000
+				  01000000 0 00000000 0 e8000000 0 00010000>;
+
+			/* Inbound 2GB range starting at 0 */
+			dma-ranges = <42000000 0 0 0 0 0 80000000>;
+
+			/* Bamboo has all 4 IRQ pins tied together per slot */
+			interrupt-map-mask = <f800 0 0 0>;
+			interrupt-map = <
+				/* IDSEL 1 */
+				0800 0 0 0 &UIC0 1c 8
+
+				/* IDSEL 2 */

qemu/pc-bios/bamboo.dts line 302

Quoted 10 lines
qemu/pc-bios/bamboo.dts new file +10 -0
+				1000 0 0 0 &UIC0 1b 8
+
+				/* IDSEL 3 */
+				1800 0 0 0 &UIC0 1a 8
+
+				/* IDSEL 4 */
+				2000 0 0 0 &UIC0 19 8
+			>;
+		};
+	};

PCI0 is the only node you might want to leave commented out, since we will have a patch for that in the near future.

However, since we haven't posted that patch yet, the PCI0 node shouldn't be visible to the guest yet.

qemu/pc-bios/bamboo.dts line 310

Quoted 7 lines
qemu/pc-bios/bamboo.dts new file +7 -0
+	chosen {
+		linux,stdout-path = "/plb/opb/serial@ef600300";
+		linux,initrd-start = <0>;
+		linux,initrd-end = <0>;
+		bootargs = "                ";
+	};
+};

Why is bootargs filled with spaces? Also, do the initrd properties need to be present? I thought you figured out how to add them at runtime.

Signature · 8 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#9 lore raw

Re: [kvm-ppc-devel] [PATCH 4 of 7] Add PPC 440EP bamboo board device tree source & binary into qemu

Quoted 60 lines · Hollis Blanchard
Quoted 33 lines · Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 9c15709640cd55bf6f782d6856423363312493bb
# Parent 48651677b7d05254d6acf03551bfea05cef8aa47
Add PPC 440EP bamboo board device tree source & binary into qemu

This patch places the bamboo device tree for the PPC 440EP bamboo board into the pc-bios directory of the qemu source. This also adds a rule into the pc-bios/Makefile to build device tree files.

qemu/pc-bios/Makefile +4 -1
@@ -12,6 +12,9 @@ all: $(TARGETS)
 %.o: %.S
 	$(CC) $(DEFINES) -c -o $@ $<
 
+%.dtb: %.dts 
+	dtc -O dtb -I dts -o $@ $< 
+
 clean:
-	rm -f $(TARGETS) *.o *~
+	rm -f $(TARGETS) *.o *~ *.dtb
 
qemu/pc-bios/bamboo.dts new file +0 -0
new file mode 100644

qemu/pc-bios/bamboo.dts line 7

Quoted 7 lines
qemu/pc-bios/bamboo.dts new file +7 -0
@@ -0,0 +1,310 @@
+/*
+ * Device Tree Source for AMCC Bamboo
+ *
+ * Copyright (c) 2006, 2007 IBM Corp.
+ * Josh Boyer <[email protected]>
+ *
+ * FIXME: Draft only!

Might as well remove this. In its place, add a little blurb explaining how this file is used, and how qemu modifies the binary device tree at runtime.

Quoted 14 lines
qemu/pc-bios/bamboo.dts new file +14 -0
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <1>;
+	model = "amcc,bamboo";
+	compatible = "amcc,bamboo";
+	dcr-parent = <&/cpus/cpu@0>;
+
+	aliases {
+/*		ethernet0 = &EMAC0;  */
Quoted 8 lines

qemu/pc-bios/bamboo.dts line 28

Quoted 6 lines
qemu/pc-bios/bamboo.dts new file +6 -0
+/*		ethernet1 = &EMAC1;  *
+		serial0 = &UART0;
+ 		serial1 = &UART1;   
+/*		serial2 = &UART2;    */
+/*		serial3 = &UART3;    */
+	};

Please just remove all the stuff you've commented out.

Ok mainly just commented out stuff so that if we later wanted to have it (for what ever reason), it could just be uncommented.

Quoted 17 lines
Quoted 17 lines
qemu/pc-bios/bamboo.dts new file +16 -0
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			model = "PowerPC,440EP";
+			reg = <0>;
+			clock-frequency = <1fca0550>; /* Filled in by zImage */
+			timebase-frequency = <017d7840>; /* Filled in by zImage */
+			i-cache-line-size = <20>;
+			d-cache-line-size = <20>;
+			i-cache-size = <8000>;
+			d-cache-size = <8000>;
+			dcr-controller;
+			dcr-access-method = "native";
Quoted 8 lines

qemu/pc-bios/bamboo.dts line 52

Quoted 6 lines
qemu/pc-bios/bamboo.dts new file +6 -0
+		};
+	};
+	memory {
+		device_type = "memory";
+		reg = <0 0 9000000>; /* Filled in by zImage */
+	};

Also remove all references to "zImage".

I can. Though this helped me to determine which variables that need to be filled in. I'll still have it in some places till I have the code to fill them in.

Quoted 17 lines
Quoted 17 lines
qemu/pc-bios/bamboo.dts new file +16 -0
+	UIC0: interrupt-controller0 {
+		compatible = "ibm,uic-440ep","ibm,uic";
+		interrupt-controller;
+		cell-index = <0>;
+		dcr-reg = <0c0 009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+	};
+/*
+	UIC1: interrupt-controller1 {
+		compatible = "ibm,uic-440ep","ibm,uic";
+		interrupt-controller;
+		cell-index = <1>;
+		dcr-reg = <0d0 009>;
+		#address-cells = <0>;
Quoted 8 lines

qemu/pc-bios/bamboo.dts line 75

Quoted 6 lines
qemu/pc-bios/bamboo.dts new file +6 -0
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <1e 4 1f 4>; 
+		interrupt-parent = <&UIC0>;
+	};
+*/

Is it difficult to add UIC1 to our 440EP init code?

I'll leave this commented. But will have to try adding once bigger issues are taken care of.

Quoted 48 lines
Quoted 31 lines
qemu/pc-bios/bamboo.dts new file +30 -0
+
+		PCI0: pci@ec000000 {
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			compatible = "ibm,plb440ep-pci", "ibm,plb-pci";
+			primary;
+			reg = <0 eec00000 8	/* Config space access */
+			       0 eed00000 4	/* IACK */
+			       0 eed00000 4	/* Special cycle */
+			       0 ef400000 40>;	/* Internal registers */
+
+			/* Outbound ranges, one memory and one IO,
+			 * later cannot be changed. Chip supports a second
+			 * IO range but we don't use it for now
+			 */
+			ranges = <02000000 0 a0000000 0 a0000000 0 20000000
+				  01000000 0 00000000 0 e8000000 0 00010000>;
+
+			/* Inbound 2GB range starting at 0 */
+			dma-ranges = <42000000 0 0 0 0 0 80000000>;
+
+			/* Bamboo has all 4 IRQ pins tied together per slot */
+			interrupt-map-mask = <f800 0 0 0>;
+			interrupt-map = <
+				/* IDSEL 1 */
+				0800 0 0 0 &UIC0 1c 8
+
+				/* IDSEL 2 */

qemu/pc-bios/bamboo.dts line 302

Quoted 10 lines
qemu/pc-bios/bamboo.dts new file +10 -0
+				1000 0 0 0 &UIC0 1b 8
+
+				/* IDSEL 3 */
+				1800 0 0 0 &UIC0 1a 8
+
+				/* IDSEL 4 */
+				2000 0 0 0 &UIC0 19 8
+			>;
+		};
+	};

PCI0 is the only node you might want to leave commented out, since we will have a patch for that in the near future.

However, since we haven't posted that patch yet, the PCI0 node shouldn't be visible to the guest yet.

Quoted 10 lines

qemu/pc-bios/bamboo.dts line 310

Quoted 7 lines
qemu/pc-bios/bamboo.dts new file +7 -0
+	chosen {
+		linux,stdout-path = "/plb/opb/serial@ef600300";
+		linux,initrd-start = <0>;
+		linux,initrd-end = <0>;
+		bootargs = "                ";
+	};
+};

Why is bootargs filled with spaces? Also, do the initrd properties need to be present? I thought you figured out how to add them at runtime.

These are going to be removed. I left them in. But they actually don't need to be here at all.

Quoted 1 line

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#10 lore raw

PATCH 1/1 Add dynamic device tree manipulation & change uboot loader for PPC bamboo board model

In reply to Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 50fddb23a4c19ec6f359a4dd39e98712eb6bcaeb
# Parent 9c15709640cd55bf6f782d6856423363312493bb
Add dynamic device tree manipulation & change uboot loader for PPC bamboo board model

This patch adds code to dynamically manipulate the device tree when loaded into memory. This allows us to finally have the ability to manipulate the kernel command line & initrd from the qemu command line. This will also let us setup different settings for the board.

This patch also now uses new uboot loader uboot_loader_l() to load kernel image.

qemu/Makefile.target +1 -1
@@ -615,7 +615,7 @@ OBJS+= unin_pci.o ppc_chrp.o
 OBJS+= unin_pci.o ppc_chrp.o
 # PowerPC 4xx boards
 OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
-OBJS+= ppc440.o ppc440_bamboo.o
+OBJS+= ppc440.o ppc440_bamboo.o ppc_device_tree_support.o
 endif
 ifeq ($(TARGET_BASE_ARCH), mips)
 OBJS+= mips_r4k.o mips_malta.o mips_pica61.o mips_mipssim.o
qemu/hw/ppc440_bamboo.c +71 -16

131 lines not on this page · raw message

qemu/hw/ppc_device_tree_support.c new file +223 -0

223 lines not on this page · raw message

qemu/hw/ppc_device_tree_support.h new file +26 -0
new file mode 100644
@@ -0,0 +1,26 @@
+/*
+ * Header with function prototypes to help device tree manipulation using 
+ * libfdt. It also provides functions to read entries from device tree proc
+ * interface.
+ *
+ * Copyright 2008 IBM Corporation.
+ * Authors: Jerone Young <[email protected]>
+ *
+ * This work is licensed under the GNU GPL licence version 2 or later.
+ *
+ */
+
+/* device-tree proc support functions */
+uint32_t get_proc_dt_prop_cpu_clock_freq(void);
+uint32_t get_proc_dt_prop_cpu_timebase_freq(void);
+
+#ifdef CONFIG_LIBFDT
+/* device tree functions */ 
+void *load_device_tree(char *filename_path, target_ulong load_addr);
+void dump_device_tree_to_file(void *fdt, char *filename);
+void set_dt_cpu_0_clock_freq_prop(void *fdt, uint32_t freq);
+void set_dt_cpu_0_timebase_prop(void *fdt, uint32_t timebase);
+void set_dt_initrd_start_prop(void *fdt, uint32_t start_addr);
+void set_dt_initrd_end_prop(void *fdt, uint32_t end_addr);
+void set_dt_bootargs_prop(void *fdt, char *cmdline);
+#endif

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#11 lore raw

Re: [kvm-ppc-devel] [PATCH 5 of 7] Add dynamic device tree manipulation & change uboot loader for PPC bamboo board model

You've misspelled "licence" several times in this patch.

Quoted 9 lines · Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 50fddb23a4c19ec6f359a4dd39e98712eb6bcaeb
# Parent 9c15709640cd55bf6f782d6856423363312493bb
Add dynamic device tree manipulation & change uboot loader for PPC bamboo board model

Quoted 7 lines

This patch adds code to dynamically manipulate the device tree when loaded into memory. This allows us to finally have the ability to manipulate the kernel command line & initrd from the qemu command line. This will also let us setup different settings for the board.

This patch also now uses new uboot loader uboot_loader_l() to load kernel image.

So the load_uboot() part should be a separate patch, right?

Quoted 124 lines
qemu/Makefile.target +1 -1
@@ -615,7 +615,7 @@ OBJS+= unin_pci.o ppc_chrp.o
 OBJS+= unin_pci.o ppc_chrp.o
 # PowerPC 4xx boards
 OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
-OBJS+= ppc440.o ppc440_bamboo.o
+OBJS+= ppc440.o ppc440_bamboo.o ppc_device_tree_support.o
 endif
 ifeq ($(TARGET_BASE_ARCH), mips)
 OBJS+= mips_r4k.o mips_malta.o mips_pica61.o mips_mipssim.o
qemu/hw/ppc440_bamboo.c +57 -8
@@ -8,11 +8,12 @@
  *
  */
 
+#include "config.h"
 #include "ppc440.h"
+#include "qemu-kvm.h"
+#include "ppc_device_tree_support.h"
 
-#define KERNEL_LOAD_ADDR 0x400000 /* uboot loader puts kernel at 4MB */
-
-#include "qemu-kvm.h"
+#define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
 
 /* PPC 440 refrence demo board
  *
@@ -26,14 +27,22 @@ void bamboo_init(ram_addr_t ram_size, in
 			const char *initrd_filename,
 			const char *cpu_model)
 {
+	char buf[1024];	
 	target_phys_addr_t ram_bases[2], ram_sizes[2];
 	qemu_irq *pic;
 	CPUState *env;
-	target_ulong ep;
+	target_ulong ep=0;
+	target_ulong la=0;
 	int is_linux=1; /* Will assume allways is Linux for now */
-	long kernel_size=0;
+	target_long kernel_size=0;
 	target_ulong initrd_base=0;
-	target_ulong initrd_size=0;
+	target_long initrd_size=0;
+	target_ulong dt_base=0;
+	void *fdt;
+	int ret;
+
+	uint32_t cpu_freq;
+	uint32_t timebase_freq;
 
 	printf("%s: START\n", __func__);
 
@@ -78,18 +87,23 @@ void bamboo_init(ram_addr_t ram_size, in
 
 	/* load kernel with uboot loader */
 	printf("%s: load kernel\n", __func__);
-	kernel_size = load_uboot(kernel_filename, &ep, &is_linux);
+	load_uboot_l(kernel_filename, &ep, &la, &kernel_size, &is_linux);
 	if (kernel_size < 0) {
 		fprintf(stderr, "qemu: could not load kernel '%s'\n",
 			kernel_filename);
 		exit(1);
 	}
+	printf("kernel is at guest address: 0x%lx\n", (unsigned long)la);
 
 	/* load initrd */
 	if (initrd_filename) {
-		initrd_base = kernel_size + KERNEL_LOAD_ADDR;
+        	initrd_base = kernel_size + la;
+		printf("%s: load initrd\n", __func__);
 		initrd_size = load_image(initrd_filename,
 				phys_ram_base + initrd_base);
+
+		printf("initrd is at guest address: 0x%lx\n", 
+					(unsigned long) initrd_base);
 
 		if (initrd_size < 0) {
 			fprintf(stderr,
@@ -99,17 +113,58 @@ void bamboo_init(ram_addr_t ram_size, in
 		}
 	}
 
+#ifdef CONFIG_LIBFDT
+	/* get variable for device tree */
+	cpu_freq = get_proc_dt_prop_cpu_clock_freq();
+	timebase_freq = get_proc_dt_prop_cpu_timebase_freq();
+
+	/* load binary device tree into qemu (not guest memory) */
+	printf("%s: load device tree file\n", __func__);
+	
+	snprintf(buf, sizeof(buf), "%s/%s", bios_dir, 
+		BINARY_DEVICE_TREE_FILE);
+
+	/* set base for device tree that will be in guest memory */	
+	if (initrd_base)
+		dt_base = initrd_base + initrd_size;
+	else
+		dt_base = kernel_size + la;
+
+	fdt = load_device_tree(buf, (phys_ram_base + dt_base));
+	if (fdt == NULL) {
+		printf("Loading device tree failed!\n");
+		exit(1);
+	}
+
+	printf("device tree address is at guest address: 0x%lx\n", 
+		(unsigned long) dt_base);
+
+	/* manipulate device tree in memory */
+	set_dt_cpu_0_clock_freq_prop(fdt, cpu_freq);
+	set_dt_cpu_0_timebase_prop(fdt, timebase_freq);
+
+	set_dt_initrd_start_prop(fdt, initrd_base);
+	set_dt_initrd_end_prop(fdt, (initrd_base + initrd_size));
+
+	set_dt_bootargs_prop(fdt, kernel_cmdline);
+#endif

qemu/hw/ppc440_bamboo.c void bamboo_init(ram_addr_t ram_size, in · line 155

Quoted 10 lines
qemu/hw/ppc440_bamboo.c +3 -5
+
 	if (kvm_enabled()) {
-	    /* XXX insert TLB entries */
-	    env->gpr[1] = (16<<20) - 8;
-	    env->gpr[4] = initrd_base;
-	    env->gpr[5] = initrd_size;
 
-	    env->nip = ep;
+		/* XXX insert TLB entries */
+		env->gpr[1] = (16<<20) - 8;

Please fix your whitespace.

qemu/hw/ppc440_bamboo.c void bamboo_init(ram_addr_t ram_size, in · line 163

Quoted 10 lines
qemu/hw/ppc440_bamboo.c +7 -3
-	    env->cpu_index = 0;
-	    printf("%s: loading kvm registers\n", __func__);
-	    kvm_load_registers(env);
+#ifdef CONFIG_LIBFDT
+		/* location of device tree in register */
+		env->gpr[3] = dt_base;
+#else
+		env->gpr[4] = initrd_base;
+		env->gpr[5] = initrd_size;
+#endif

Linux ignores R4 and R5 regardless of whether qemu has libfdt support or not. Those should be removed.

qemu/hw/ppc_device_tree_support.c

Quoted 11 lines
qemu/hw/ppc440_bamboo.c +4 -0
+		env->nip = ep;
+
+		printf("%s: loading kvm registers\n", __func__);
+		kvm_load_registers(env);
 	}
 
 	printf("%s: DONE\n", __func__);
qemu/hw/ppc_device_tree_support.c new file +0 -0
new file mode 100644

This is a really long file name.

Quoted 16 lines
qemu/hw/ppc_device_tree_support.c new file +15 -0
@@ -0,0 +1,223 @@
+/*
+ * Functions to help device tree manipulation using libfdt.
+ * It also provides functions to read entries from device tree proc
+ * interface.
+ *
+ * Copyright 2008 IBM Corporation.
+ * Authors: Jerone Young <[email protected]>
+ *
+ * This work is licensed under the GNU GPL licence version 2 or later.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>

qemu/hw/ppc_device_tree_support.c line 25

Quoted 10 lines
qemu/hw/ppc_device_tree_support.c new file +10 -0
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "ppc440.h"
+
+#ifdef CONFIG_LIBFDT
+	#include "libfdt.h"
+#endif

Don't indent this.

Quoted 19 lines
qemu/hw/ppc_device_tree_support.c new file +19 -0
+#define DT_PROC_INTERFACE_PATH "/proc/device-tree"
+
+/* FUNCTIONS FOR READING FROM DEVICE TREE OF HOST IN /PROC */
+
+/* This function reads device-tree property files that are of
+ * a single cell size
+ */
+static uint32_t read_proc_device_tree_prop_cell(char *path_in_device_tree)
+{
+	char buf[1024];
+	uint32_t num;
+	FILE *stream;
+
+	snprintf(buf, sizeof(buf), "%s/%s",  DT_PROC_INTERFACE_PATH,
+		path_in_device_tree);
+
+	stream = fopen(buf, "rb");
+	
+	if (stream == NULL)

qemu/hw/ppc_device_tree_support.c line 55

Quoted 10 lines
qemu/hw/ppc_device_tree_support.c new file +10 -0
+	{
+		printf("%s: Unable to open '%s'\n", __func__, buf);
+		exit(1);
+	}
+
+	fread(&num, sizeof(num), 1, stream);
+	fclose(stream);
+
+	return num;
+} 

I hate that "buf" variable. You can use snprintf() with length 0 to find out how much memory to malloc.

...

Quoted 23 lines
qemu/hw/ppc_device_tree_support.c new file +23 -0
+void set_dt_cpu_0_timebase_prop(void *fdt, uint32_t timebase)
+{	
+	int offset;
+	offset = get_offset_of_node(fdt, "/cpus/cpu@0");
+	set_dt_prop_cell(fdt, offset, "timebase-frequency",
+			timebase);
+
+}
+
+void set_dt_initrd_start_prop(void *fdt, uint32_t start_addr)
+{
+	int offset;
+	offset = get_offset_of_node(fdt, "/chosen");
+	set_dt_prop_cell(fdt, offset, "linux,initrd-start",
+			start_addr);
+}
+
+void set_dt_initrd_end_prop(void *fdt, uint32_t end_addr)
+{
+	int offset;
+	offset = get_offset_of_node(fdt, "/chosen");
+	set_dt_prop_cell(fdt, offset, "linux,initrd-end",
+			end_addr);

qemu/hw/ppc_device_tree_support.c line 223

Quoted 10 lines
qemu/hw/ppc_device_tree_support.c new file +10 -0
+}
+
+void set_dt_bootargs_prop(void *fdt, char *cmdline)
+{
+	int offset;
+	offset = get_offset_of_node(fdt, "/chosen");
+	set_dt_prop_string(fdt,offset, "bootargs", cmdline);
+}
+
+#endif

These are also really long function names. If you're basically going to encode the full device tree path into the function name, I don't think they're very convenient and they're not worth having. You could just pass the path in from the caller.

Signature · 8 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#12 lore raw

Re: [kvm-ppc-devel] [PATCH 5 of 7] Add dynamic device tree manipulation & change uboot loader for PPC bamboo board model

Quoted 1 line · Hollis Blanchard

You've misspelled "licence" several times in this patch.

Got them. More of one error propagating through cut & paste.

Quoted 152 lines · Jerone Young
Quoted 9 lines

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 50fddb23a4c19ec6f359a4dd39e98712eb6bcaeb
# Parent 9c15709640cd55bf6f782d6856423363312493bb
Add dynamic device tree manipulation & change uboot loader for PPC bamboo board model

Quoted 7 lines

This patch adds code to dynamically manipulate the device tree when loaded into memory. This allows us to finally have the ability to manipulate the kernel command line & initrd from the qemu command line. This will also let us setup different settings for the board.

This patch also now uses new uboot loader uboot_loader_l() to load kernel image.

So the load_uboot() part should be a separate patch, right?

Quoted 131 lines
qemu/Makefile.target +1 -1
@@ -615,7 +615,7 @@ OBJS+= unin_pci.o ppc_chrp.o
 OBJS+= unin_pci.o ppc_chrp.o
 # PowerPC 4xx boards
 OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
-OBJS+= ppc440.o ppc440_bamboo.o
+OBJS+= ppc440.o ppc440_bamboo.o ppc_device_tree_support.o
 endif
 ifeq ($(TARGET_BASE_ARCH), mips)
 OBJS+= mips_r4k.o mips_malta.o mips_pica61.o mips_mipssim.o
qemu/hw/ppc440_bamboo.c +58 -12
@@ -8,11 +8,12 @@
  *
  */
 
+#include "config.h"
 #include "ppc440.h"
+#include "qemu-kvm.h"
+#include "ppc_device_tree_support.h"
 
-#define KERNEL_LOAD_ADDR 0x400000 /* uboot loader puts kernel at 4MB */
-
-#include "qemu-kvm.h"
+#define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
 
 /* PPC 440 refrence demo board
  *
@@ -26,14 +27,22 @@ void bamboo_init(ram_addr_t ram_size, in
 			const char *initrd_filename,
 			const char *cpu_model)
 {
+	char buf[1024];	
 	target_phys_addr_t ram_bases[2], ram_sizes[2];
 	qemu_irq *pic;
 	CPUState *env;
-	target_ulong ep;
+	target_ulong ep=0;
+	target_ulong la=0;
 	int is_linux=1; /* Will assume allways is Linux for now */
-	long kernel_size=0;
+	target_long kernel_size=0;
 	target_ulong initrd_base=0;
-	target_ulong initrd_size=0;
+	target_long initrd_size=0;
+	target_ulong dt_base=0;
+	void *fdt;
+	int ret;
+
+	uint32_t cpu_freq;
+	uint32_t timebase_freq;
 
 	printf("%s: START\n", __func__);
 
@@ -78,18 +87,23 @@ void bamboo_init(ram_addr_t ram_size, in
 
 	/* load kernel with uboot loader */
 	printf("%s: load kernel\n", __func__);
-	kernel_size = load_uboot(kernel_filename, &ep, &is_linux);
+	load_uboot_l(kernel_filename, &ep, &la, &kernel_size, &is_linux);
 	if (kernel_size < 0) {
 		fprintf(stderr, "qemu: could not load kernel '%s'\n",
 			kernel_filename);
 		exit(1);
 	}
+	printf("kernel is at guest address: 0x%lx\n", (unsigned long)la);
 
 	/* load initrd */
 	if (initrd_filename) {
-		initrd_base = kernel_size + KERNEL_LOAD_ADDR;
+        	initrd_base = kernel_size + la;
+		printf("%s: load initrd\n", __func__);
 		initrd_size = load_image(initrd_filename,
 				phys_ram_base + initrd_base);
+
+		printf("initrd is at guest address: 0x%lx\n", 
+					(unsigned long) initrd_base);
 
 		if (initrd_size < 0) {
 			fprintf(stderr,
@@ -99,17 +113,58 @@ void bamboo_init(ram_addr_t ram_size, in
 		}
 	}
 
+#ifdef CONFIG_LIBFDT
+	/* get variable for device tree */
+	cpu_freq = get_proc_dt_prop_cpu_clock_freq();
+	timebase_freq = get_proc_dt_prop_cpu_timebase_freq();
+
+	/* load binary device tree into qemu (not guest memory) */
+	printf("%s: load device tree file\n", __func__);
+	
+	snprintf(buf, sizeof(buf), "%s/%s", bios_dir, 
+		BINARY_DEVICE_TREE_FILE);
+
+	/* set base for device tree that will be in guest memory */	
+	if (initrd_base)
+		dt_base = initrd_base + initrd_size;
+	else
+		dt_base = kernel_size + la;
+
+	fdt = load_device_tree(buf, (phys_ram_base + dt_base));
+	if (fdt == NULL) {
+		printf("Loading device tree failed!\n");
+		exit(1);
+	}
+
+	printf("device tree address is at guest address: 0x%lx\n", 
+		(unsigned long) dt_base);
+
+	/* manipulate device tree in memory */
+	set_dt_cpu_0_clock_freq_prop(fdt, cpu_freq);
+	set_dt_cpu_0_timebase_prop(fdt, timebase_freq);
+
+	set_dt_initrd_start_prop(fdt, initrd_base);
+	set_dt_initrd_end_prop(fdt, (initrd_base + initrd_size));
+
+	set_dt_bootargs_prop(fdt, kernel_cmdline);
+#endif
+
 	if (kvm_enabled()) {
-	    /* XXX insert TLB entries */
-	    env->gpr[1] = (16<<20) - 8;
-	    env->gpr[4] = initrd_base;
-	    env->gpr[5] = initrd_size;
 
Quoted 5 lines

qemu/hw/ppc440_bamboo.c void bamboo_init(ram_addr_t ram_size, in · line 155

Quoted 3 lines
qemu/hw/ppc440_bamboo.c +2 -1
-	    env->nip = ep;
+		/* XXX insert TLB entries */
+		env->gpr[1] = (16<<20) - 8;

Please fix your whitespace.

This actually is the white space fix. Moves from

Quoted 14 lines

qemu/hw/ppc440_bamboo.c void bamboo_init(ram_addr_t ram_size, in · line 163

Quoted 11 lines
qemu/hw/ppc440_bamboo.c +7 -3
-	    env->cpu_index = 0;
-	    printf("%s: loading kvm registers\n", __func__);
-	    kvm_load_registers(env);
+#ifdef CONFIG_LIBFDT
+		/* location of device tree in register */
+		env->gpr[3] = dt_base;
+#else
+		env->gpr[4] = initrd_base;
+		env->gpr[5] = initrd_size;
+#endif

Linux ignores R4 and R5 regardless of whether qemu has libfdt support or not. Those should be removed.

Oh I forgot.

Quoted 7 lines
Quoted 7 lines
qemu/hw/ppc440_bamboo.c +4 -0
+		env->nip = ep;
+
+		printf("%s: loading kvm registers\n", __func__);
+		kvm_load_registers(env);
 	}
 
Quoted 7 lines

qemu/hw/ppc_device_tree_support.c

Quoted 5 lines
qemu/hw/ppc440_bamboo.c +0 -0
 	printf("%s: DONE\n", __func__);
qemu/hw/ppc_device_tree_support.c new file +0 -0
new file mode 100644

This is a really long file name.

Just renamed them something much shorter.

Quoted 54 lines
Quoted 17 lines
qemu/hw/ppc_device_tree_support.c new file +15 -0
@@ -0,0 +1,223 @@
+/*
+ * Functions to help device tree manipulation using libfdt.
+ * It also provides functions to read entries from device tree proc
+ * interface.
+ *
+ * Copyright 2008 IBM Corporation.
+ * Authors: Jerone Young <[email protected]>
+ *
+ * This work is licensed under the GNU GPL licence version 2 or later.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>

qemu/hw/ppc_device_tree_support.c line 25

Quoted 10 lines
qemu/hw/ppc_device_tree_support.c new file +10 -0
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "ppc440.h"
+
+#ifdef CONFIG_LIBFDT
+	#include "libfdt.h"
+#endif

Don't indent this.

Quoted 24 lines
qemu/hw/ppc_device_tree_support.c new file +24 -0
+#define DT_PROC_INTERFACE_PATH "/proc/device-tree"
+
+/* FUNCTIONS FOR READING FROM DEVICE TREE OF HOST IN /PROC */
+
+/* This function reads device-tree property files that are of
+ * a single cell size
+ */
+static uint32_t read_proc_device_tree_prop_cell(char *path_in_device_tree)
+{
+	char buf[1024];
+	uint32_t num;
+	FILE *stream;
+
+	snprintf(buf, sizeof(buf), "%s/%s",  DT_PROC_INTERFACE_PATH,
+		path_in_device_tree);
+
+	stream = fopen(buf, "rb");
+	
+	if (stream == NULL)
+	{
+		printf("%s: Unable to open '%s'\n", __func__, buf);
+		exit(1);
+	}
+
Quoted 8 lines

qemu/hw/ppc_device_tree_support.c line 55

Quoted 5 lines
qemu/hw/ppc_device_tree_support.c new file +5 -0
+	fread(&num, sizeof(num), 1, stream);
+	fclose(stream);
+
+	return num;
+} 

I hate that "buf" variable. You can use snprintf() with length 0 to find out how much memory to malloc.

done

Quoted 32 lines

...

Quoted 30 lines
qemu/hw/ppc_device_tree_support.c new file +30 -0
+void set_dt_cpu_0_timebase_prop(void *fdt, uint32_t timebase)
+{	
+	int offset;
+	offset = get_offset_of_node(fdt, "/cpus/cpu@0");
+	set_dt_prop_cell(fdt, offset, "timebase-frequency",
+			timebase);
+
+}
+
+void set_dt_initrd_start_prop(void *fdt, uint32_t start_addr)
+{
+	int offset;
+	offset = get_offset_of_node(fdt, "/chosen");
+	set_dt_prop_cell(fdt, offset, "linux,initrd-start",
+			start_addr);
+}
+
+void set_dt_initrd_end_prop(void *fdt, uint32_t end_addr)
+{
+	int offset;
+	offset = get_offset_of_node(fdt, "/chosen");
+	set_dt_prop_cell(fdt, offset, "linux,initrd-end",
+			end_addr);
+}
+
+void set_dt_bootargs_prop(void *fdt, char *cmdline)
+{
+	int offset;
+	offset = get_offset_of_node(fdt, "/chosen");
+	set_dt_prop_string(fdt,offset, "bootargs", cmdline);
Quoted 8 lines

qemu/hw/ppc_device_tree_support.c

Quoted 3 lines
qemu/hw/ppc_device_tree_support.c new file +3 -0
+}
+
+#endif

These are also really long function names. If you're basically going to encode the full device tree path into the function name, I don't think they're very convenient and they're not worth having. You could just pass the path in from the caller.

I've reworked the codd to remove all this.

Quoted 1 line

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#13 lore raw

PATCH 1/1 Modify PPC bamboo & ppc440 board models

In reply to Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 3a891d8fada96166089b5796f3241087d4aae50f # Parent 50fddb23a4c19ec6f359a4dd39e98712eb6bcaeb Modify PPC bamboo & ppc440 board models

This patch renames pp440_init to ppc440ep_init, as ppc440 is the name of the core and ppc440ep is the name of the SOC. When we init we are initializing the SOC.

Also in this patch we now call cpu_ppc_init for bamboo with string 440 .. as 440 is the core.

qemu/hw/ppc440.c +1 -1
@@ -10,7 +10,7 @@
 
 #include "ppc440.h"
 
-void ppc440_init(CPUState *env,
+void ppc440ep_init(CPUState *env,
 		target_phys_addr_t ram_bases[2],
 		target_phys_addr_t ram_sizes[2],
 		qemu_irq **picp,
qemu/hw/ppc440.h +1 -1
@@ -20,7 +20,7 @@
 #include "exec-all.h"
 #include "boards.h"
 
-void ppc440_init(CPUState *env,
+void ppc440ep_init(CPUState *env,
 		target_phys_addr_t ram_bases[2],
 		target_phys_addr_t ram_sizes[2],
 		qemu_irq **picp,
qemu/hw/ppc440_bamboo.c +2 -3
@@ -68,8 +68,7 @@ void bamboo_init(ram_addr_t ram_size, in
 	printf("Ram size of domain is %d bytes\n", (int)ram_size);
 
 	/* Setup CPU */
-	/* XXX We cheat for now and use 405 */
-	env = cpu_ppc_init("405");
+	env = cpu_ppc_init("440");
 	if (!env) {
 		fprintf(stderr, "Unable to initilize CPU!\n");
 		exit(1);
@@ -77,7 +76,7 @@ void bamboo_init(ram_addr_t ram_size, in
 
 	/* call init */
 	printf("Calling function ppc440_init\n");
-	ppc440_init(env, ram_bases, ram_sizes, &pic,1);
+	ppc440ep_init(env, ram_bases, ram_sizes, &pic,1);
 	printf("Done calling ppc440_init\n");
 
 	/* Register mem */

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#14 lore raw

PATCH 1/1 Add ability to specify ram on command line for bamboo board model

In reply to Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 8b1dd3609551efefbd6633ac6fe4caa3a6cbe5e9
# Parent 3a891d8fada96166089b5796f3241087d4aae50f
Add ability to specify ram on command line for bamboo board model

This patch adds the ability to now specify ram sizes on the command line. Due to the nature of the code there are restictions on exactly how much ram and the multiple that the size must match.

qemu/hw/ppc440_bamboo.c +59 -20
@@ -40,32 +40,71 @@ void bamboo_init(ram_addr_t ram_size, in
 	target_ulong dt_base=0;
 	void *fdt;
 	int ret;
+	int holdr;
+ 	unsigned long ram_size1; /* Value will be in bytes */
+ 	unsigned long ram_size2; /* Value will be in bytes */
+
 
 	uint32_t cpu_freq;
 	uint32_t timebase_freq;
 
 	printf("%s: START\n", __func__);
 
-	/* Setup Memory */
-	if (ram_size) {
-		printf("Ram size specified on command line is %i bytes\n",
-								(int)ram_size);
-		printf("WARNING: RAM is hard coded to 144MB\n");
-	}
-	else {
-		printf("Using defualt ram size of %iMB\n",
-						((int)ram_size/1024)/1024);
-	}
-
-	/* Each bank can only have memory in configurations of
-	 *   16MB, 32MB, 64MB, 128MB, or 256MB
-	 */
-	ram_bases[0] = 0x0;
-	ram_sizes[0] = 0x08000000;
-	ram_bases[1] = 0x0;
-	ram_sizes[1] = 0x01000000;
-
-	printf("Ram size of domain is %d bytes\n", (int)ram_size);
+ 	/* Setup Memory */
+ 	printf("Ram size is set to: %i MB\n",
+ 				((int)ram_size/1024)/1024); 		
+ 
+   	/* Check that total ram is at least 8 MB 
+  	 * but less than 512 MB 
+    	 * and is a multiple of 4
+    	 */
+ 
+ 	if (ram_size < (8 * 1024 * 1024)) {
+ 		printf("Ram size specified on cmd line must at least be 8 MB\n");
+ 		exit(1);
+ 	}
+ 
+ 	if (ram_size > (512 * 1024 * 1024)) {
+ 		printf("Ram size specified on cmd line is greater than 512 MB\n");
+ 		exit(1);
+ 	}
+ 
+ 	if ((((int)ram_size/1024)/1024) % 4) {
+ 		printf("Ram size specified on cmd line must be multiple of 4\n");
+ 		exit(1);
+ 	}
+ 
+ 	/* split ram into two slots */
+ 	holdr = (ram_size/(1024*1024))/4;	
+ 
+ 	/* ram_size2 has to at least have 4MB in it*/
+ 	ram_size2 = 4 * 1024 * 1024; /* Add 4MB */
+ 	holdr = holdr - 1;
+ 
+ 	
+ 	if ((4 * holdr) <= 256) {
+ 		/* if what remains is 256MB or less put in first slot */
+ 		ram_size1 = (4 * holdr) * (1024 * 1024);
+ 	}
+ 	else {
+ 		/* place first 256MB or less in first slot */
+ 		ram_size1 = 256 * 1024 * 1024;
+ 		holdr = holdr - (256/4);
+ 		
+ 		/* place remainder in slot 2 */
+ 		ram_size2 += (4 * holdr) * (1024 * 1024);
+ 	}
+ 
+ 	/* Each bank can only have memory in configurations of
+ 	 *   4MB, 8MB, 16MB, 32MB, 64MB, 128MB, or 256MB
+ 	 *   why? see sdram_bcr()
+ 	 *   
+ 	 *   Max of 512MB
+ 	 */
+ 	ram_bases[0] = 0x0;
+ 	ram_sizes[0] = ram_size1;
+ 	ram_bases[1] = 0x0;
+ 	ram_sizes[1] = ram_size2;	
 
 	/* Setup CPU */
 	env = cpu_ppc_init("440");

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

#15 lore raw

Re: [kvm-ppc-devel] [PATCH 7 of 7] Add ability to specify ram on command line for bamboo board model

Quoted 8 lines · Jerone Young

# HG changeset patch
# User Jerone Young <[email protected]>
# Date 1205296680 18000
# Branch merge
# Node ID 8b1dd3609551efefbd6633ac6fe4caa3a6cbe5e9
# Parent 3a891d8fada96166089b5796f3241087d4aae50f
Add ability to specify ram on command line for bamboo board model

Quoted 5 lines

This patch adds the ability to now specify ram sizes on the command line. Due to the nature of the code there are restictions on exactly how much ram and the multiple that the size must match.

NAK, this is both brittle and overcomplicated. Try translating the following Python to C:

ram = 144
reg = [0, 0, 0, 0]
sizes = (256, 128, 64, 32, 16, 8)

for i in range(len(reg)):
for size in sizes:
if ram / size:
reg[i] = size
ram -= size
break

if ram:
print "warning: %d left over" % ram
print reg

Signature · 8 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#16 lore raw
In reply to Jerone Young
Quoted 10 lines · Jerone Young

This set of patches enables the following:
-Device tree Support
- Add libfdt to kvm-userspace
- Add bamboo device tree to qemu source
- Detection of host Device Tree attributes
- Device tree loading
- Ability to specify initrd on the command line
- Ability to add kernel arguments on the command line
- Ability to load compressed uImages
- Ability to specify memory on the command line

This is good work, but I have some comments. :) I'll be happy to ack this stuff once those are addressed.

Quoted 7 lines

So now when running powerpc code on a 440board.

Known Issues:
There is an issue currently where guest kernel is not mounting the initrd. Working it now!

But these changes should go in anyway.

I don't believe our initrd troubles have anything to do with qemu, so I wouldn't worry about that here.

Signature · 8 lines
Hollis Blanchard
IBM Linux Technology Center


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/