ia64/xen-unstable

view tools/python/xen/xend/server/pciif.py @ 13642:ba3ec84c9423

[XEND] Add missing ConsoleController.py

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Fri Jan 26 02:44:35 2007 +0000 (2007-01-26)
parents 5bed7bc05c8a
children 2cdf8fef8d93
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16 # Copyright (C) 2005 XenSource Ltd
17 #============================================================================
20 import types
22 from xen.xend import sxp
23 from xen.xend.XendError import VmError
24 from xen.xend.XendLogging import log
26 from xen.xend.xenstore.xstransact import xstransact
28 from xen.xend.server.DevController import DevController
30 import xen.lowlevel.xc
32 from xen.util.pci import PciDevice
33 import resource
34 import re
36 from xen.xend.server.pciquirk import *
38 xc = xen.lowlevel.xc.xc()
40 #Calculate PAGE_SHIFT: number of bits to shift an address to get the page number
41 PAGE_SIZE = resource.getpagesize()
42 PAGE_SHIFT = 0
43 t = PAGE_SIZE
44 while not (t&1):
45 t>>=1
46 PAGE_SHIFT+=1
48 class PciController(DevController):
50 def __init__(self, vm):
51 DevController.__init__(self, vm)
54 def getDeviceDetails(self, config):
55 """@see DevController.getDeviceDetails"""
56 def parse_hex(val):
57 try:
58 if isinstance(val, types.StringTypes):
59 return int(val, 16)
60 else:
61 return val
62 except ValueError:
63 return None
65 back = {}
66 pcidevid = 0
67 for pci_config in config.get('devs', []):
68 domain = parse_hex(pci_config.get('domain', 0))
69 bus = parse_hex(pci_config.get('bus', 0))
70 slot = parse_hex(pci_config.get('slot', 0))
71 func = parse_hex(pci_config.get('func', 0))
72 self.setupDevice(domain, bus, slot, func)
73 back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%02x" % \
74 (domain, bus, slot, func)
75 pcidevid += 1
77 back['num_devs']=str(pcidevid)
78 back['uuid'] = config.get('uuid','')
79 return (0, back, {})
81 def getDeviceConfiguration(self, devid):
82 result = DevController.getDeviceConfiguration(self, devid)
83 num_devs = self.readBackend(devid, 'num_devs')
84 pci_devs = []
86 for i in range(int(num_devs)):
87 dev_config = self.readBackend(devid, 'dev-%d' % i)
89 pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" +
90 r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" +
91 r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" +
92 r"(?P<func>[0-9a-fA-F]{1,2})", dev_config)
94 if pci_match!=None:
95 pci_dev_info = pci_match.groupdict()
96 pci_devs.append({'domain': '0x%(domain)s' % pci_dev_info,
97 'bus': '0x%(bus)s' % pci_dev_info,
98 'slot': '0x%(slot)s' % pci_dev_info,
99 'func': '0x%(func)s' % pci_dev_info})
101 result['devs'] = pci_devs
102 result['uuid'] = self.readBackend(devid, 'uuid')
103 return result
105 def configuration(self, devid):
106 """Returns SXPR for devices on domain.
108 @note: we treat this dict especially to convert to
109 SXP because it is not a straight dict of strings."""
111 configDict = self.getDeviceConfiguration(devid)
112 sxpr = [self.deviceClass]
114 # remove devs
115 devs = configDict.pop('devs', [])
117 for dev in devs:
118 dev_sxpr = ['dev']
119 for dev_item in dev.items():
120 dev_sxpr.append(list(dev_item))
121 sxpr.append(dev_sxpr)
123 for key, val in configDict.items():
124 if type(val) == type(list()):
125 for v in val:
126 sxpr.append([key, v])
127 else:
128 sxpr.append([key, val])
130 return sxpr
132 def setupDevice(self, domain, bus, slot, func):
133 """ Attach I/O resources for device to frontend domain
134 """
135 fe_domid = self.getDomid()
137 try:
138 dev = PciDevice(domain, bus, slot, func)
139 except Exception, e:
140 raise VmError("pci: failed to locate device and "+
141 "parse it's resources - "+str(e))
143 if dev.driver!='pciback':
144 raise VmError(("pci: PCI Backend does not own device "+ \
145 "%s\n"+ \
146 "See the pciback.hide kernel "+ \
147 "command-line parameter or\n"+ \
148 "bind your slot/device to the PCI backend using sysfs" \
149 )%(dev.name))
151 PCIQuirk(dev.vendor, dev.device, dev.subvendor, dev.subdevice, domain,
152 bus, slot, func)
154 for (start, size) in dev.ioports:
155 log.debug('pci: enabling ioport 0x%x/0x%x'%(start,size))
156 rc = xc.domain_ioport_permission(domid = fe_domid, first_port = start,
157 nr_ports = size, allow_access = True)
158 if rc<0:
159 raise VmError(('pci: failed to configure I/O ports on device '+
160 '%s - errno=%d')%(dev.name,rc))
162 for (start, size) in dev.iomem:
163 # Convert start/size from bytes to page frame sizes
164 start_pfn = start>>PAGE_SHIFT
165 # Round number of pages up to nearest page boundary (if not on one)
166 nr_pfns = (size+(PAGE_SIZE-1))>>PAGE_SHIFT
168 log.debug('pci: enabling iomem 0x%x/0x%x pfn 0x%x/0x%x'% \
169 (start,size,start_pfn,nr_pfns))
170 rc = xc.domain_iomem_permission(domid = fe_domid,
171 first_pfn = start_pfn,
172 nr_pfns = nr_pfns,
173 allow_access = True)
174 if rc<0:
175 raise VmError(('pci: failed to configure I/O memory on device '+
176 '%s - errno=%d')%(dev.name,rc))
178 if dev.irq>0:
179 log.debug('pci: enabling irq %d'%dev.irq)
180 rc = xc.domain_irq_permission(domid = fe_domid, pirq = dev.irq,
181 allow_access = True)
182 if rc<0:
183 raise VmError(('pci: failed to configure irq on device '+
184 '%s - errno=%d')%(dev.name,rc))
186 def waitForBackend(self,devid):
187 return (0, "ok - no hotplug")