def collect_zone_element(zone_el, ignore_name, namespace, pools, image, bootinfo, machine): """Collect the contents of a zone.""" non_zone_ms = [] # New namespace for objects living in the memsection. zone_namespace = namespace.add_namespace(zone_el.name) physpool = getattr(zone_el, 'physpool', None) attrs = image.new_attrs(zone_namespace.add_namespace(zone_el.name)) zone = Zone(attrs, pools, image, machine) bootinfo.add_zone(zone) # Push the overriding attributes for the zone. image.push_attrs(virtual = zone_el.name, physical = physpool) master = Cap("master", ["master"]) zone.add_cap(master) zone_namespace.add(master.get_name(), master) for ms_el in zone_el.find_children('memsection'): if not ignore_name.match(ms_el.name): ms = collect_memsection_element(ms_el, ignore_name, zone_namespace, image, machine, pools) # Memsections that aren't allocated in the zone belong to the PD. if ms.get_attrs().virtpool == zone_el.name: zone.add_memsection(ms) image.add_group(None, [ms.get_ms()]) else: non_zone_ms.append(ms) # All of the segments have already been processed by the program/pd, but # record the ones probably should belong to the zone. These will be added # to the zone by PD.add_zone() segment_els = zone_el.find_children("segment") zone.claimed_segments = [segment_el.name for segment_el in segment_els] image.pop_attrs() return (zone, non_zone_ms)
def create_implicit_objects(self, namespace, machine, pools, image, bootinfo): """ Create memory objects that are implicitly defined by this physical device. The reason we have to do this now, rather than earlier or later, is because when the PhysicalDevice is created, we don't know who owns it, so we can't do memsection allocation yet. If we leave it until create_ops() when bootinfo instructions are generated, layout() is already determined, so that's too late. The only solution is to create the objects when you do collect_environment_element(). This guarantees that this function will only be called once. For physical devices, for each physmem we create a phys pool, and allocate memsections out of it. We grant a cap to the memsection to the containing PD. No objects are created for interrupts. """ from weaver.cells.iguana.bootinfo import Cap, PhysPool, MemSection caps = {} memsects = [] for (name, physmem) in self.gen_dev.physical_mem.iteritems(): # Create the physpool pool = pools.new_physical_pool("%s_pool" % name, machine) pp = PhysPool("%s_pool" % name, pool) bootinfo.add_physpool(pp) # This cap is probably never used. pns = namespace.add_namespace(pp.get_name()) master = Cap("master", ["master"]) pp.add_cap(master) pns.add(master.get_name(), master) cap_name = "%s_pool" % name caps[cap_name.upper()] = master for (base, size, _, _) in physmem: pp.add_memory(None, base, size, machine, pools) # Create the memsection attrs = image.new_attrs(namespace.add_namespace(name)) attrs.size = size attrs.pager = None attrs.physpool = pp.name attrs.scrub = False attrs.cache_policy = weaver.machine.CACHE_POLICIES['device'] # attrs.virtpool can only be determined when we know the owner PD ms = MemSection(image, machine, pools, attrs) # This cap is probably never used. master = Cap("master", ["master"]) ms.add_cap(master) memsects.append(ms) # Sigh. In order to support forward references in the # environment, this method is no longer called when the # environment tag is parsed. This means that the # memsection can't be added to the allocation group with # the rest of the items in the program. Therefore we'll # add it to it's own group here. The infrastructure to # add it to the program group is kept in place in the hope # that a better solution will be found. image.add_group(None, [ms.get_ms()]) # Return the list of caps, the XML parser should add it cap_name = "%s_ms" % name caps[cap_name.upper()] = master # Record the mapping self.mappings[name] = (pp, None, ms) return caps, memsects