[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XenPPC] [xenppc-unstable] [POWERPC] add PowerPC-specific loader to xend
# HG changeset patch # User Hollis Blanchard <hollisb@xxxxxxxxxx> # 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 <hollisb@xxxxxxxxxx> --- 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 <hollisb@xxxxxxxxxx> + +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('memory@0') + 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,970@0') + 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,970@0', 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,970@%d/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@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ppc-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |