[ros-diffs] [arty] 28757: Add interface generator for open firmware calls.

arty at svn.reactos.org arty at svn.reactos.org
Sun Sep 2 11:02:13 CEST 2007


Author: arty
Date: Sun Sep  2 13:02:12 2007
New Revision: 28757

URL: http://svn.reactos.org/svn/reactos?rev=28757&view=rev
Log:
Add interface generator for open firmware calls.

Added:
    trunk/reactos/tools/ofw_interface/
    trunk/reactos/tools/ofw_interface/calls.ofw
    trunk/reactos/tools/ofw_interface/ofw_interface.cpp
    trunk/reactos/tools/ofw_interface/ofw_interface.mak
Modified:
    trunk/reactos/tools/tools.mak

Added: trunk/reactos/tools/ofw_interface/calls.ofw
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/ofw_interface/calls.ofw?rev=28757&view=auto
==============================================================================
--- trunk/reactos/tools/ofw_interface/calls.ofw (added)
+++ trunk/reactos/tools/ofw_interface/calls.ofw Sun Sep  2 13:02:12 2007
@@ -1,0 +1,25 @@
+# Function		Args	Returns	Types
+# Real OFW functions to proxy
+finddevice		1	1	char* int
+open			1	1	char* int
+getprop			4	1	int char* char*:arg3 int int
+write			3	1	int char*:arg2 int int
+read			3	1	int char*:arg2 int int
+exit			0	0	
+child			1	1	int int
+peer			1	1	int int
+parent			1	1	int int
+seek			3	1	int int int int
+# MMU methods 
+# claim (virt size align -- base)
+claim			3	1	int int int int
+# claim-mem (size align -- base)
+claim-mem		2	1	int int int
+# release (virt size --)
+release			2	0	int int
+package-to-path         3       1       int char*:arg2 int int
+# Declare the call-method BE function
++call-method		0	0	
+# MMU Methods
+ at phys2virt!translate	4	1	int int int int&0 int
+ at virt2phys!translate	2	1	int int&1 int

