# HG changeset patch
# User Hollis Blanchard <[EMAIL PROTECTED]>
# Node ID 279843441136b04e11d8c49249c009ef7823cc5e
# Parent  f4e9ed4708a39ef9abe37cc9148867d4e4a53322
[POWERPC] add PowerPC-specific loader to xend
- create a flat device tree to pass to libxc
Signed-off-by: Hollis Blanchard <[EMAIL PROTECTED]>
---
 tools/python/xen/xend/FlatDeviceTree.py |  286 ++++++++++++++++++++++++++++++++
 tools/python/xen/xend/image.py          |   35 +++
 2 files changed, 320 insertions(+), 1 deletion(-)

diff -r f4e9ed4708a3 -r 279843441136 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Wed Aug 16 17:19:38 2006 -0500
+++ b/tools/python/xen/xend/image.py    Wed Aug 16 17:19:38 2006 -0500
@@ -28,6 +28,7 @@ from xen.xend.server.netif import random
 from xen.xend.server.netif import randomMAC
 from xen.xend.xenstore.xswatch import xswatch
 from xen.xend import arch
+from xen.xend import FlatDeviceTree
 
 
 xc = xen.lowlevel.xc.xc()
@@ -182,6 +183,38 @@ class LinuxImageHandler(ImageHandler):
                               cmdline        = self.cmdline,
                               ramdisk        = self.ramdisk,
                               features       = self.vm.getFeatures())
+
+class PPC_LinuxImageHandler(LinuxImageHandler):
+
+    ostype = "linux"
+
+    def configure(self, imageConfig, deviceConfig):
+        LinuxImageHandler.configure(self, imageConfig, deviceConfig)
+        self.imageConfig = imageConfig
+
+    def buildDomain(self):
+        store_evtchn = self.vm.getStorePort()
+        console_evtchn = self.vm.getConsolePort()
+
+        log.debug("dom            = %d", self.vm.getDomid())
+        log.debug("image          = %s", self.kernel)
+        log.debug("store_evtchn   = %d", store_evtchn)
+        log.debug("console_evtchn = %d", console_evtchn)
+        log.debug("cmdline        = %s", self.cmdline)
+        log.debug("ramdisk        = %s", self.ramdisk)
+        log.debug("vcpus          = %d", self.vm.getVCpuCount())
+        log.debug("features       = %s", self.vm.getFeatures())
+
+        devtree = FlatDeviceTree.build(self)
+
+        return xc.linux_build(dom            = self.vm.getDomid(),
+                              image          = self.kernel,
+                              store_evtchn   = store_evtchn,
+                              console_evtchn = console_evtchn,
+                              cmdline        = self.cmdline,
+                              ramdisk        = self.ramdisk,
+                              features       = self.vm.getFeatures(),
+                              arch_args      = devtree.to_bin())
 
 class HVMImageHandler(ImageHandler):
 
