17 # Key is the rule name. Value is a mkrule object.
20 # List of targets in the order defined by makerule commands.
28 # make these a hash so they will be unique.
35 globalvars = {} # We will globals here
39 # options in order defined. These will be unique due to use of hash
48 local_path = re.compile(r'^\.')
50 # -----------------------------------------------------------------------------
52 # -----------------------------------------------------------------------------
56 def __init__(self, file, line, command):
59 self.command = command
60 def next_line(self, command):
61 self.line = self.line + 1
62 self.command = command
64 return "%s:%d" % (self.file, self.line)
70 return self.stack[-1].file
72 return self.stack[-1].line
74 return self.stack[-1].command
76 def push_file(self, file):
77 self.stack.append(self.place(file, 0, ""))
80 def next_line(self, command):
81 self.stack[-1].next_line(command)
83 return self.stack[-1].at()
87 def __init__ (self, target):
92 def addaction(self, action):
93 self.actions.append(action)
95 def adddependency(self, dependency):
96 self.dependency.append(dependency)
101 def gdependency(self):
102 return self.dependency
108 def __init__ (self, name):
109 self.name = name # name of option
110 self.loc = 0 # current location
111 self.value = 0 # option value
112 self.set = 0 # option has been set
113 self.used = 0 # option has been set
114 self.default = 0 # option has default value (otherwise
116 self.comment = '' # description of option
117 self.exportable = 0 # option is able to be exported
118 self.exported = 0 # option is exported
119 self.defined = 0 # option has a value
120 self.format = '%s' # option print format
122 def setvalue(self, value, loc):
124 print "Option %s: " % self.name
125 print "Attempt to set %s at %s" % (value, loc.at())
126 print "Already set to %s at %s" % \
127 (self.value, self.loc.at())
134 def getvalue(self, part):
136 if (not (type(self.value) is str)):
138 if (self.value == '' or self.value[0] != '{'):
140 # save curpart so we can evaluate expression
144 v = parse('delexpr', self.value)
145 # TODO: need to check for parse errors!
149 def setdefault(self, value, loc):
151 print "%s: " % self.name
152 print "Attempt to default %s at %s" % (value, loc)
153 print "Already defaulted to %s at %s" % \
154 (self.value, self.loc.at())
157 print "%s: " % self.name
158 print "Attempt to default %s at %s" % (value, loc)
159 print "Already set to %s at %s" % \
160 (self.value, self.loc.at())
168 def setnodefault(self, loc):
176 def setcomment(self, value, loc):
177 if (self.comment != ''):
178 print "%s: " % self.name
179 print "Attempt to modify comment at %s" % loc
183 def setexportable(self):
186 def setexported(self):
190 def setnoexport(self):
194 def setformat(self, fmt):
201 if (self.exportable):
205 def isexported(self):
206 return (self.exported and self.defined)
209 return (self.defined)
218 def __init__ (self, dir, parent, type):
221 print "partobj dir %s parent %s type %s" %(dir,parent,type)
224 self.registercode = []
230 self.instance = partinstance + 1
231 partinstance = partinstance + 1
237 print "add to parent"
239 parent.children.append(self)
243 def dumpme(self, lvl):
244 print "%d: type %s" % (lvl, self.type)
245 print "%d: dir %s" % (lvl,self.dir)
246 print "%d: parent %s" % (lvl,self.parent.type)
247 print "%d: parent dir %s" % (lvl,self.parent.dir)
248 print "%d: initcode " % lvl
249 for i in self.initcode:
251 print "%d: registercode " % lvl
252 for i in self.registercode:
256 print "struct cdev dev%d = {" % self.instance
257 print "/* %s %s */" % (self.type, self.dir)
258 print " .devfn = %d" % self.devfn
260 print " .next = &dev%d" % self.sibling.instance
262 print " .children = &dev%d" % \
263 self.children[0].instance
265 print " .private = private%d" % self.instance
272 def addinit(self, code):
273 self.initcode.append(code)
275 def addregister(self, code):
276 self.registercode.append(code)
278 def usesoption(self, name):
279 o = getvalue(options, name)
281 fatal("Error: can't use undefined option %s" % name)
283 setvalue(self.options, name, o)
285 print "option %s used in %s" % (name, self)
291 def push(self, part):
292 self.stack.append(part)
295 return self.stack.pop()
298 return self.stack[-1]
299 pstack = partsstack()
304 size = len(loc.stack)
307 print loc.stack[i].at()
309 print "%s: %s"% (loc.at(), string)
321 warnings = warnings + 1
322 print "===> Warning:"
323 size = len(loc.stack)
326 print loc.stack[i].at()
328 print "%s: %s"% (loc.at(), string)
331 # -----------------------------------------------------------------------------
333 # -----------------------------------------------------------------------------
335 def getvalue(dict, name):
336 if name not in dict.keys():
338 print 'Undefined:', name
340 v = dict.get(name, 0)
342 print "getvalue %s returning %s" % (name, v)
345 def setvalue(dict, name, value):
346 if name in dict.keys():
347 print "Warning, %s previously defined" % name
349 print "setvalue sets %s to %s" % (name, value)
353 # to create an option, it has to not exist.
354 # When an option value is fetched, the fact that it was used is
356 # Legal things to do:
357 # set a default value, then set a real value before the option is used.
358 # set a value, try to set a default, default silently fails.
360 # use the value, then try to set the value
363 o = getvalue(options, name)
365 print "option %s already defined" % name
368 setvalue(options, name, o)
369 options_by_order.append(name)
371 # option must be declared before being used in a part
372 # if we're not processing a part, then we must
373 # be at the top level where all options are available
374 def getoption(name, part):
377 o = getvalue(part.options, name)
379 o = getvalue(options, name)
380 if (o == 0 or not o.defined):
381 error("Error: Option %s undefined (missing use command?)." % name)
385 print "getoption returns %s" % v
386 print "%s" % o.where()
389 # setoptionstmt only allowed at top level
390 def setoptionstmt(name, value):
392 if (curpart != root):
393 fatal("Error: options can only be set in target configuration file")
394 setoption(name, value)
396 def setoption(name, value):
398 o = getvalue(options, name)
400 fatal("Error: attempt set nonexistent option %s" % name)
401 o.setvalue(value, loc)
403 def setdefault(name, value):
405 o = getvalue(options, name)
409 print "setdefault: attempt to duplicate default for %s" % name
411 o.setdefault(value, loc)
413 def setnodefault(name):
415 o = getvalue(options, name)
419 print "setdefault: attempt to duplicate default for %s" % name
423 def setcomment(name, value):
424 o = getvalue(options, name)
426 fatal("setcomment: %s not here" % name)
427 o.setcomment(value, loc)
429 def setexported(name):
430 o = getvalue(options, name)
432 fatal("setexported: %s not here" % name)
435 def setnoexport(name):
436 o = getvalue(options, name)
438 fatal("setnoexport: %s not here" % name)
441 def setexportable(name):
442 o = getvalue(options, name)
444 fatal("setexportable: %s not here" % name)
447 def setformat(name, fmt):
448 o = getvalue(options, name)
450 fatal("setformat: %s not here" % name)
453 def getformated(name, part):
456 o = getvalue(part.options, name)
458 o = getvalue(options, name)
459 if (o == 0 or not o.defined):
460 fatal( "Error: Option %s undefined (missing use command?)." % name)
465 def isexported(name, part):
467 o = getvalue(part.options, name)
469 o = getvalue(options, name)
471 return o.isexported()
474 def isdefined(name, part):
476 o = getvalue(part.options, name)
478 o = getvalue(options, name)
483 def isset(name, part):
485 o = getvalue(part.options, name)
487 o = getvalue(options, name)
492 def isused(name, part):
494 o = getvalue(part.options, name)
496 o = getvalue(options, name)
501 def usesoption(name):
503 curpart.usesoption(name)
505 def validdef(name, defval):
506 o = getvalue(options, name)
508 fatal("validdef: %s not here" % name)
509 if ((defval & 1) != 1):
510 fatal("Error: must specify default value for option %s" % name)
511 if ((defval & 2) != 2):
512 fatal("Error: must specify export for option %s" % name)
513 if ((defval & 4) != 4):
514 fatal("Error: must specify comment for option %s" % name)
518 optionsfile = os.path.join(treetop, 'src', 'config', 'Options.lb')
519 loc.push_file(optionsfile)
520 if (not parse('options', open(optionsfile, 'r').read())):
521 fatal("Error: Could not parse file")
524 # we do the crt0include as a dictionary, so that if needed we
525 # can trace who added what when. Also it makes the keys
527 def addcrt0include(path):
529 #fullpath = os.path.join(curdir, path)
531 #setvalue(crt0includes, fullpath, loc)
532 # oh shoot. Order matters. All right, we'll worry about this
536 print "ADDCRT0: %s" % fullpath
537 crt0includes.append(fullpath)
539 def addldscript(path):
542 fullpath = treetop + '/src/' + path
544 fullpath = curdir + '/' + path
545 #fullpath = os.path.join(curdir, path)
546 #setvalue(ldscripts, fullpath, loc)
548 print "fullpath :%s: curdir :%s: path :%s:" % (fullpath, curdir, path)
549 ldscripts.append(fullpath)
553 adduserdefine("PAYLOAD:=%s"%path)
555 # adddep('payload', path)
556 # addaction('payload', 'cp $< $@')
558 # this is called with an an object name.
559 # the easiest thing to do is add this object to the current
561 # such kludgery. If the name starts with '.' then make the
562 # dependency be on ./thing.x gag me.
563 def addobjectdriver(dict, object_name):
564 suffix = object_name[-2:]
567 base = object_name[:-2]
568 if (object_name[0] == '.'):
569 source = base + suffix
571 source = os.path.join(curdir, base + suffix)
574 print "add object %s source %s" % (object_name, source)
575 setvalue(dict, base, [object, source])
577 def addobject(object_name):
578 addobjectdriver(objectrules, object_name)
580 def adddriver(driver_name):
581 addobjectdriver(driverrules, driver_name)
583 def target(targ_name):
587 print "Configuring TARGET %s" % targ_name
588 target_dir = os.path.join(os.path.dirname(loc.file()), targ_name)
589 if not os.path.isdir(target_dir):
590 print "Creating directory %s" % target_dir
591 os.makedirs(target_dir)
592 print "Will place Makefile, crt0.S, etc. in %s" % target_dir
593 root = partobj(target_dir, 0, 'board')
596 def part(name, path, file):
597 global curpart,curdir,treetop
598 dirstack.append(curdir)
599 curdir = os.path.join(treetop, 'src', name, path)
600 newpart = partobj(curdir, curpart, name)
601 print "Configuring PART %s" % name
603 print "PUSH part %s %s" % (name, curpart.dir)
606 doconfigfile(curdir, file)
609 global curpart,curdir
610 print "End PART %s" % curpart.type
611 # Warn if options are used without being set in this part
612 for i in curpart.options.keys():
613 if (not isset(i, curpart)):
614 print "WARNING: Option %s using default value %s" % (i, getformated(i, curpart))
615 curpart = pstack.pop()
616 curdir = dirstack.pop()
618 # dodir is like part but there is no new part
619 def dodir(path, file):
620 global curdir, treetop
621 # if the first char is '/', it is relative to treetop,
622 # else relative to curdir
623 # os.path.join screws up if the name starts with '/', sigh.
625 fullpath = treetop + '/src/' + path
627 fullpath = os.path.join(curdir, path)
629 print "DODIR: path %s, fullpath %s" % (path, fullpath)
630 print "DODIR: curdis %s treetop %s" % (curdir, treetop)
631 print "Configuring DIR %s" % os.path.join(path, file)
632 dirstack.append(curdir)
634 file = os.path.join(fullpath, file)
635 config_file_list.append(file)
636 doconfigfile(fullpath, file)
637 curdir = dirstack.pop()
641 v = getoption(name, curpart)
645 def ternary(val, yes, no):
647 print "ternary %s" % expr
649 print "expr %s a %d yes %d no %d"% (expr, a, yes, no)
652 print "Ternary returns %d" % yes
656 print "Ternary returns %d" % no
659 # atoi is in the python library, but not strtol? Weird!
661 return eval('int(%s)' % name)
664 """ Is the given string an integer?"""
673 setvalue(makebaserules, id, o)
675 def adduserdefine(str):
676 userdefines.append(str)
679 a = re.sub("^\"", "", str)
680 a = re.sub("\"$", "", a)
681 # highly un-intuitive, need four \!
682 a = re.sub("\\\\\"", "\"", a)
685 def addaction(id, str):
686 o = getvalue(makebaserules, id)
691 o = getvalue(makebaserules, id)
695 # If the first part of <path> matches treetop, replace that part with "$(TOP)"
698 if path[0:len(treetop)] == treetop:
699 path = path[len(treetop):len(path)]
700 if (path[0:1] == "/"):
701 path = path[1:len(path)]
702 path = "$(TOP)/" + path
705 # arch is 'different' ... darn it.
706 def set_arch(my_arch):
710 setoption('ARCH', my_arch)
711 part('arch', my_arch, 'config/make.base.lb')
715 global mainboard_dir, treetop
717 full_mainboard_dir = os.path.join(treetop, 'src/mainboard', path)
718 setoption('MAINBOARD', full_mainboard_dir)
719 vendor = re.sub("/.*", "", path)
720 mainboard_part_number = re.sub("[^/]/", "", path)
721 setoption('MAINBOARD_VENDOR', vendor)
722 setoption('MAINBOARD_PART_NUMBER', mainboard_part_number)
723 part('mainboard', path, 'Config.lb')
725 #=============================================================================
727 #=============================================================================
728 def writemakefileheader(file, fname):
729 file.write("# File: %s\n" % fname)
730 file.write("# This file was generated by '%s %s %s'\n\n"
731 % (sys.argv[0], sys.argv[1], sys.argv[2]))
734 def writemakefilesettings(path):
735 global treetop, arch, mainboard_dir, target_dir, options_by_order, root
736 # Write Makefile.settings to seperate the settings
737 # from the actual makefile creation
738 # In practice you need to rerun NLBConfig.py to change
739 # these but in theory you shouldn't need to.
741 filename = os.path.join(path, "Makefile.settings")
742 print "Creating", filename
743 file = open(filename, 'w+')
744 writemakefileheader(file, filename)
745 file.write("TOP:=%s\n" % (treetop))
746 #file.write("ARCH:=%s\n" % (arch))
747 #file.write("MAINBOARD:=%s\n" % (mainboard_dir))
748 file.write("TARGET_DIR:=%s\n" % (target_dir))
749 for i in options_by_order:
750 if (isexported(i, 0)):
751 file.write("export %s:=%s\n" % (i, getformated(i, 0)))
752 file.write("export VARIABLES := ")
753 for i in options.keys():
754 if (isexported(i, 0)):
755 file.write("%s " % i)
757 # file.write("CPUFLAGS := ")
758 # for i in options.keys():
760 # file.write("-D%s=%s " % (i, o.getvalue()))
766 # let's try the Makefile
767 # first, dump all the -D stuff
769 def writemakefile(path):
771 makefilepath = os.path.join(path, "Makefile")
772 print "Creating", makefilepath
773 file = open(makefilepath, 'w+')
774 writemakefileheader(file, makefilepath)
776 # file.write("include Makefile.settings\n")
777 # file.write("include cpuflags\n")
778 # Putting "include cpuflags" in the Makefile has the problem that the
779 # cpuflags file would be generated _after_ we want to include it.
780 # Instead, let make do the work of computing CPUFLAGS:
782 # Get the value of TOP, VARIABLES, and several other variables.
783 include Makefile.settings
785 # Function to create an item like -Di586 or -DMAX_CPUS='1' or -Ui686
786 D_item = $(if $(subst undefined,,$(origin $1)),-D$1$(if $($1),='$($1)',),-U$1)
788 # Compute the value of CPUFLAGS here during make's first pass.
789 CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))
792 for i in userdefines:
793 file.write("%s\n" %i)
796 # print out all the object dependencies
797 file.write("\n# object dependencies (objectrules:)\n")
798 file.write("OBJECTS :=\n")
799 file.write("DRIVERS :=\n")
800 for objrule in objectrules.keys():
801 obj = objectrules[objrule]
804 file.write("OBJECTS-1 += %s\n" % (obj_name))
806 for driverrule in driverrules.keys():
807 driver = driverrules[driverrule]
809 obj_source = driver[1]
810 file.write("DRIVER += %s\n" % (obj_name))
812 # Print out all ldscript.ld dependencies.
813 file.write("\n# ldscript.ld dependencies:\n")
814 file.write("LDSUBSCRIPTS-1 := \n" )
815 for script in ldscripts:
816 file.write("LDSUBSCRIPTS-1 += %s\n" % topify(script))
818 # Print out the dependencies for crt0_includes.h
819 file.write("\n# Dependencies for crt0_includes.h\n")
820 file.write("CRT0_INCLUDES:=\n")
821 for i in crt0includes:
822 if (local_path.match(i)):
823 file.write("CRT0_INCLUDES += %s\n" % i)
825 file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % i)
827 file.write("\nSOURCES=\n")
828 #for source in sources:
829 #file.write("SOURCES += %s\n" % source)
831 # Print out the user defines.
832 file.write("\n# userdefines:\n")
833 #for udef in userdefines:
834 #file.write("%s\n" % udef)
836 # Print out the base rules.
837 # Need to have a rule that counts on 'all'.
838 file.write("\n# mainrulelist:")
839 #file.write("\nmainrule: %s\n" % mainrulelist)
841 # Print out any user rules.
842 file.write("\n# From makerule or docipl commands:\n")
843 # Old way (hash order): for target in makebaserules.keys():
844 # New way (config file order):
845 #for target in makerule_targets:
846 #makebaserules[target].write(file)
848 file.write("\n# objectrules:\n")
849 for objrule in objectrules.keys():
850 obj = objectrules[objrule]
851 source = topify(obj[1])
852 file.write("%s: %s\n" % (obj[0], source))
853 file.write("\t$(CC) -c $(CFLAGS) -o $@ $<\n")
854 #file.write("%s\n" % objrule[2])
856 for driverrule in driverrules.keys():
857 driver = driverrules[driverrule]
858 source = topify(driver[1])
859 file.write("%s: %s\n" % (driver[0], source))
860 #file.write("%s\n" % objrule[2])
862 # Print out the rules that will make cause the files
863 # generated by NLBConfig.py to be remade if any dependencies change.
865 file.write("\n# Remember the automatically generated files\n")
866 file.write("GENERATED:=\n")
867 for genfile in [ 'Makefile',
872 'LinuxBIOSDoc.config' ]:
873 file.write("GENERATED += %s\n" % genfile)
875 file.write("\n# Remake Makefile (and the other files generated by\n")
876 file.write("# NLBConfig.py) if any config dependencies change.\n")
878 for cfile in config_file_list:
879 file.write("$(GENERATED): %s\n" % topify(cfile))
881 for depfile in [ '%s' % top_config_file, # This a duplicate, remove?
882 '$(TOP)/util/config/NLBConfig.py',
883 '$(TOP)/src/arch/$(ARCH)/config/make.base' ]:
884 file.write("$(GENERATED): %s\n" % depfile)
886 file.write("$(GENERATED):\n")
887 file.write("\tpython $(TOP)/util/config/NLBConfig.py %s $(TOP)\n"
890 keys = root.options.keys()
892 file.write("\necho:\n")
894 file.write("\t@echo %s='$(%s)'\n"% (key,key))
897 for i in makebaserules.keys():
899 file.write("%s: " %i)
900 for i in m.dependency:
901 file.write("%s " % i)
904 file.write("\t%s\n" % i)
907 # Write out crt0_includes.h (top-level assembly language) include file.
908 def writecrt0_includes(path):
909 crt0filepath = os.path.join(path, "crt0_includes.h")
910 print "Creating", crt0filepath
911 file = open(crt0filepath, 'w+')
913 for i in crt0includes:
914 file.write("#include <%s>\n" % i)
924 # less general tokens should come first, otherwise they get matched
927 token ADDACTION: 'addaction'
928 token ALWAYS: 'always'
930 token COMMENT: 'comment'
932 token DEFAULT: 'default'
933 token DEFINE: 'define'
936 token DRIVER: 'driver'
940 token EXPORT: 'export'
941 token FORMAT: 'format'
944 token LDSCRIPT: 'ldscript'
945 token LOADOPTIONS: 'loadoptions'
946 token MAINBOARD: 'mainboard'
947 token MAINBOARDINIT: 'mainboardinit'
948 token MAKEDEFINE: 'makedefine'
949 token MAKERULE: 'makerule'
952 token NORTHBRIDGE: 'northbridge'
953 token OBJECT: 'object'
954 token OPTION: 'option'
955 token PAYLOAD: 'payload'
957 token REGISTER: 'register'
958 token SOUTHBRIDGE: 'southbridge'
959 token SUPERIO: 'superio'
960 token TARGET: 'target'
964 token XNUM: r'0x[0-9a-fA-F]+'
965 # Why is path separate? Because paths to resources have to at least
966 # have a slash, we thinks
967 token PATH: r'[a-zA-Z0-9_.][a-zA-Z0-9/_.]+[a-zA-Z0-9_.]+'
968 # Dir's on the other hand are abitrary
969 # this may all be stupid.
970 token DIRPATH: r'[a-zA-Z0-9_$()./]+'
971 token ID: r'[a-zA-Z_.]+[a-zA-Z0-9_.]*'
972 token DELEXPR: r'{([^}]+|\\.)*}'
973 token STR: r'"([^\\"]+|\\.)*"'
976 rule expr: logical {{ l = logical }}
977 ( "&&" logical {{ l = l and logical }}
978 | "||" logical {{ l = l or logical }}
981 rule logical: factor {{ n = factor }}
982 ( "[+]" factor {{ n = n+factor }}
983 | "-" factor {{ n = n-factor }}
986 rule factor: term {{ v = term }}
987 ( "[*]" term {{ v = v*term }}
988 | "/" term {{ v = v/term }}
989 | "<<" term {{ v = v << term }}
990 | ">=" term {{ v = (v < term)}}
993 # A term is a number, variable, or an expression surrounded by parentheses
994 rule term: NUM {{ return atoi(NUM) }}
995 | XNUM {{ return tohex(XNUM) }}
996 | ID {{ return lookup(ID) }}
997 | unop {{ return unop }}
998 | "\\(" expr "\\)" {{ return expr }}
1000 rule unop: "!" expr {{ return not(expr) }}
1002 rule partend<<C>>: (stmt<<C>>)* END {{ partpop()}}
1004 rule mainboard: MAINBOARD PATH {{ mainboard(PATH) }}
1007 rule northbridge<<C>>:
1008 NORTHBRIDGE PATH {{ if (C): part('northbridge', PATH, 'Config.lb') }}
1011 rule superio<<C>>: SUPERIO PATH {{ if (C): part('superio', PATH, 'Config.lb') }}
1014 rule cpu<<C>>: CPU ID {{ if (C): part('cpu', ID, 'Config.lb') }}
1017 rule pmc<<C>>: PMC PATH {{ if (C): part('pmc', PATH, 'Config.lb') }}
1020 rule arch<<C>>: ARCH ID {{ if (C): set_arch(ID) }}
1023 rule southbridge<<C>>:
1024 SOUTHBRIDGE PATH {{ if (C): part('southbridge', PATH, 'Config.lb')}}
1027 rule mainboardinit<<C>>:
1028 MAINBOARDINIT DIRPATH {{ if (C): addcrt0include(DIRPATH)}}
1030 rule object<<C>>: OBJECT DIRPATH {{ if (C): addobject(DIRPATH)}}
1032 rule driver<<C>>: DRIVER DIRPATH {{ if (C): adddriver(DIRPATH)}}
1034 rule dir<<C>>: DIR DIRPATH {{ if (C): dodir(DIRPATH, 'Config.lb') }}
1036 rule ldscript<<C>>: LDSCRIPT DIRPATH {{ if (C): addldscript(DIRPATH) }}
1038 rule payload<<C>>: PAYLOAD DIRPATH {{ if (C): payload(DIRPATH) }}
1040 # if is a bad id ....
1041 # needs to be C and ID, but nested if's are, we hope, not going to
1042 # happen. IF so, possibly ID && C could be used.
1043 rule iif<<C>>: IF ID {{ c = lookup(ID) }}
1044 (stmt<<c>>)* [ ELSE (stmt<<not c>>)* ] END
1046 rule depsacts<<ID, C>>:
1047 ( DEP STR {{ if (C): adddep(ID, STR) }}
1048 | ACT STR {{ if (C): addaction(ID, STR) }}
1051 rule makerule<<C>>: MAKERULE DIRPATH {{ if (C): addrule(DIRPATH) }}
1052 depsacts<<DIRPATH, C>>
1054 rule makedefine<<C>>:
1055 MAKEDEFINE RAWTEXT {{ if (C): adduserdefine(RAWTEXT) }}
1057 rule addaction<<C>>:
1058 ADDACTION ID STR {{ if (C): addaction(ID, STR) }}
1060 rule init<<C>>: INIT STR {{ if (C): curpart.addinit(STR) }}
1062 rule register<<C>>: REGISTER STR {{ if (C): curpart.addregister(STR) }}
1064 # to make if work without 2 passses, we use an old hack from SIMD, the
1065 # context bit. If the bit is 1, then ops get done, otherwise
1066 # ops don't get done. From the top level, context is always
1067 # 1. In an if, context depends on eval of the if condition
1068 rule stmt<<C>>: cpu<<C>> {{ return cpu}}
1069 | pmc<<C>> {{ return pmc}}
1070 | arch<<C>> {{ return arch}}
1071 | northbridge<<C>> {{ return northbridge }}
1072 | southbridge<<C>> {{ return southbridge }}
1073 | superio<<C>> {{ return superio }}
1074 | object<<C>> {{ return object }}
1075 | driver<<C>> {{ return driver }}
1076 | mainboardinit<<C>> {{ return mainboardinit }}
1077 | makerule<<C>> {{ return makerule }}
1078 | makedefine<<C>> {{ return makedefine }}
1079 | addaction<<C>> {{ return addaction }}
1080 | init<<C>> {{ return init }}
1081 | register<<C>> {{ return register}}
1082 | iif<<C>> {{ return iif }}
1083 | dir<<C>> {{ return dir}}
1084 | ldscript<<C>> {{ return ldscript}}
1085 | payload<<C>> {{ return payload}}
1087 # ENTRY for parsing Config.lb file
1088 rule cfgfile: (uses<<1>>)* (stmt<<1>>)*
1091 rule usesid<<C>>: ID {{ if (C): usesoption(ID) }}
1093 rule uses<<C>>: USES (usesid<<C>>)+
1095 rule value: STR {{ return dequote(STR) }}
1096 | expr {{ return expr }}
1097 | DELEXPR {{ return DELEXPR }}
1099 rule option<<C>>: OPTION ID EQ value {{ if (C): setoptionstmt(ID, value) }}
1101 rule opif: IF ID {{ c = lookup(ID) }}
1102 (option<<c>>)* [ ELSE (option<<not c>>)* ] END
1104 rule opstmt: option<<1>>
1107 # ENTRY for parsing a delayed value
1108 rule delexpr: "{" expr "}" {{ return expr }}
1110 # ENTRY for parsing root part
1111 rule board: LOADOPTIONS {{ loadoptions() }}
1112 TARGET DIRPATH {{ target(DIRPATH) }}
1115 mainboard {{ return 1 }}
1117 rule defstmts<<ID>>: {{ d = 0 }}
1119 ( value {{ setdefault(ID, value) }}
1120 | NONE {{ setnodefault(ID) }}
1122 | FORMAT STR {{ setformat(ID, dequote(STR)) }}
1124 ( ALWAYS {{ setexported(ID) }}
1125 | USED {{ setexportable(ID) }}
1126 | NEVER {{ setnoexport(ID) }}
1128 | COMMENT STR {{ setcomment(ID, dequote(STR)); d = d | 4 }}
1131 rule define: DEFINE ID {{ newoption(ID) }}
1132 defstmts<<ID>> END {{ validdef(ID, defstmts) }}
1134 # ENTRY for parsing Options.lb file
1135 rule options: (define)* END {{ return 1 }}
1138 def dumptree(part, lvl):
1140 print "DUMPTREE ME is"
1142 # dump the siblings -- actually are there any? not sure
1145 print "DUMPTREE KIDS are"
1146 for kid in part.children:
1147 dumptree(kid, lvl+1)
1149 print "DONE DUMPTREE"
1153 print "GENCODE ME is"
1156 # dump the siblings -- actually are there any? not sure
1159 print "GENCODE KIDS are"
1160 for kid in part.children:
1163 print "DONE GENCODE"
1166 def doconfigfile(path, file):
1167 filename = os.path.join(path, file)
1168 loc.push_file(filename)
1169 if (not parse('cfgfile', open(filename, 'r').read())):
1170 fatal("Error: Could not parse file")
1173 if __name__=='__main__':
1174 from sys import argv
1176 print 'Args: <file> <path to linuxbios>'
1179 top_config_file = os.path.abspath(sys.argv[1])
1181 treetop = os.path.abspath(sys.argv[2])
1183 # Now read in the customizing script...
1184 loc.push_file(argv[1])
1185 if (not parse('board', open(argv[1], 'r').read())):
1186 fatal("Error: Could not parse file")
1189 print "DEVICE TREE:"
1196 for i in crt0includes:
1197 print "crt0include file %s" % (i)
1198 for i in driverrules.keys():
1199 print "driver file %s" % (i)
1201 print "ldscript file %s" % (i)
1202 for i in makebaserules.keys():
1203 m = makebaserules[i]
1204 print " makerule %s dep %s act %s" % (i, m.dependency, m.actions)
1206 writemakefilesettings(target_dir)
1207 writecrt0_includes(target_dir)
1208 writemakefile(target_dir)