Added: trunk/reactos/tools/ofw_interface/ofw_interface.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/ofw_interface/ofw_interface.cpp?rev=28757&view=auto
==============================================================================
--- trunk/reactos/tools/ofw_interface/ofw_interface.cpp (added)
+++ trunk/reactos/tools/ofw_interface/ofw_interface.cpp Sun Sep  2 13:02:12 2007
@@ -1,0 +1,316 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+class ofw_wrappers {
+public:
+    int base, ctindex, method_ctindex;
+    std::string functions;
+    std::string names;
+    std::string calltable;
+    std::string le_stubs;
+    std::string of_call;
+};
+
+class vartype {
+public:
+    vartype( const std::string &typestr ) {
+	size_t amp = typestr.find('&');
+	size_t col = typestr.find(':');
+	if( amp != std::string::npos ) {
+	    if( col > amp && col != std::string::npos )
+		lit_value = typestr.substr(amp+1,col-amp+1);
+	    else lit_value = typestr.substr(amp+1);
+	}
+	if( col != std::string::npos ) {
+	    if( amp > col && amp != std::string::npos ) 
+		len = typestr.substr(col+1,amp-col+1);
+	    else len = typestr.substr(col+1);
+	}
+
+	if( amp != std::string::npos && amp < col ) col = amp;
+	if( col == std::string::npos ) col = typestr.size();
+	c_type = typestr.substr(0,col);
+    }
+
+    vartype( const vartype &other ) 
+	: c_type(other.c_type),
+	  len(other.len),
+	  lit_value(other.lit_value) {
+    }
+
+    vartype &operator = ( const vartype &other ) {
+	c_type = other.c_type;
+	len = other.len;
+	lit_value = other.lit_value;
+	return *this;
+    }
+
+    std::string c_type;
+    std::string len;
+    std::string lit_value;
+};
+
+std::string uppercase( const std::string &toucase ) {
+    std::vector<char> ucase_work(toucase.size());
+    for( size_t i = 0; i < toucase.size(); i++ ) {
+	ucase_work[i] = toupper(toucase[i]);
+    }
+    return std::string(&ucase_work[0], toucase.size());
+}
+
+std::string clip_eol( std::string in, const std::string &eol_marks ) {
+    size_t found;
+    for( size_t i = 0; i < eol_marks.size(); i++ ) {
+	found = in.find( eol_marks[i] );
+	if( found != std::string::npos ) 
+	    in = in.substr( 0, found );
+    }
+    return in;
+}
+
+int round_up( int x, int factor ) {
+    return (x + (factor - 1)) & ~(factor - 1);
+}
+
+void populate_definition( ofw_wrappers &wrapper, const std::string &line ) {
+    std::istringstream iss(line);
+    bool make_function = true, method_call = false, make_stub = true, comma;
+    std::string name, nametext, argtype, rettype;
+    std::vector<vartype> argtypes;
+    int args, rets, i, local_offset, total_stack, userarg_start = 0;
+    size_t f;
+    std::ostringstream function, ct_csource, le_stub, of_call;
+
+    iss >> name >> args >> rets;
+
+    if( !name.size() ) return;
+
+    if( (f = name.find('!')) != std::string::npos ) {
+	nametext = name.substr(f+1);
+	name = name.substr(0,f);
+    }
+    if( name[0] == '-' ) {
+	name = name.substr(1);
+	make_function = false;
+    }
+    if( name[0] == '+' ) {
+	name = name.substr(1);
+	make_stub = false;
+    }
+    if( name[0] == '@' ) {
+	name = name.substr(1);
+	method_call = true;
+	make_function = false;
+    }
+
+    if( !nametext.size() ) nametext = name;
+
+    for( i = 1; i < (int)name.size(); i++ )
+	if( name[i] == '-' ) name[i] = '_';
+
+    if( nametext == "call-method" ) 
+	wrapper.method_ctindex = wrapper.ctindex;
+
+    for( i = 0; i < args; i++ ) {
+        iss >> argtype;
+	argtypes.push_back(vartype(argtype));
+    }
+
+    if( method_call ) {
+	userarg_start = 1;
+	args += 2;
+    }
+
+    iss >> rettype;
+    if( !rettype.size() ) rettype = "void";
+
+    local_offset = (3 + rets + args) * 4;
+    total_stack = round_up(12 + local_offset, 16);
+
+    function << "asm_ofw_" << name << ":\n"
+	     << "\t/* Reserve stack space */\n"
+	     << "\tsubi %r1,%r1," << total_stack << "\n"
+	     << "\t/* Store r8, r9, lr */\n"
+	     << "\tstw %r8," << (local_offset + 0) << "(%r1)\n"
+	     << "\tstw %r9," << (local_offset + 4) << "(%r1)\n"
+	     << "\tmflr %r8\n"
+	     << "\tstw %r8," << (local_offset + 8) << "(%r1)\n"
+	     << "\t/* Get read name */\n"
+	     << "\tlis %r8," << name << "_ofw_name at ha\n"
+	     << "\taddi %r9,%r8," << name << "_ofw_name at l\n"
+	     << "\tstw %r9,0(%r1)\n"
+	     << "\t/* " << args << " arguments and " << rets << " return */\n"
+	     << "\tli %r9," << args << "\n"
+	     << "\tstw %r9,4(%r1)\n"
+	     << "\tli %r9," << rets << "\n"
+	     << "\tstw %r9,8(%r1)\n";
+
+    for( int i = 0; i < args; i++ )
+	function << "\tstw %r" << (i+3) << "," << (4 * (i + 3)) << "(%r1)\n";
+	    
+    function << "\t/* Load up the call address */\n"
+             << "\tlis %r10,ofw_call_addr at ha\n"
+	     << "\tlwz %r9,ofw_call_addr at l(%r10)\n"
+	     << "\tmtlr %r9\n"
+	     << "\t/* Set argument */\n"
+	     << "\tmr %r3,%r1\n"
+	     << "\t/* Fire */\n"
+	     << "\tblrl\n"
+	     << "\tlwz %r3," << (local_offset - 4) << "(%r1)\n"
+	     << "\t/* Restore registers */\n"
+	     << "\tlwz %r8," << (local_offset + 8) << "(%r1)\n"
+	     << "\tmtlr %r8\n"
+	     << "\tlwz %r9," << (local_offset + 4) << "(%r1)\n"
+	     << "\tlwz %r8," << (local_offset + 0) << "(%r1)\n"
+	     << "\t/* Return */\n"
+	     << "\taddi %r1,%r1," << total_stack << "\n"
+	     << "\tblr\n";
+
+    if( method_call ) {
+	argtypes.insert(argtypes.begin(),vartype("int"));
+	argtypes.insert(argtypes.begin(),vartype("char*"));
+    }
+
+    le_stub << rettype << " ofw_" << name << "(";
+
+    comma = false;
+    for( i = userarg_start; i < args; i++ ) {
+	if( !argtypes[i].lit_value.size() ) {
+	    if( !comma ) comma = true; else le_stub << ",";
+	    le_stub << argtypes[i].c_type << " arg" << i;
+	}
+    }
+    le_stub << ")";
+    of_call << le_stub.str() << ";\n";
+
+    le_stub << " {\n";
+    if( rettype != "void" ) 
+	le_stub << "\t" << rettype << " ret;\n";
+
+    if( method_call ) {
+	le_stub << "\tchar arg0[" 
+		<< round_up(nametext.size()+1,8) 
+		<< "] = \"" << nametext << "\";\n";
+    }
+
+    for( i = 0; i < args; i++ ) {
+	if( argtypes[i].lit_value.size() ) {
+	    le_stub << "\t" << argtypes[i].c_type << " arg" << i << " = " 
+		    << argtypes[i].lit_value << ";\n";
+	}
+    }
+
+    le_stub << "\t";
+    if( rettype != "void" ) le_stub << "ret = (" << rettype << ")";
+
+    le_stub << "ofproxy(" << 
+      (method_call ? (wrapper.method_ctindex * 4) : (wrapper.ctindex * 4));
+
+    for( i = 0; i < 6; i++ ) {
+	if( i < args ) le_stub << ",(void *)arg" << i;
+	else le_stub << ",NULL";
+    }
+
+    le_stub << ");\n";
+
+    if( rettype != "void" ) 
+	le_stub << "\treturn ret;\n";
+
+    le_stub << "}\n";
+
+    if( make_function ) wrapper.functions += function.str();
+    if( make_stub ) {
+	wrapper.le_stubs += le_stub.str();
+	wrapper.of_call += of_call.str();
+    }
+    if( !method_call ) {
+	wrapper.names += name + "_ofw_name:\n\t.asciz \"" + nametext + "\"\n";
+	wrapper.calltable += std::string("\t.long asm_ofw_") + name + "\n";
+	wrapper.ctindex++;
+    }
+}
+
+int main( int argc, char **argv ) {
+    int status = 0;
+    std::ifstream in;
+    std::ofstream out, outcsource, outcheader;
+    std::string line;
+    const char *eol_marks = "#\r\n";
+    ofw_wrappers wrappers;
+
+    wrappers.base = 0xe00000;
+    wrappers.ctindex = 0;
+
+    if( argc < 5 ) {
+	fprintf( stderr, "%s [interface.ofw] [ofw.s] [le_stub.c] [le_stub.h]\n", argv[0] );
+	return 1;
+    }
+
+    in.open( argv[1] );
+    if( !in ) {
+	fprintf( stderr, "can't open %s\n", argv[1] );
+	status = 1;
+	goto error;
+    }
+
+    out.open( argv[2] );
+    if( !out ) {
+	fprintf( stderr, "can't open %s\n", argv[2] );
+	status = 1;
+	goto error;
+    }
+
+    outcsource.open( argv[3] );
+    if( !outcsource ) {
+	fprintf( stderr, "can't open %s\n", argv[3] );
+	status = 1;
+	goto error;
+    }
+
+    outcheader.open( argv[4] );
+    if( !outcheader ) {
+	fprintf( stderr, "can't open %s\n", argv[4] );
+	status = 1;
+	goto error;
+    }
+
+    while( std::getline( in, line ) ) {
+	line = clip_eol( line, eol_marks );
+	if( line.size() ) populate_definition( wrappers, line );
+    }
+
+    out << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n"
+	<< "\t.section .text\n"
+	<< "\t.align 4\n"
+	<< "\t.globl _start\n"
+        << "\t.globl ofw_functions\n"
+	<< "\t.globl ofw_call_addr\n"
+	<< "ofw_call_addr:\n"
+	<< "\t.long 0\n"
+	<< "\n/* Function Wrappers */\n\n"
+	<< wrappers.functions
+	<< "\n/* Function Names */\n\n"
+	<< wrappers.names
+	<< "\n/* Function Call Table for Freeldr */\n\n"
+        << "\t.align 4\n"
+	<< "ofw_functions:\n"
+	<< wrappers.calltable
+	<< "\n/* End */\n";
+
+    outcsource << "/* AUTOMATICALLY GENERATED BY ofw_interface */\n"
+	       << "#include \"of.h\"\n" 
+	       << wrappers.le_stubs;
+
+    outcheader << "/* AUTOMATICALLY GENERATE BY ofw_interface */\n"
+	       << "#ifndef _OFW_CALLS_H\n"
+	       << "#define _OFW_CALLS_H\n"
+	       << wrappers.of_call
+	       << "#endif/*_OFW_CALLS_H*/\n";
+
+error:
+    return status;
+}

Added: trunk/reactos/tools/ofw_interface/ofw_interface.mak
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/ofw_interface/ofw_interface.mak?rev=28757&view=auto
==============================================================================
--- trunk/reactos/tools/ofw_interface/ofw_interface.mak (added)
+++ trunk/reactos/tools/ofw_interface/ofw_interface.mak Sun Sep  2 13:02:12 2007
@@ -1,0 +1,63 @@
+OFW_INTERFACE_BASE = $(TOOLS_BASE_)ofw_interface
+OFW_INTERFACE_BASE_ = $(OFW_INTERFACE_BASE)$(SEP)
+OFW_INTERFACE_INT = $(INTERMEDIATE_)$(OFW_INTERFACE_BASE)
+OFW_INTERFACE_INT_ = $(OFW_INTERFACE_INT)$(SEP)
+OFW_INTERFACE_OUT = $(OUTPUT_)$(OFW_INTERFACE_BASE)
+OFW_INTERFACE_OUT_ = $(OFW_INTERFACE_OUT)$(SEP)
+
+OFW_INTERFACE_OUTPUT = boot/freeldr/freeldr/arch/powerpc/ofw_calls.s
+OFW_INTERFACE_SOURCE = boot/freeldr/freeldr/arch/powerpc/ofw.c
+OFW_INTERFACE_HEADER = boot/freeldr/freeldr/include/of_call.h
+OFW_INTERFACE_INPUT = $(OFW_INTERFACE_BASE_)calls.ofw
+OFW_INTERFACE_SERVICE_FILES = \
+	$(OFW_INTERFACE_OUTPUT) \
+	$(OFW_INTERFACE_SOURCE) \
+	$(OFW_INTERFACE_HEADER)
+
+$(OFW_INTERFACE_INT): | $(TOOLS_INT)
+	$(ECHO_MKDIR)
+	${mkdir} $@
+
+ifneq ($(INTERMEDIATE),$(OUTPUT))
+$(OFW_INTERFACE_OUT): | $(TOOLS_OUT)
+	$(ECHO_MKDIR)
+	${mkdir} $@
+endif
+
+OFW_INTERFACE_TARGET = \
+	$(EXEPREFIX)$(OFW_INTERFACE_OUT_)ofw_interface$(EXEPOSTFIX)
+
+OFW_INTERFACE_SOURCES = $(addprefix $(OFW_INTERFACE_BASE_), \
+	ofw_interface.cpp \
+	)
+
+OFW_INTERFACE_OBJECTS = \
+	$(addprefix $(INTERMEDIATE_), $(OFW_INTERFACE_SOURCES:.cpp=.o))
+
+OFW_INTERFACE_HOST_CFLAGS = $(TOOLS_CFLAGS)
+
+OFW_INTERFACE_HOST_LFLAGS = $(TOOLS_LFLAGS)
+
+$(OFW_INTERFACE_TARGET): $(OFW_INTERFACE_OBJECTS) | $(OFW_INTERFACE_OUT)
+	$(ECHO_LD)
+	${host_gpp} $(OFW_INTERFACE_OBJECTS) $(OFW_INTERFACE_HOST_LFLAGS) -o $@
+
+$(OFW_INTERFACE_INT_)ofw_interface.o: $(OFW_INTERFACE_BASE_)ofw_interface.cpp | $(OFW_INTERFACE_INT)
+	$(ECHO_CC)
+	${host_gpp} $(OFW_INTERFACE_HOST_CFLAGS) -c $< -o $@
+
+$(OFW_INTERFACE_SERVICE_FILES): $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_INPUT)
+	$(ECHO_OFW)
+	$(Q)$(OFW_INTERFACE_TARGET) \
+		$(OFW_INTERFACE_INPUT) \
+		$(OFW_INTERFACE_OUTPUT) \
+		$(OFW_INTERFACE_SOURCE) \
+		$(OFW_INTERFACE_HEADER)
+	
+.PHONY: ofw_interface
+ofw_interface: $(OFW_INTERFACE_TARGET)
+
+.PHONY: ofw_interface_clean
+ofw_interface_clean:
+	-@$(rm) $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_OBJECTS) 2>$(NUL)
+clean: ofw_interface_clean

Modified: trunk/reactos/tools/tools.mak
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/tools.mak?rev=28757&r1=28756&r2=28757&view=diff
==============================================================================
--- trunk/reactos/tools/tools.mak (original)
+++ trunk/reactos/tools/tools.mak Sun Sep  2 13:02:12 2007
@@ -47,6 +47,7 @@
 include tools/cdmake/cdmake.mak
 include tools/dbgprint/dbgprint.mak
 include tools/gendib/gendib.mak
+include tools/ofw_interface/ofw_interface.mak
 include tools/mkhive/mkhive.mak
 include tools/nci/nci.mak
 include tools/pefixup.mak




More information about the Ros-diffs mailing list