Files
codezero/scripts/kernel/generate_kernel_cinfo.py
Bahadir Balban caa7ac0764 Put cinfo array into initdata section. Added more precision in bootmem
cinfo array is now freed along with other init memory.
bootmem allocator memory is reduced to be completely used up.
free boot memory now prints the used free memory as well.
2009-11-21 13:35:53 +02:00

192 lines
5.4 KiB
Python
Executable File

#! /usr/bin/env python2.6
# -*- mode: python; coding: utf-8; -*-
#
# Codezero -- a microkernel for embedded systems.
#
# Copyright © 2009 B Labs Ltd
#
import os, sys, shelve, glob
from os.path import join
from string import Template
PROJRELROOT = '../..'
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), PROJRELROOT)))
sys.path.append(os.path.abspath("../"))
from config.projpaths import *
from config.configuration import *
cinfo_file_start = \
'''/*
* Autogenerated container descriptions
* defined for the current build.
*
* Copyright (C) 2009 Bahadir Balban
*/
#include <l4/generic/container.h>
#include <l4/generic/resource.h>
#include <l4/generic/capability.h>
#include <l4/generic/cap-types.h>
%s
/*
* FIXME:
* Add irqs, exceptions
*/
__initdata struct container_info cinfo[] = {
'''
cinfo_file_end = \
'''
};
'''
cinfo_start = \
'''
\t[%d] = {
\t.name = "%s",
\t.npagers = 1,
\t.pager = {
'''
cinfo_end = \
'''
\t\t},
\t},
'''
pager_start = \
'''
\t\t[0] = {
\t\t\t.start_address = (CONFIG_CONT%(cn)d_START_PC_ADDR),
\t\t\t.pager_lma = __pfn(CONFIG_CONT%(cn)d_PAGER_LMA),
\t\t\t.pager_vma = __pfn(CONFIG_CONT%(cn)d_PAGER_VMA),
\t\t\t.pager_size = __pfn(page_align_up(CONT%(cn)d_PAGER_MAPSIZE)),
\t\t\t.ncaps = %(caps)d,
\t\t\t.caps = {
'''
pager_end = \
'''
\t\t\t},
\t\t},
'''
cap_virtmem = \
'''
\t\t\t[%(capidx)d] = {
\t\t\t\t.target = %(cn)d,
\t\t\t\t.type = CAP_TYPE_MAP_VIRTMEM | CAP_RTYPE_CONTAINER,
\t\t\t\t.access = CAP_MAP_READ | CAP_MAP_WRITE | CAP_MAP_EXEC
\t\t\t\t\t| CAP_MAP_CACHED | CAP_MAP_UNCACHED | CAP_MAP_UNMAP | CAP_MAP_UTCB,
\t\t\t\t.start = __pfn(CONFIG_CONT%(cn)d_VIRT%(vn)d_START),
\t\t\t\t.end = __pfn(CONFIG_CONT%(cn)d_VIRT%(vn)d_END),
\t\t\t\t.size = __pfn(CONFIG_CONT%(cn)d_VIRT%(vn)d_END - CONFIG_CONT%(cn)d_VIRT%(vn)d_START),
\t\t\t},
'''
cap_physmem = \
'''
\t\t\t[%(capidx)d] = {
\t\t\t\t.target = %(cn)d,
\t\t\t\t.type = CAP_TYPE_MAP_PHYSMEM | CAP_RTYPE_CONTAINER,
\t\t\t\t.access = CAP_MAP_READ | CAP_MAP_WRITE | CAP_MAP_EXEC |
\t\t\t\t\tCAP_MAP_CACHED | CAP_MAP_UNCACHED | CAP_MAP_UNMAP | CAP_MAP_UTCB,
\t\t\t\t.start = __pfn(CONFIG_CONT%(cn)d_PHYS%(pn)d_START),
\t\t\t\t.end = __pfn(CONFIG_CONT%(cn)d_PHYS%(pn)d_END),
\t\t\t\t.size = __pfn(CONFIG_CONT%(cn)d_PHYS%(pn)d_END - CONFIG_CONT%(cn)d_PHYS%(pn)d_START),
\t\t\t},
'''
pager_ifdefs_todotext = \
'''
/*
* TODO:
* This had to be defined this way because in CML2 there
* is no straightforward way to derive symbols from expressions, even
* it is stated in the manual that it can be done.
* As a workaround, a ternary expression of (? : ) was tried but this
* complains that type deduction could not be done.
*/'''
# This will be filled after the containers are compiled
# and pager binaries are formed
pager_mapsize = \
'''
#define CONT%d_PAGER_SIZE %s
'''
pager_ifdefs = \
'''
#if defined(CONFIG_CONT%(cn)d_TYPE_LINUX)
#define CONFIG_CONT%(cn)d_START_PC_ADDR \\
(CONFIG_CONT%(cn)d_LINUX_ZRELADDR - CONFIG_CONT%(cn)d_LINUX_PHYS_OFFSET + \\
CONFIG_CONT%(cn)d_LINUX_PAGE_OFFSET)
#define CONFIG_CONT%(cn)d_PAGER_LMA (CONFIG_CONT%(cn)d_LINUX_PHYS_OFFSET)
#define CONFIG_CONT%(cn)d_PAGER_VMA (CONFIG_CONT%(cn)d_LINUX_PAGE_OFFSET)
#define CONT%(cn)d_PAGER_MAPSIZE \\
(CONT%(cn)d_PAGER_SIZE + CONFIG_CONT%(cn)d_LINUX_ZRELADDR - \\
CONFIG_CONT%(cn)d_LINUX_PHYS_OFFSET)
#else
#define CONFIG_CONT%(cn)d_START_PC_ADDR (CONFIG_CONT%(cn)d_PAGER_VMA)
#define CONT%(cn)d_PAGER_MAPSIZE (CONT%(cn)d_PAGER_SIZE)
#endif
'''
def generate_pager_memory_ifdefs(config, containers):
pager_ifdef_string = ""
linux = 0
for c in containers:
if c.type == "linux":
if linux == 0:
pager_ifdef_string += pager_ifdefs_todotext
linux = 1
pager_ifdef_string += \
pager_mapsize % (c.id, c.pager_size)
pager_ifdef_string += pager_ifdefs % { 'cn' : c.id }
return pager_ifdef_string
def generate_kernel_cinfo(config, cinfo_path):
containers = config.containers
containers.sort()
print "Generating kernel cinfo..."
#config.config_print()
pager_ifdefs = generate_pager_memory_ifdefs(config, containers)
with open(cinfo_path, 'w+') as cinfo_file:
fbody = cinfo_file_start % pager_ifdefs
for c in containers:
# Currently only these are considered as capabilities
total_caps = c.virt_regions + c.phys_regions + len(c.caps)
fbody += cinfo_start % (c.id, c.name)
fbody += pager_start % { 'cn' : c.id, 'caps' : total_caps}
cap_index = 0
for mem_index in range(c.virt_regions):
fbody += cap_virtmem % { 'capidx' : cap_index, 'cn' : c.id, 'vn' : mem_index }
cap_index += 1
for mem_index in range(c.phys_regions):
fbody += cap_physmem % { 'capidx' : cap_index, 'cn' : c.id, 'pn' : mem_index }
cap_index += 1
for capkey, capstr in c.caps.items():
templ = Template(capstr)
fbody += templ.safe_substitute(idx = cap_index)
cap_index += 1
fbody += pager_end
fbody += cinfo_end
fbody += cinfo_file_end
cinfo_file.write(fbody)
if __name__ == "__main__":
config = configuration_retrieve()
if len(sys.argv) > 1:
generate_kernel_cinfo(config, join(PROJROOT, sys.argv[1]))
else:
generate_kernel_cinfo(config, join(PROJROOT, 'src/generic/cinfo.c'))