Hollis Blanchard
2006-Aug-16 21:28 UTC
[XenPPC] [PATCH] [XEND] abstract architecture-specific bits in image.py
# HG changeset patch
# User Hollis Blanchard <hollisb@us.ibm.com>
# Date 1155763645 18000
# Node ID fcf9104665f59d886733c985ced0827be32c8874
# Parent 41827ce2ccebf927df251ce3024eb10023de7d5b
[XEND] abstract architecture-specific bits in image.py
- create arch.type (which evaluates to "x86", "ia64" or
"powerpc")
- create subclasses for x86 and ia64 HVM loaders
- rework findImageHandlerClass()
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
diff -r 41827ce2cceb -r fcf9104665f5 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Mon Aug 14 19:22:16 2006 -0500
+++ b/tools/python/xen/xend/XendDomainInfo.py Wed Aug 16 16:27:25 2006 -0500
@@ -1279,23 +1279,14 @@ class XendDomainInfo:
cpu = [ int( cpus[v % len(cpus)] ) ]
xc.vcpu_setaffinity(self.domid, v, cpu)
- # set domain maxmem in KiB
- xc.domain_setmaxmem(self.domid,
self.info[''maxmem''] * 1024)
-
- m =
self.image.getDomainMemory(self.info[''memory''] * 1024)
- balloon.free(m)
-
- init_reservation = self.info[''memory''] * 1024
- if os.uname()[4] in (''ia64'',
''ppc64''):
- # Workaround for architectures that don''t yet support
- # ballooning.
- init_reservation = m
- # Following line from xiantao.zhang@intel.com
- # Needed for IA64 until supports ballooning -- okay for PPC64?
- xc.domain_setmaxmem(self.domid, m)
-
- xc.domain_memory_increase_reservation(self.domid, init_reservation,
- 0, 0)
+ # set memory limit
+ maxmem =
self.image.getRequiredMemory(self.info[''maxmem''] * 1024)
+ xc.domain_setmaxmem(self.domid, maxmem)
+
+ # initial memory allocation
+ mem_kb =
self.image.getRequiredMemory(self.info[''memory''] * 1024)
+ balloon.free(mem_kb)
+ xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0)
self.createChannels()
diff -r 41827ce2cceb -r fcf9104665f5 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Mon Aug 14 19:22:16 2006 -0500
+++ b/tools/python/xen/xend/image.py Wed Aug 16 16:27:25 2006 -0500
@@ -27,6 +27,7 @@ from xen.xend.XendLogging import log
from xen.xend.XendLogging import log
from xen.xend.server.netif import randomMAC
from xen.xend.xenstore.xswatch import xswatch
+from xen.xend import arch
xc = xen.lowlevel.xc.xc()
@@ -141,16 +142,7 @@ class ImageHandler:
raise VmError(''Building domain failed: ostype=%s dom=%d
err=%s''
% (self.ostype, self.vm.getDomid(), str(result)))
-
- def getDomainMemory(self, mem_kb):
- """@return The memory required, in KiB, by the domain to
store the
- given amount, also in KiB."""
- if os.uname()[4] != ''ia64'':
- # A little extra because auto-ballooning is broken w.r.t. HVM
- # guests. Also, slack is necessary for live migration since that
- # uses shadow page tables.
- if ''hvm'' in
xc.xeninfo()[''xen_caps'']:
- mem_kb += 4*1024;
+ def getRequiredMemory(self, mem_kb):
return mem_kb
def buildDomain(self):
@@ -192,8 +184,6 @@ class LinuxImageHandler(ImageHandler):
features = self.vm.getFeatures())
class HVMImageHandler(ImageHandler):
-
- ostype = "hvm"
def configure(self, imageConfig, deviceConfig):
ImageHandler.configure(self, imageConfig, deviceConfig)
@@ -349,21 +339,6 @@ class HVMImageHandler(ImageHandler):
os.waitpid(self.pid, 0)
self.pid = 0
- def getDomainMemory(self, mem_kb):
- """@see ImageHandler.getDomainMemory"""
- if os.uname()[4] == ''ia64'':
- page_kb = 16
- # ROM size for guest firmware, ioreq page and xenstore page
- extra_pages = 1024 + 2
- else:
- page_kb = 4
- # This was derived emperically:
- # 2.4 MB overhead per 1024 MB RAM + 8 MB constant
- # + 4 to avoid low-memory condition
- extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12;
- extra_pages = int( math.ceil( extra_mb*1024 / page_kb ))
- return mem_kb + extra_pages * page_kb
-
def register_shutdown_watch(self):
""" add xen store watch on control/shutdown
"""
self.shutdownWatch = xswatch(self.vm.dompath +
"/control/shutdown", \
@@ -400,15 +375,42 @@ class HVMImageHandler(ImageHandler):
return 1 # Keep watching
-"""Table of image handler classes for virtual machine images.
Indexed by
-image type.
-"""
-imageHandlerClasses = {}
-
-
-for h in LinuxImageHandler, HVMImageHandler:
- imageHandlerClasses[h.ostype] = h
-
+class IA64_HVM_ImageHandler(HVMImageHandler):
+
+ ostype = "hvm"
+
+ def getRequiredMemory(self, mem_kb):
+ page_kb = 16
+ # ROM size for guest firmware, ioreq page and xenstore page
+ extra_pages = 1024 + 2
+ return mem_kb + extra_pages * page_kb
+
+class X86_HVM_ImageHandler(HVMImageHandler):
+
+ ostype = "hvm"
+
+ def getRequiredMemory(self, mem_kb):
+ page_kb = 4
+ # This was derived emperically:
+ # 2.4 MB overhead per 1024 MB RAM + 8 MB constant
+ # + 4 to avoid low-memory condition
+ extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12;
+ extra_pages = int( math.ceil( extra_mb*1024 / page_kb ))
+ return mem_kb + extra_pages * page_kb
+
+_handlers = {
+ "powerpc": {
+ "linux": LinuxImageHandler,
+ },
+ "ia64": {
+ "linux": LinuxImageHandler,
+ "hvm": IA64_HVM_ImageHandler,
+ },
+ "x86": {
+ "linux": LinuxImageHandler,
+ "hvm": X86_HVM_ImageHandler,
+ },
+}
def findImageHandlerClass(image):
"""Find the image handler class for an image config.
@@ -416,10 +418,10 @@ def findImageHandlerClass(image):
@param image config
@return ImageHandler subclass or None
"""
- ty = sxp.name(image)
- if ty is None:
+ type = sxp.name(image)
+ if type is None:
raise VmError(''missing image type'')
- imageClass = imageHandlerClasses.get(ty)
- if imageClass is None:
- raise VmError(''unknown image type: '' + ty)
- return imageClass
+ try:
+ return _handlers[arch.type][type]
+ except KeyError:
+ raise VmError(''unknown image type: '' + type)
diff -r 41827ce2cceb -r fcf9104665f5 tools/python/xen/xend/arch.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/arch.py Wed Aug 16 16:27:25 2006 -0500
@@ -0,0 +1,31 @@
+#!/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@us.ibm.com>
+
+import os
+
+_types = {
+ "i386": "x86",
+ "i486": "x86",
+ "i586": "x86",
+ "i686": "x86",
+ "ia64": "ia64",
+ "ppc": "powerpc",
+ "ppc64": "powerpc",
+}
+type = _types.get(os.uname()[4], "unknown")
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel
Hollis Blanchard
2006-Aug-22 21:50 UTC
[Xen-devel] [PATCH] [XEND] abstract architecture-specific bits in image.py
Since this patch wasn''t committed, the shadow2 changes created
conflicts. Here is the respin. Note that I have not tested with shadow2,
but as you can see below the math doesn''t need to be so complicated.
Ewan, please apply or comment.
[XEND] abstract architecture-specific bits in image.py
- create arch.type (which evaluates to "x86", "ia64" or
"powerpc")
- create subclasses for x86 and ia64 HVM loaders
- rework findImageHandlerClass()
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
diff -r 5fc1fe790835 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Sat Aug 19 17:07:54 2006 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py Tue Aug 22 16:11:57 2006 -0500
@@ -30,7 +30,6 @@ import time
import time
import threading
import os
-import math
import xen.lowlevel.xc
from xen.util import asserts
@@ -1280,34 +1279,27 @@ class XendDomainInfo:
for v in range(0,
self.info[''max_vcpu_id'']+1):
xc.vcpu_setaffinity(self.domid, v,
self.info[''cpus''])
- # set domain maxmem in KiB
- xc.domain_setmaxmem(self.domid,
self.info[''maxmem''] * 1024)
-
- m =
self.image.getDomainMemory(self.info[''memory''] * 1024)
+ # set memory limit
+ maxmem =
self.image.getRequiredMemory(self.info[''maxmem''] * 1024)
+ xc.domain_setmaxmem(self.domid, maxmem)
+
+ mem_kb =
self.image.getRequiredMemory(self.info[''memory''] * 1024)
# get the domain''s shadow memory requirement
- sm = int(math.ceil(self.image.getDomainShadowMemory(m) / 1024.0))
- if self.info[''shadow_memory''] > sm:
- sm = self.info[''shadow_memory'']
+ shadow_kb = self.image.getRequiredShadowMemory(mem_kb)
+ shadow_kb_req = self.info[''shadow_memory''] * 1024
+ if shadow_kb_req > shadow_kb:
+ shadow_kb = shadow_kb_req
# Make sure there''s enough RAM available for the domain
- balloon.free(m + sm * 1024)
+ balloon.free(mem_kb + shadow_kb)
# Set up the shadow memory
- sm = xc.shadow_mem_control(self.domid, mb=sm)
- self.info[''shadow_memory''] = sm
-
- init_reservation = self.info[''memory''] * 1024
- if os.uname()[4] in (''ia64'',
''ppc64''):
- # Workaround for architectures that don''t yet support
- # ballooning.
- init_reservation = m
- # Following line from xiantao.zhang@intel.com
- # Needed for IA64 until supports ballooning -- okay for PPC64?
- xc.domain_setmaxmem(self.domid, m)
-
- xc.domain_memory_increase_reservation(self.domid, init_reservation,
- 0, 0)
+ shadow_cur = xc.shadow_mem_control(self.domid, shadow_kb * 1024)
+ self.info[''shadow_memory''] = shadow_cur
+
+ # initial memory allocation
+ xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0)
self.createChannels()
diff -r 5fc1fe790835 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Sat Aug 19 17:07:54 2006 +0100
+++ b/tools/python/xen/xend/image.py Tue Aug 22 15:30:36 2006 -0500
@@ -27,6 +27,8 @@ from xen.xend.XendLogging import log
from xen.xend.XendLogging import log
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()
@@ -141,19 +143,10 @@ class ImageHandler:
raise VmError(''Building domain failed: ostype=%s dom=%d
err=%s''
% (self.ostype, self.vm.getDomid(), str(result)))
-
- def getDomainMemory(self, mem_kb):
- """@return The memory required, in KiB, by the domain to
store the
- given amount, also in KiB."""
- if os.uname()[4] != ''ia64'':
- # A little extra because auto-ballooning is broken w.r.t. HVM
- # guests. Also, slack is necessary for live migration since that
- # uses shadow page tables.
- if ''hvm'' in
xc.xeninfo()[''xen_caps'']:
- mem_kb += 4*1024;
+ def getRequiredMemory(self, mem_kb):
return mem_kb
- def getDomainShadowMemory(self, mem_kb):
+ def getRequiredShadowMemory(self, mem_kb):
"""@return The minimum shadow memory required, in KiB,
for a domain
with mem_kb KiB of RAM."""
# PV domains don''t need any shadow memory
@@ -197,9 +190,39 @@ class LinuxImageHandler(ImageHandler):
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):
-
- ostype = "hvm"
def configure(self, imageConfig, deviceConfig):
ImageHandler.configure(self, imageConfig, deviceConfig)
@@ -355,32 +378,6 @@ class HVMImageHandler(ImageHandler):
os.waitpid(self.pid, 0)
self.pid = 0
- def getDomainMemory(self, mem_kb):
- """@see ImageHandler.getDomainMemory"""
- if os.uname()[4] == ''ia64'':
- page_kb = 16
- # ROM size for guest firmware, ioreq page and xenstore page
- extra_pages = 1024 + 2
- else:
- page_kb = 4
- # This was derived emperically:
- # 2.4 MB overhead per 1024 MB RAM + 8 MB constant
- # + 4 to avoid low-memory condition
- extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12;
- extra_pages = int( math.ceil( extra_mb*1024 / page_kb ))
- return mem_kb + extra_pages * page_kb
-
- def getDomainShadowMemory(self, mem_kb):
- """@return The minimum shadow memory required, in KiB,
for a domain
- with mem_kb KiB of RAM."""
- if os.uname()[4] in (''ia64'',
''ppc64''):
- # Explicit shadow memory is not a concept
- return 0
- else:
- # 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than
- # the minimum that Xen would allocate if no value were given.
- return 1024 * self.vm.getVCpuCount() + mem_kb / 256
-
def register_shutdown_watch(self):
""" add xen store watch on control/shutdown
"""
self.shutdownWatch = xswatch(self.vm.dompath +
"/control/shutdown", \
@@ -417,15 +414,51 @@ class HVMImageHandler(ImageHandler):
return 1 # Keep watching
-"""Table of image handler classes for virtual machine images.
Indexed by
-image type.
-"""
-imageHandlerClasses = {}
-
-
-for h in LinuxImageHandler, HVMImageHandler:
- imageHandlerClasses[h.ostype] = h
-
+class IA64_HVM_ImageHandler(HVMImageHandler):
+
+ ostype = "hvm"
+
+ def getRequiredMemory(self, mem_kb):
+ page_kb = 16
+ # ROM size for guest firmware, ioreq page and xenstore page
+ extra_pages = 1024 + 2
+ return mem_kb + extra_pages * page_kb
+
+ def getRequiredShadowMemory(self, mem_kb):
+ # Explicit shadow memory is not a concept
+ return 0
+
+class X86_HVM_ImageHandler(HVMImageHandler):
+
+ ostype = "hvm"
+
+ def getRequiredMemory(self, mem_kb):
+ page_kb = 4
+ # This was derived emperically:
+ # 2.4 MB overhead per 1024 MB RAM + 8 MB constant
+ # + 4 to avoid low-memory condition
+ extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12;
+ extra_pages = int( math.ceil( extra_mb*1024 / page_kb ))
+ return mem_kb + extra_pages * page_kb
+
+ def getRequiredShadowMemory(self, mem_kb):
+ # 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than
+ # the minimum that Xen would allocate if no value were given.
+ return 1024 * self.vm.getVCpuCount() + mem_kb / 256
+
+_handlers = {
+ "powerpc": {
+ "linux": PPC_LinuxImageHandler,
+ },
+ "ia64": {
+ "linux": LinuxImageHandler,
+ "hvm": IA64_HVM_ImageHandler,
+ },
+ "x86": {
+ "linux": LinuxImageHandler,
+ "hvm": X86_HVM_ImageHandler,
+ },
+}
def findImageHandlerClass(image):
"""Find the image handler class for an image config.
@@ -433,10 +466,10 @@ def findImageHandlerClass(image):
@param image config
@return ImageHandler subclass or None
"""
- ty = sxp.name(image)
- if ty is None:
+ type = sxp.name(image)
+ if type is None:
raise VmError(''missing image type'')
- imageClass = imageHandlerClasses.get(ty)
- if imageClass is None:
- raise VmError(''unknown image type: '' + ty)
- return imageClass
+ try:
+ return _handlers[arch.type][type]
+ except KeyError:
+ raise VmError(''unknown image type: '' + type)
diff -r 5fc1fe790835 tools/python/xen/xend/FlatDeviceTree.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/FlatDeviceTree.py Tue Aug 22 16:27:40 2006 -0500
@@ -0,0 +1,323 @@
+#!/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@us.ibm.com>
+
+import os
+import sys
+import struct
+import stat
+import re
+
+_OF_DT_HEADER = int("d00dfeed", 16) # avoid signed/unsigned
FutureWarning
+_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'')
+
+def _indent(item):
+ indented = []
+ for line in str(item).splitlines(True):
+ indented.append('' '' + line)
+ return ''''.join(indented)
+
+class _Property:
+ _nonprint = re.compile(''[\000-\037\200-\377]'')
+ def __init__(self, node, name, value):
+ self.node = node
+ self.value = value
+ self.name = name
+ self.node.tree.stradd(name)
+
+ def __str__(self):
+ result = self.name
+ if self.value:
+ searchtext = self.value
+ # it''s ok for a string to end in NULL
+ if searchtext.find(''\000'') == len(searchtext)-1:
+ searchtext = searchtext[:-1]
+ m = self._nonprint.search(searchtext)
+ if m:
+ bytes = struct.unpack("B" * len(self.value),
self.value)
+ hexbytes = [ ''%02x'' % b for b in bytes ]
+ words = []
+ for i in range(0, len(self.value), 4):
+ words.append(''''.join(hexbytes[i:i+4]))
+ v = ''<'' + ''
''.join(words) + ''>''
+ else:
+ v = ''"%s"'' % self.value
+ result += '': '' + v
+ return result
+
+ 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 __str__(self):
+ propstrs = [ _indent(prop) for prop in self.props.values() ]
+ childstrs = [ _indent(child) for child in self.children.values() ]
+ return ''%s:\n%s\n%s'' % (self.name,
''\n''.join(propstrs),
+ ''\n''.join(childstrs))
+
+ 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 _copynode(node, dirpath, propfilter):
+ ''''''Extract all properties from a node in the
system''s device tree.''''''
+ dirents = os.listdir(dirpath)
+ for dirent in dirents:
+ fullpath = os.path.join(dirpath, dirent)
+ st = os.lstat(fullpath)
+ if stat.S_ISDIR(st.st_mode):
+ child = node.addnode(dirent)
+ _copytree(child, fullpath, propfilter)
+ elif stat.S_ISREG(st.st_mode) and propfilter(fullpath):
+ node.addprop(dirent, _getprop(fullpath))
+
+def _copytree(node, dirpath, propfilter):
+ path = os.path.join(_host_devtree_root, dirpath)
+ _copynode(node, path, propfilter)
+
+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)
+
+ # Copy all properties the system firmware gave us, except for
''linux,''
+ # properties, from ''cpus/@0'', once for every vcpu.
Hopefully all cpus are
+ # identical...
+ cpu0 = None
+ def _nolinuxprops(fullpath):
+ return not
os.path.basename(fullpath).startswith(''linux,'')
+ for i in range(imghandler.vm.getVCpuCount()):
+ cpu = cpus.addnode(''PowerPC,970@0'')
+ _copytree(cpu, ''cpus/PowerPC,970@0'', _nolinuxprops)
+ # and then overwrite what we need to
+ pft_size = imghandler.vm.info.get(''pft-size'', 0x14)
+ cpu.setprop(''ibm,pft-size'', 0, pft_size)
+
+ # 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
diff -r 5fc1fe790835 tools/python/xen/xend/arch.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/xend/arch.py Tue Aug 22 16:48:25 2006 -0500
@@ -0,0 +1,31 @@
+#!/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@us.ibm.com>
+
+import os
+
+_types = {
+ "i386": "x86",
+ "i486": "x86",
+ "i586": "x86",
+ "i686": "x86",
+ "ia64": "ia64",
+ "ppc": "powerpc",
+ "ppc64": "powerpc",
+}
+type = _types.get(os.uname()[4], "unknown")
--
Hollis Blanchard
IBM Linux Technology Center
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Hollis Blanchard
2006-Aug-23 17:58 UTC
Re: [Xen-devel] [PATCH] [XEND] abstract architecture-specific bits in image.py
On Tue, 2006-08-22 at 16:50 -0500, Hollis Blanchard wrote:> Since this patch wasn''t committed, the shadow2 changes created > conflicts. Here is the respin. Note that I have not tested with shadow2, > but as you can see below the math doesn''t need to be so complicated.Tim, could you confirm this doesn''t break the shadow code please? -- Hollis Blanchard IBM Linux Technology Center _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ewan Mellor
2006-Aug-29 22:16 UTC
[Xen-devel] Re: [PATCH] [XEND] abstract architecture-specific bits in image.py
On Tue, Aug 22, 2006 at 04:50:54PM -0500, Hollis Blanchard wrote:> Since this patch wasn''t committed, the shadow2 changes created > conflicts. Here is the respin. Note that I have not tested with shadow2, > but as you can see below the math doesn''t need to be so complicated. > > Ewan, please apply or comment.Applied, thanks Hollis. Is this your only outstanding patch? I got lost when you rev''d this one a couple of times ;-) Thanks, Ewan. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Hollis Blanchard
2006-Aug-30 02:27 UTC
[Xen-devel] Re: [PATCH] [XEND] abstract architecture-specific bits in image.py
On Tue, 2006-08-29 at 23:16 +0100, Ewan Mellor wrote:> On Tue, Aug 22, 2006 at 04:50:54PM -0500, Hollis Blanchard wrote: > > > Since this patch wasn''t committed, the shadow2 changes created > > conflicts. Here is the respin. Note that I have not tested with shadow2, > > but as you can see below the math doesn''t need to be so complicated. > > > > Ewan, please apply or comment. > > Applied, thanks Hollis. Is this your only outstanding patch? I got lost > when you rev''d this one a couple of times ;-)Thanks Ewan! I will have another patch for you shortly. :) Actually there was one bug we discovered as a result of the shadow merge: shadow_mem_control''s arguments should be MB, not bytes. Here''s the pseudo-diff: - shadow_cur = xc.shadow_mem_control(self.domid, shadow_kb * 1024) + shadow_cur = xc.shadow_mem_control(self.domid, shadow_kb / 1024) -- Hollis Blanchard IBM Linux Technology Center _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ewan Mellor
2006-Aug-30 08:48 UTC
[Xen-devel] Re: [PATCH] [XEND] abstract architecture-specific bits in image.py
On Tue, Aug 29, 2006 at 09:27:58PM -0500, Hollis Blanchard wrote:> On Tue, 2006-08-29 at 23:16 +0100, Ewan Mellor wrote: > > On Tue, Aug 22, 2006 at 04:50:54PM -0500, Hollis Blanchard wrote: > > > > > Since this patch wasn''t committed, the shadow2 changes created > > > conflicts. Here is the respin. Note that I have not tested with shadow2, > > > but as you can see below the math doesn''t need to be so complicated. > > > > > > Ewan, please apply or comment. > > > > Applied, thanks Hollis. Is this your only outstanding patch? I got lost > > when you rev''d this one a couple of times ;-) > > Thanks Ewan! I will have another patch for you shortly. :) > > Actually there was one bug we discovered as a result of the shadow > merge: shadow_mem_control''s arguments should be MB, not bytes. Here''s > the pseudo-diff: > - shadow_cur = xc.shadow_mem_control(self.domid, shadow_kb * 1024) > + shadow_cur = xc.shadow_mem_control(self.domid, shadow_kb / 1024)I''ve done that, but with (shadow_kb + 1023) / 1024, as it needs to be rounded up. Cheers, Ewan. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel