[ros-diffs] [arty] 22654: Add ofw interface generator. It's a bit like mig is for mach. Just does some convenience stuff, since we're an unusual OS, and we have special needs wrt OF.

arty at svn.reactos.org arty at svn.reactos.org
Tue Jun 27 09:32:57 CEST 2006


Author: arty
Date: Tue Jun 27 11:32:56 2006
New Revision: 22654

URL: http://svn.reactos.org/svn/reactos?rev=22654&view=rev
Log:
Add ofw interface generator.  It's a bit like mig is for mach.  Just 
does some convenience stuff, since we're an unusual OS, and we have 
special needs wrt OF.

Added:
    branches/powerpc/reactos/tools/ofw_interface/
    branches/powerpc/reactos/tools/ofw_interface/calls.ofw
    branches/powerpc/reactos/tools/ofw_interface/ofw_interface.cpp
    branches/powerpc/reactos/tools/ofw_interface/ofw_interface.mak
Modified:
    branches/powerpc/reactos/Makefile

Modified: branches/powerpc/reactos/Makefile
URL: http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/Makefile?rev=22654&r1=22653&r2=22654&view=diff
==============================================================================
--- branches/powerpc/reactos/Makefile (original)
+++ branches/powerpc/reactos/Makefile Tue Jun 27 11:32:56 2006
@@ -370,7 +370,10 @@
 	$(ERRCODES_H) \
 	$(ERRCODES_RC) \
 	$(NCI_SERVICE_FILES) \
-	$(GENDIB_DIB_FILES)
+	$(GENDIB_DIB_FILES) \
+	$(OFW_INTERFACE_OUTPUT) \
+	$(OFW_INTERFACE_SOURCE) \
+	$(OFW_INTERFACE_HEADER)
 
 $(ROS_AUTOMAKE): $(RBUILD_TARGET) $(PREAUTO) $(XMLBUILDFILES)
 	$(ECHO_RBUILD)

Added: branches/powerpc/reactos/tools/ofw_interface/calls.ofw
URL: http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ofw_interface/calls.ofw?rev=22654&view=auto
==============================================================================
--- branches/powerpc/reactos/tools/ofw_interface/calls.ofw (added)
+++ branches/powerpc/reactos/tools/ofw_interface/calls.ofw Tue Jun 27 11:32:56 2006
@@ -1,0 +1,15 @@
+# Function		Args	Returns	Types
+# Real OFW functions to proxy
+finddevice		1	1	char* int
+open			1	1	int int
+getprop			4	1	int char* int*: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
+seek			3	1	int int int int
+# Convenience functions that interact closely with OFW (written in BE asm)
+-dumpregs		0	0
+-print_string		1	0	char*
+-print_number		1	0	int

Added: branches/powerpc/reactos/tools/ofw_interface/ofw_interface.cpp
URL: http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ofw_interface/ofw_interface.cpp?rev=22654&view=auto
==============================================================================
--- branches/powerpc/reactos/tools/ofw_interface/ofw_interface.cpp (added)
+++ branches/powerpc/reactos/tools/ofw_interface/ofw_interface.cpp Tue Jun 27 11:32:56 2006
@@ -1,0 +1,270 @@
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+class ofw_wrappers {
+public:
+    int base, ctindex;
+    std::string functions;
+    std::string names;
+    std::string calltable;
+    std::string le_stubs;
+    std::string of_call;
+};
+
+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);
+}
+
+std::string c_type( const std::string &intype ) {
+    size_t colon = intype.find(':');
+    if( colon != std::string::npos ) return intype.substr(0,colon);
+    else if( intype.size() ) return intype;
+    else return "void";
+}
+
+std::string have_len( const std::string &intype ) {
+    size_t colon = intype.find(':');
+    if( colon != std::string::npos ) return intype.substr(colon+1);
+    else return "";
+}
+
+bool need_swap( const std::string &intype ) {
+    return intype.find('*') != std::string::npos;
+}
+
+void populate_definition( ofw_wrappers &wrapper, const std::string &line ) {
+    std::istringstream iss(line);
+    bool make_function = true;
+    std::string name, argtype, rettype, c_rettype;
+    std::vector<std::string> argtypes;
+    int args, rets, i, local_offset, total_stack;
+    std::ostringstream function, ct_csource, le_stub, of_call;
+
+    iss >> name >> args >> rets;
+
+    if( !name.size() ) return;
+    if( name[0] == '-' ) {
+	name = name.substr(1);
+	make_function = false;
+    }
+
+    for( i = 0; i < args; i++ ) {
+        iss >> argtype;
+	argtypes.push_back(argtype);
+    }
+
+    iss >> rettype;
+
+    local_offset = (3 + rets + args) * 4;
+    total_stack = round_up(12 + local_offset, 16);
+
+    function << "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," << wrapper.base << "@ha\n"
+	     << "\taddi %r9,%r8," << name << "_ofw_name - _start\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"
+	     << "\tlwz %r9,ofw_call_addr - _start(%r8)\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";
+
+    c_rettype = c_type(rettype);
+
+    le_stub << c_rettype << " ofw_" << name << "(";
+    for( i = 0; i < args; i++ ) {
+	if( i ) le_stub << ",";
+	le_stub << c_type(argtypes[i]) << " arg" << i;
+    }
+    le_stub << ")";
+    of_call << le_stub.str() << ";\n";
+
+    le_stub << " {\n";
+    if( c_rettype != "void" ) 
+	le_stub << "\t" << c_rettype << " ret;\n";
+
+    for( i = 0; i < args; i++ ) {
+	if( need_swap(argtypes[i]) ) {
+	    std::string len;
+	    if( have_len(argtypes[i]).size() ) 
+		len = have_len(argtypes[i]);
+	    else {
+		std::ostringstream oss;
+		oss << "strlen(arg" << i << ")";
+		len = oss.str();
+	    }
+	    le_stub << "\tle_swap("
+		    << "arg" << i << "," 
+		    << "arg" << i << "+" << len << ","
+		    << "arg" << i << ");\n";
+	}
+    }
+
+    le_stub << "\t";
+    if( c_rettype != "void" ) le_stub << "ret = (" << c_rettype << ")";
+
+    le_stub << "ofproxy(" << (wrapper.ctindex * 4);
+    
+    for( i = 0; i < 4; i++ ) {
+	if( i < args ) le_stub << ",(void *)arg" << i;
+	else le_stub << ",NULL";
+    }
+
+    le_stub << ");\n";
+
+    for( i = args-1; i >= 0; i-- ) {
+	if( need_swap(argtypes[i]) ) {
+	    std::string len;
+	    if( have_len(argtypes[i]).size() ) 
+		len = have_len(argtypes[i]);
+	    else {
+		std::ostringstream oss;
+		oss << "strlen(arg" << i << ")";
+		len = oss.str();
+	    }
+	    le_stub << "\tle_swap("
+		    << "arg" << i << "," 
+		    << "arg" << i << "+" << len << ","
+		    << "arg" << i << ");\n";
+	}
+    }
+
+    if( c_rettype != "void" ) 
+	le_stub << "\treturn ret;\n";
+
+    le_stub << "}\n";
+
+    if( make_function ) wrapper.functions += function.str();
+    wrapper.le_stubs += le_stub.str();
+    wrapper.of_call += of_call.str();
+    wrapper.names += name + "_ofw_name:\n\t.asciz \"" + name + "\"\n";
+    wrapper.calltable += std::string("\t.long 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.globl _start\n"
+	<< "\t.globl ofw_call_addr\n"
+	<< "ofw_call_addr:\n"
+	<< "\t.long 0\n"
+	<< "\n/* Function Wrappers */\n\n"
+	<< wrappers.functions
+	<< "\t/* Function Names */\n\n"
+	<< wrappers.names
+	<< "\n/* Function Call Table for Freeldr */\n\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: branches/powerpc/reactos/tools/ofw_interface/ofw_interface.mak
URL: http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/tools/ofw_interface/ofw_interface.mak?rev=22654&view=auto
==============================================================================
--- branches/powerpc/reactos/tools/ofw_interface/ofw_interface.mak (added)
+++ branches/powerpc/reactos/tools/ofw_interface/ofw_interface.mak Tue Jun 27 11:32:56 2006
@@ -1,0 +1,58 @@
+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/bootsect/ofw.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_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_OUTPUT): ofw_interface
+	$(OFW_INTERFACE_TARGET) \
+		$(OFW_INTERFACE_INPUT) \
+		$(OFW_INTERFACE_OUTPUT) \
+		$(OFW_INTERFACE_SOURCE) \
+		$(OFW_INTERFACE_HEADER)
+	
+.PHONY: ofw_interface
+ofw_interface: $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_INPUT)
+
+.PHONY: ofw_interface_clean
+ofw_interface_clean:
+	-@$(rm) $(OFW_INTERFACE_TARGET) $(OFW_INTERFACE_OBJECTS) 2>$(NUL)
+clean: ofw_interface_clean




More information about the Ros-diffs mailing list