@@ -400,7 +433,7 @@ class X86_HVM_ImageHandler(HVMImageHandl
 
 _handlers = {
     "powerpc": {
-        "linux": LinuxImageHandler,
+        "linux": PPC_LinuxImageHandler,
     },
     "ia64": {
         "linux": LinuxImageHandler,
diff -r f4e9ed4708a3 -r 279843441136 tools/python/xen/xend/FlatDeviceTree.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/FlatDeviceTree.py   Wed Aug 16 17:19:38 2006 -0500
@@ -0,0 +1,286 @@
+#!/usr/bin/env python
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+# Copyright (C) IBM Corp. 2006
+#
+# Authors: Hollis Blanchard <[EMAIL PROTECTED]>
+
+import os
+import sys
+import struct
+
+_OF_DT_HEADER = 0xd00dfeed
+_OF_DT_BEGIN_NODE = 0x1
+_OF_DT_END_NODE = 0x2
+_OF_DT_PROP = 0x3
+_OF_DT_END = 0x9
+
+def _bincat(seq, separator=''):
+    '''Concatenate the contents of seq into a bytestream.'''
+    strs = []
+    for item in seq:
+        if type(item) == type(0):
+            strs.append(struct.pack(">I", item))
+        else:
+            try:
+                strs.append(item.to_bin())
+            except AttributeError, e:
+                strs.append(item)
+    return separator.join(strs)
+
+def _alignup(val, alignment):
+    return (val + alignment - 1) & ~(alignment - 1)
+
+def _pad(buf, alignment):
+    '''Pad bytestream with NULLs to specified alignment.'''
+    padlen = _alignup(len(buf), alignment)
+    return buf + '\0' * (padlen - len(buf))
+    # not present in Python 2.3:
+    #return buf.ljust(_padlen, '\0')
+
+class _Property:
+    def __init__(self, node, name, value):
+        self.node = node
+        self.value = value
+        self.name = name
+        self.node.tree.stradd(name)
+    def to_bin(self):
+        offset = self.node.tree.stroffset(self.name)
+        return struct.pack('>III', _OF_DT_PROP, len(self.value), offset) \
+            + _pad(self.value, 4)
+
+class _Node:
+    def __init__(self, tree, name):
+        self.tree = tree
+        self.name = name
+        self.props = {}
+        self.children = {}
+        self.phandle = 0
+
+    def to_bin(self):
+        name = _pad(self.name + '\0', 4)
+        return struct.pack('>I', _OF_DT_BEGIN_NODE) + \
+                name + \
+                _bincat(self.props.values()) + \
+                _bincat(self.children.values()) + \
+                struct.pack('>I', _OF_DT_END_NODE)
+
+    def addprop(self, propname, *cells):
+        '''setprop with duplicate error-checking.'''
+        if propname in self.props:
+            raise AttributeError('%s/%s already exists' % (self.name, 
propname))
+        self.setprop(propname, *cells)
+
+    def setprop(self, propname, *cells):
+        self.props[propname] = _Property(self, propname, _bincat(cells))
+
+    def addnode(self, nodename):
+        '''newnode with duplicate error-checking.'''
+        if nodename in self.children:
+            raise AttributeError('%s/%s already exists' % (self.name, 
nodename))
+        return self.newnode(nodename)
+
+    def newnode(self, nodename):
+        node = _Node(self.tree, nodename)
+        self.children[nodename] = node
+        return node
+
+    def getprop(self, propname):
+        return self.props[propname]
+
+    def getchild(self, nodename):
+        return self.children[nodename]
+
+    def get_phandle(self):
+        if self.phandle:
+            return self.phandle
+        self.phandle = self.tree.alloc_phandle()
+        self.addprop('linux,phandle', self.phandle)
+        return self.phandle
+
+class _Header:
+    def __init__(self):
+        self.magic = 0
+        self.totalsize = 0
+        self.off_dt_struct = 0
+        self.off_dt_strings = 0
+        self.off_mem_rsvmap = 0
+        self.version = 0
+        self.last_comp_version = 0
+        self.boot_cpuid_phys = 0
+        self.size_dt_strings = 0
+    def to_bin(self):
+        return struct.pack('>9I',
+            self.magic,
+            self.totalsize,
+            self.off_dt_struct,
+            self.off_dt_strings,
+            self.off_mem_rsvmap,
+            self.version,
+            self.last_comp_version,
+            self.boot_cpuid_phys,
+            self.size_dt_strings)
+
+class _StringBlock:
+    def __init__(self):
+        self.table = []
+    def to_bin(self):
+        return _bincat(self.table, '\0') + '\0'
+    def add(self, str):
+        self.table.append(str)
+    def getoffset(self, str):
+        return self.to_bin().index(str + '\0')
+
+class Tree(_Node):
+    def __init__(self):
+        self.last_phandle = 0
+        self.strings = _StringBlock()
+        self.reserved = [(0, 0)]
+        _Node.__init__(self, self, '\0')
+
+    def alloc_phandle(self):
+        self.last_phandle += 1
+        return self.last_phandle
+
+    def stradd(self, str):
+        return self.strings.add(str)
+
+    def stroffset(self, str):
+        return self.strings.getoffset(str)
+
+    def reserve(self, start, len):
+        self.reserved.insert(0, (start, len))
+
+    def to_bin(self):
+        # layout:
+        #   header
+        #   reservation map
+        #   string block
+        #   data block
+
+        datablock = _Node.to_bin(self)
+
+        r = [ struct.pack('>QQ', rsrv[0], rsrv[1]) for rsrv in self.reserved ]
+        reserved = _bincat(r)
+
+        strblock = _pad(self.strings.to_bin(), 4)
+        strblocklen = len(strblock)
+
+        header = _Header()
+        header.magic = _OF_DT_HEADER
+        header.off_mem_rsvmap = _alignup(len(header.to_bin()), 8)
+        header.off_dt_strings = header.off_mem_rsvmap + len(reserved)
+        header.off_dt_struct = header.off_dt_strings + strblocklen
+        header.version = 0x10
+        header.last_comp_version = 0x10
+        header.boot_cpuid_phys = 0
+        header.size_dt_strings = strblocklen
+
+        payload = reserved + \
+                strblock + \
+                datablock + \
+                struct.pack('>I', _OF_DT_END)
+        header.totalsize = len(payload) + _alignup(len(header.to_bin()), 8)
+        return _pad(header.to_bin(), 8) + payload
+
+_host_devtree_root = '/proc/device-tree'
+def _getprop(propname):
+    '''Extract a property from the system's device tree.'''
+    f = file(os.path.join(_host_devtree_root, propname), 'r')
+    data = f.read()
+    f.close()
+    return data
+
+def build(imghandler):
+    '''Construct a device tree by combining the domain's configuration and
+    the host's device tree.'''
+    root = Tree()
+
+    # 4 pages: start_info, console, store, shared_info
+    root.reserve(0x3ffc000, 0x4000)
+
+    root.addprop('device_type', 'chrp-but-not-really\0')
+    root.addprop('#size-cells', 2)
+    root.addprop('#address-cells', 2)
+    root.addprop('model', 'Momentum,Maple-D\0')
+    root.addprop('compatible', 'Momentum,Maple\0')
+
+    xen = root.addnode('xen')
+    xen.addprop('start-info', 0, 0x3ffc000, 0, 0x1000)
+    xen.addprop('version', 'Xen-3.0-unstable\0')
+    xen.addprop('reg', 0, imghandler.vm.domid, 0, 0)
+    xen.addprop('domain-name', imghandler.vm.getName() + '\0')
+    xencons = xen.addnode('console')
+    xencons.addprop('interrupts', 1, 0)
+
+    # XXX split out RMA node
+    mem = root.addnode('[EMAIL PROTECTED]')
+    totalmem = imghandler.vm.getMemoryTarget() * 1024
+    mem.addprop('reg', 0, 0, 0, totalmem)
+    mem.addprop('device_type', 'memory\0')
+
+    cpus = root.addnode('cpus')
+    cpus.addprop('smp-enabled')
+    cpus.addprop('#size-cells', 0)
+    cpus.addprop('#address-cells', 1)
+
+    # create a cpu node for each vcpu
+    cpu0 = None
+    for i in range(imghandler.vm.getVCpuCount()):
+        cpu = cpus.addnode('PowerPC,[EMAIL PROTECTED]')
+        pft_size = imghandler.vm.info.get('pft-size', 0x14)
+        cpu.addprop('ibm,pft-size', 0, pft_size)
+        cpu.addprop('reg', i)
+        cpu.addprop('cpu#', i)
+        cpu.addprop('device_type', 'cpu\0')
+        for prop in ('d-cache-size', 'd-cache-line-size', 'd-cache-sets',
+                     'i-cache-size', 'i-cache-line-size', 'i-cache-sets',
+                     'clock-frequency', 'timebase-frequency',
+                     'timebases-in-sync'):
+            val = _getprop(os.path.join('cpus/PowerPC,[EMAIL PROTECTED]', 
prop))
+            cpu.addprop(prop, val)
+            # XXX 64-bit, more
+
+        # L2 cache
+        l2 = cpu.addnode('l2-cache')
+        l2.addprop('name', 'l2-cache\0')
+        l2.addprop('device_type', 'cache\0')
+        for prop in ('d-cache-size', 'd-cache-sets',
+                     'i-cache-size', 'i-cache-sets',
+                     'cache-unified'):
+            fullprop = os.path.join('cpus/PowerPC,[EMAIL PROTECTED]/l2-cache' 
% i, prop)
+            val = _getprop(fullprop)
+            l2.addprop(prop, val)
+
+        # set default CPU
+        if cpu0 == None:
+            cpu0 = cpu
+
+    chosen = root.addnode('chosen')
+    chosen.addprop('cpu', cpu0.get_phandle())
+    chosen.addprop('memory', mem.get_phandle())
+    chosen.addprop('linux,stdout-path', '/xen/console\0')
+    chosen.addprop('interrupt-controller', xen.get_phandle())
+    chosen.addprop('bootargs', imghandler.cmdline + '\0')
+    # xc_linux_load.c will overwrite these 64-bit properties later
+    chosen.addprop('linux,initrd-start', 0, 0)
+    chosen.addprop('linux,initrd-end', 0, 0)
+
+    if 1:
+        f = file('/tmp/domU.dtb', 'w')
+        f.write(root.to_bin())
+        f.close()
+
+    return root

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to