# HG changeset patch # User jlarmour # Date 956094715 0 # Node ID 6736c52df5079709746ed60ee91e40ae77bdc59c # Parent 89fef2181d7d328d976001d3ed2bf9cbd590f192 Merge from eCos master repository on 2000-04-14-13:35:46-BST diff --git a/host/libcdl/ChangeLog b/host/libcdl/ChangeLog --- a/host/libcdl/ChangeLog +++ b/host/libcdl/ChangeLog @@ -1,3 +1,36 @@ +2000-04-11 Bart Veer + + * infer.cxx (infer_make_active): + Fix infinite recursion. Naughty inference engine. + + * interp.cxx (eval): + Diagnostics enhancement tweak. + + * build.cxx (generate_config_header): + Add a context when generating header files. + + * base.cxx (CdlLoadableBody): + Add a context to the CdlInterpreter on creation, for better + diagnostics. + Do not raise errors in the internal Tcl scripts, since those + may now get reported. + + * database.cxx (new_package): + A single spurious subdirectory in a package should not invalidate + the entire package. + +2000-04-10 Bart Veer + + * base.cxx, build.cxx, cdl.hxx, cdlcore.hxx, cdlmisc.cxx, + component.cxx, config.cxx, database.cxx, dialog.cxx, expr.cxx, + interface.cxx, interp.cxx, option.cxx, package.cxx, parse.cxx, + property.cxx, value.cxx, wizard.cxx + Improved diagnostics support. + + * build.cxx, property.cxx, parse.cxx: + Allow for string vector properties with no elements. Use this + for the include_files property. + 2000-03-13 John Dallaway * cdl.dsp: diff --git a/host/libcdl/TODO b/host/libcdl/TODO --- a/host/libcdl/TODO +++ b/host/libcdl/TODO @@ -89,6 +89,12 @@ 17) what happens when several packages s 18) evalexception conflicts. What should happen if the node is disabled or inactive? Especially if it is the default_value expression that is causing the problem. +19) add diagnostic callback support to the inference engine so that I + can figure out what is going on. + +20) make version comparison completely case insensitive, to avoid + problems on some file systems. + Intermediate ------------ @@ -106,14 +112,7 @@ 3) full definition of custom build steps 4) get safe interpreters working, and make sure that only safe file I/O operations are permitted. -5) diagnostic messages. These need to follow a suitable convention and - made generally more comprehensible. - - Huge> Oh yeah, if the cdl file quoted to a script in a package in ecos.db is - Huge> mis-named, there error message is something about "no package - Huge> versions found" - a simple "file not found: - Huge> /masala/hmt/work/ecc/net/ecc/ecc/net/drivers/eth/ebsa285/*/cdl/ebsa285_eth_drivers.cdl" - Huge> would be far more informative. +5) Improve diagnostic messages, including line numbers. 6) extend the inference engine to support more operators. @@ -147,6 +146,9 @@ 12) header file dependencies. From Jespe smoooking fast dependency system. It doesn't get finer-grained than this. +13) friend packages, allowing one package to see the implementation + details of another. Also, handle documentation links between these. + Major ----- diff --git a/host/libcdl/base.cxx b/host/libcdl/base.cxx --- a/host/libcdl/base.cxx +++ b/host/libcdl/base.cxx @@ -1014,6 +1014,7 @@ CdlLoadableBody::CdlLoadableBody(CdlTopl CdlInterpreter master = toplevel->get_interpreter(); CYG_ASSERTC(0 != master); interp = master->create_slave(this, false); + interp->push_context(this->get_name()); CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_POSTCONDITION_THISC(); @@ -1247,7 +1248,7 @@ CdlLoadableBody::bind(CdlTransaction tra } } - // Nodes start of inactive. Check each one whether or not it + // Nodes start off inactive. Check each one whether or not it // should be active. // NOTE: possibly this should be done via a per-node init // update instead. @@ -1471,7 +1472,7 @@ set filename [file join $::cdl_topdir $: if {[file exists $filename]} { \n\ return \"[set filename][set cdl_anchor]\" \n\ } \n\ -return -error \"\" \n\ +return \"\" \n\ "; std::string @@ -1519,7 +1520,7 @@ set filename $::cdl_target if {[file exists [file join $::cdl_topdir $::cdl_pkgdir $filename]]} { \n\ return \"[set filename][set cdl_anchor]\" \n\ } \n\ -return -error \"\" \n\ +return \"\" \n\ "; std::string @@ -1558,9 +1559,9 @@ CdlLoadableBody::find_relative_file(std: static char has_subdirectory_script[] = " \n\ set dirname [file join $::cdl_topdir $::cdl_pkgdir $::cdl_target] \n\ if {[file isdirectory $dirname] == 0} { \n\ - return -error \"\" \n\ + return 0 \n\ } \n\ -return 0 \n\ +return 1 \n\ "; bool @@ -1579,7 +1580,7 @@ CdlLoadableBody::has_subdirectory(std::s std::string tcl_result; int tmp = interp->eval(has_subdirectory_script, tcl_result); - if (TCL_OK == tmp) { + if ((TCL_OK == tmp) && ("1" == tcl_result)) { result = true; } @@ -2756,12 +2757,13 @@ CdlToplevelBody::savefile_handle_command CYG_ASSERTC(toplevel->savefile_commands_initialized); if (1 == argc) { - CdlParse::report_error(interp, "expecting at least one argument to cdl_savefile_command"); + CdlParse::report_error(interp, "", "Expecting at least one argument to cdl_savefile_command"); } else if (2 == argc) { - CdlParse::report_warning(interp, std::string("missing third argument to `cdl_savefile_command ") + argv[1] + + CdlParse::report_warning(interp, "", + std::string("Missing third argument to `cdl_savefile_command ") + argv[1] + "'\n.Expecting an additional list of subcommands."); } else if (3 != argc) { - CdlParse::report_warning(interp, std::string("unexpected additional arguments to `cdl_savefile_command ") + + CdlParse::report_warning(interp, "", std::string("Unexpected additional arguments to `cdl_savefile_command ") + argv[1] + " { " + argv[2] + " }"); } @@ -2802,7 +2804,7 @@ CdlToplevelBody::savefile_handle_command try { Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); if (TCL_OK != Tcl_SplitList(tcl_interp, argv[2], &list_count, &list_entries)) { - CdlParse::report_error(interp, std::string("invalid subcommand list for `cdl_command ") + argv[1] + "'."); + CdlParse::report_error(interp, "", std::string("Invalid subcommand list for `cdl_command ") + argv[1] + "'."); } for (int i = 0; i < list_count; i++) { @@ -2934,8 +2936,7 @@ CdlToplevelBody::savefile_handle_unknown CYG_REPORT_FUNCARG2XV(interp, argc); CYG_PRECONDITION_CLASSC(interp); - std::string msg = std::string("Unknown command `") + argv[1] + "'."; - CdlParse::report_error(interp, msg); + CdlParse::report_error(interp, "", std::string("Unknown command `") + argv[1] + "'."); CYG_UNUSED_PARAM(int, argc); return TCL_OK; @@ -2971,16 +2972,17 @@ CdlToplevelBody::savefile_handle_version CYG_PRECONDITION_CLASSC(interp); if (1 == argc) { - CdlParse::report_warning(interp, "expecting one argument to cdl_savefile_version"); + CdlParse::report_warning(interp, "", "Expecting one argument to cdl_savefile_version"); } else { if (2 != argc) { - CdlParse::report_warning(interp, std::string("unexpected number of arguments to cdl_savefile_version\n") + + CdlParse::report_warning(interp, "", + std::string("Unexpected number of arguments to cdl_savefile_version\n") + "There should be exactly one argument, the savefile format version number."); } cdl_int tmp; if (!Cdl::string_to_integer(argv[1], tmp)) { - CdlParse::report_error(interp, std::string("invalid version number `") + argv[1] + - "' for cdl_savefile_version"); + CdlParse::report_error(interp, "", + std::string("Invalid version number `") + argv[1] + "' for cdl_savefile_version"); } else { // Store the data in a Tcl variable. This is at least as convenient // as assoc data. @@ -3002,7 +3004,7 @@ CdlToplevelBody::get_savefile_version(Cd std::string version = interp->get_variable("cdl_savefile_version"); if ("" != version) { if (!Cdl::string_to_integer(version, result)) { - CdlParse::report_error(interp, std::string("invalid cdl_savefile_version number `") + version + "'"); + CdlParse::report_error(interp, "", std::string("Invalid cdl_savefile_version number `") + version + "'"); } } @@ -3306,13 +3308,13 @@ CdlUserVisibleBody::check_properties(Cdl CYG_PRECONDITION_CLASSC(interp); if (count_properties(CdlPropertyId_Display) > 1) { - CdlParse::report_error(interp, "There should be at most one display property."); + CdlParse::report_error(interp, "", "There should be at most one display property."); } if (count_properties(CdlPropertyId_Description) > 1) { - CdlParse::report_error(interp, "There should be at most one description property."); + CdlParse::report_error(interp, "", "There should be at most one description property."); } if (count_properties(CdlPropertyId_Doc) > 1) { - CdlParse::report_error(interp, "There should be at most one doc property."); + CdlParse::report_error(interp, "", "There should be at most one doc property."); } // FIXME: more validation of the doc property, in particular check that @@ -3530,12 +3532,12 @@ CdlParentableBody::check_properties(CdlI if (has_property(CdlPropertyId_Parent)) { if (count_properties(CdlPropertyId_Parent) > 1) { - CdlParse::report_error(interp, "There should be at most one `parent' property."); + CdlParse::report_error(interp, "", "There should be at most one `parent' property."); } CdlProperty_Reference refprop = dynamic_cast(get_property(CdlPropertyId_Parent)); CYG_ASSERT_CLASSC(this); if (get_name() == refprop->get_destination_name()) { - CdlParse::report_error(interp, std::string("Node ") + get_name() + " cannot be its own parent."); + CdlParse::report_error(interp, "", std::string("Node ") + get_name() + " cannot be its own parent."); } } diff --git a/host/libcdl/build.cxx b/host/libcdl/build.cxx --- a/host/libcdl/build.cxx +++ b/host/libcdl/build.cxx @@ -219,7 +219,7 @@ CdlBuildableBody::parse_compile(CdlInter 0 }; - int result = CdlParse::parse_stringvector_property(interp, argc, argv, CdlPropertyId_Compile, options, 0); + int result = CdlParse::parse_stringvector_property(interp, argc, argv, CdlPropertyId_Compile, options, 0, true); CYG_REPORT_RETVAL(result); return result; @@ -473,7 +473,7 @@ CdlBuildableBody::parse_object(CdlInterp 0 }; - int result = CdlParse::parse_stringvector_property(interp, argc, argv, CdlPropertyId_Object, options, 0); + int result = CdlParse::parse_stringvector_property(interp, argc, argv, CdlPropertyId_Object, options, 0, true); CYG_REPORT_RETVAL(result); return result; @@ -873,7 +873,7 @@ CdlBuildLoadableBody::parse_include_file { CYG_REPORT_FUNCNAMETYPE("parse_include_files", "result %d"); - int result = CdlParse::parse_stringvector_property(interp, argc, argv, CdlPropertyId_IncludeFiles, 0, 0); + int result = CdlParse::parse_stringvector_property(interp, argc, argv, CdlPropertyId_IncludeFiles, 0, 0, true); CYG_REPORT_RETVAL(result); return result; @@ -1217,13 +1217,13 @@ CdlDefinableBody::check_properties(CdlIn // There should be at most one each of no_define and define_format. if (count_properties(CdlPropertyId_NoDefine) > 1) { - CdlParse::report_error(interp, "There should be at most one no_define property."); + CdlParse::report_error(interp, "", "There should be at most one no_define property."); } if (count_properties(CdlPropertyId_DefineFormat) > 1) { - CdlParse::report_error(interp, "There should be at most one define_format property."); + CdlParse::report_error(interp, "", "There should be at most one define_format property."); } if (has_property(CdlPropertyId_NoDefine) && has_property(CdlPropertyId_DefineFormat)) { - CdlParse::report_error(interp, "The no_define and define_format properties are mutually exclusive."); + CdlParse::report_error(interp, "", "The no_define and define_format properties are mutually exclusive."); } // FIXME: the define_format property only makes sense for certain // flavors. However the flavor property may not have been processed yet. @@ -1371,7 +1371,7 @@ CdlDefinableBody::parse_if_define(CdlInt 0 }; int result = CdlParse::parse_stringvector_property(interp, argc, argv, CdlPropertyId_IfDefine, options, - &parse_if_define_final_check); + &parse_if_define_final_check, false); CYG_REPORT_RETVAL(result); return result; @@ -1651,7 +1651,7 @@ CdlDefineLoadableBody::check_properties( // There should be at most one define_header property int count = count_properties(CdlPropertyId_DefineHeader); if (count> 1) { - CdlParse::report_error(interp, "There should be at most one define_header property."); + CdlParse::report_error(interp, "", "There should be at most one define_header property."); } // FIXME: filename validation @@ -1689,6 +1689,8 @@ CdlDefineLoadableBody::generate_config_h Tcl_RegisterChannel(interp->get_tcl_interpreter(), this_hdr); Tcl_RegisterChannel(interp->get_tcl_interpreter(), system_h); + CdlInterpreterBody::ContextSupport(interp, std::string("Package ") + this->get_name() + ", header file generation"); + try { interp->set_variable("::cdl_header", Tcl_GetChannelName(this_hdr)); interp->set_variable("::cdl_system_header", Tcl_GetChannelName(system_h)); diff --git a/host/libcdl/cdl.hxx b/host/libcdl/cdl.hxx --- a/host/libcdl/cdl.hxx +++ b/host/libcdl/cdl.hxx @@ -116,7 +116,9 @@ class CdlPackagesDatabaseBody { public: - static CdlPackagesDatabase make(std::string = "") throw(CdlInputOutputException,std::bad_alloc); + static CdlPackagesDatabase make(std::string = "", CdlDiagnosticFnPtr /* error */ = 0, + CdlDiagnosticFnPtr /* warn */ = 0) + throw(CdlInputOutputException,std::bad_alloc); bool update(void) throw(CdlInputOutputException,std::bad_alloc); ~CdlPackagesDatabaseBody(); @@ -136,8 +138,6 @@ class CdlPackagesDatabaseBody { const std::string& get_target_description(std::string) const; const std::vector& get_target_aliases(std::string) const; const std::vector& get_target_packages(std::string) const; - const std::string& get_target_command_prefix(std::string) const; - const std::vector >& get_target_compiler_flags(std::string) const; const std::vector& get_target_enables(std::string) const; const std::vector& get_target_disables(std::string) const; const std::vector >& get_target_set_values(std::string) const; @@ -163,7 +163,8 @@ class CdlPackagesDatabaseBody { // The only valid constructor gets invoked from the make() member function. // The argument should be a pathname for the component repository. The // constructor is responsible for reading in the whole packages file. - CdlPackagesDatabaseBody(std::string) throw(CdlInputOutputException,std::bad_alloc); + CdlPackagesDatabaseBody(std::string, CdlDiagnosticFnPtr, CdlDiagnosticFnPtr) + throw(CdlInputOutputException,std::bad_alloc); std::string component_repository; std::vector package_names; @@ -184,8 +185,6 @@ class CdlPackagesDatabaseBody { std::string description; std::vector aliases; std::vector packages; - std::string command_prefix; - std::vector > cflags; std::vector enable; std::vector disable; std::vector > set_values; diff --git a/host/libcdl/cdlcore.hxx b/host/libcdl/cdlcore.hxx --- a/host/libcdl/cdlcore.hxx +++ b/host/libcdl/cdlcore.hxx @@ -1101,21 +1101,27 @@ class CdlInterpreterBody ClientData get_assoc_data(const char*); // Evaluate a string as Tcl code. The return value comes from Tcl, e.g. - // TCL_OK or TCL_ERROR. The result string is also available. + // TCL_OK or TCL_ERROR. There are variants depending on whether or not + // the result string is of interest. + int eval(std::string); int eval(std::string, std::string&); // Ditto for any Tcl code that comes from CDL files + int eval_cdl_code(const cdl_tcl_code); int eval_cdl_code(const cdl_tcl_code, std::string&); // And support for evaluating an entire file + int eval_file(std::string); int eval_file(std::string, std::string&); // For use by commands implemented in C++, a way of setting the result void set_result(std::string); - // And a utility to get the result as well. This is useful for e.g. - // Tcl_OpenFileChannel which leaves a result string in the interpreter + // And a utility to get the result as well. std::string get_result(); + + // Was the result set by the Tcl interpreter or by libcdl? + bool result_set_by_cdl(); // A utility to quote data that is going to end up in a TCL script. static std::string quote(std::string); @@ -1163,7 +1169,7 @@ class CdlInterpreterBody CdlLoadable get_loadable() const; CdlContainer get_container() const; CdlNode get_node() const; - std::string get_filename() const; + std::string get_context() const; CdlDiagnosticFnPtr get_error_fn_ptr() const; CdlDiagnosticFnPtr get_warning_fn_ptr() const; CdlTransaction get_transaction() const; @@ -1173,13 +1179,134 @@ class CdlInterpreterBody void pop_container(CdlContainer); CdlNode push_node(CdlNode); void pop_node(CdlNode); - std::string push_filename(std::string); - void pop_filename(std::string); + std::string push_context(std::string); + void pop_context(std::string); CdlDiagnosticFnPtr push_error_fn_ptr(CdlDiagnosticFnPtr); void pop_error_fn_ptr(CdlDiagnosticFnPtr); CdlDiagnosticFnPtr push_warning_fn_ptr(CdlDiagnosticFnPtr); void pop_warning_fn_ptr(CdlDiagnosticFnPtr); + // Provide utility classes for common push/pop combinations. The + // push happens during the constructor, the pop during the + // destructor. This can simplify some code, especially when + // exceptions may get thrown. + class DiagSupport { + public: + DiagSupport(CdlInterpreter interp_arg, CdlDiagnosticFnPtr error_fn_arg, CdlDiagnosticFnPtr warn_fn_arg) { + interp = interp_arg; + saved_error_fn = interp->push_error_fn_ptr(error_fn_arg); + saved_warn_fn = interp->push_warning_fn_ptr(warn_fn_arg); + } + ~DiagSupport() { + interp->pop_error_fn_ptr(saved_error_fn); + interp->pop_warning_fn_ptr(saved_warn_fn); + } + private: + DiagSupport(); + + CdlInterpreter interp; + CdlDiagnosticFnPtr saved_error_fn; + CdlDiagnosticFnPtr saved_warn_fn; + }; + class ContextSupport { + public: + ContextSupport(CdlInterpreter interp_arg, std::string context) { + interp = interp_arg; + saved_context = interp->push_context(context); + } + ~ContextSupport() { + interp->pop_context(saved_context); + } + private: + ContextSupport(); + CdlInterpreter interp; + std::string saved_context; + }; + class ContainerSupport { + public: + ContainerSupport(CdlInterpreter interp_arg, CdlContainer container) { + interp = interp_arg; + saved_container = interp->push_container(container); + } + ~ContainerSupport() { + interp->pop_container(saved_container); + } + private: + ContainerSupport(); + CdlInterpreter interp; + CdlContainer saved_container; + }; + class NodeSupport { + public: + NodeSupport(CdlInterpreter interp_arg, CdlNode node) { + interp = interp_arg; + saved_node = interp->push_node(node); + } + ~NodeSupport() { + interp->pop_node(saved_node); + } + private: + NodeSupport(); + CdlInterpreter interp; + CdlNode saved_node; + }; + class CommandSupport { + public: + CommandSupport(CdlInterpreter interp_arg, std::vector& commands) { + interp = interp_arg; + saved_commands = interp->push_commands(commands); + } + CommandSupport(CdlInterpreter interp_arg, CdlInterpreterCommandEntry* commands) { + unsigned int i; + for (i = 0; 0 != commands[i].command; i++) { + new_commands.push_back(commands[i]); + } + interp = interp_arg; + saved_commands = interp->push_commands(new_commands); + } + ~CommandSupport() { + interp->pop_commands(saved_commands); + } + + private: + CommandSupport(); + CdlInterpreter interp; + std::vector* saved_commands; + std::vector new_commands; + }; + + // Similar utility classes for variables and assoc data. + class VariableSupport { + public: + VariableSupport(CdlInterpreter interp_arg, std::string varname_arg, std::string data) { + interp = interp_arg; + varname = varname_arg; + interp->set_variable(varname, data); + } + ~VariableSupport() { + interp->unset_variable(varname); + } + private: + VariableSupport(); + CdlInterpreter interp; + std::string varname; + }; + class AssocSupport { + public: + AssocSupport(CdlInterpreter interp_arg, const char* name_arg, ClientData data, Tcl_InterpDeleteProc* del_proc = 0) { + interp = interp_arg; + name = name_arg; + interp->set_assoc_data(name, data, del_proc); + } + ~AssocSupport() { + interp->delete_assoc_data(name); + } + private: + AssocSupport(); + CdlInterpreter interp; + const char* name; + }; + // Some command implementations may want to access other Tcl library // routines such as Tcl_SplitList(). This requires convenient access // to the underlying Tcl interpreter. @@ -1216,9 +1343,10 @@ class CdlInterpreterBody CdlLoadable loadable; CdlContainer container; CdlNode node; - std::string filename; + std::string context; CdlDiagnosticFnPtr error_fn_ptr; CdlDiagnosticFnPtr warning_fn_ptr; + bool cdl_result; std::vector* current_commands; // for push() and pop() @@ -3100,14 +3228,17 @@ class CdlParse { public: // Utility routines. - static const char* get_tcl_cmd_name(const char*); + static std::string get_tcl_cmd_name(std::string); static std::string concatenate_argv(int, char**, int); static int parse_options(CdlInterpreter, std::string /* diag_prefix */, char** /* options */, int /* argc */, char** /* argv */, int /* start_index */, std::vector >& /* result */); - static std::string get_diagnostic_prefix(CdlInterpreter); - static void report_error(CdlInterpreter, std::string); - static void report_warning(CdlInterpreter, std::string); + static std::string construct_diagnostic(CdlInterpreter, std::string /* classification */, + std::string /* sub-identifier */, std::string /* message */); + + static void report_error(CdlInterpreter, std::string /* sub-identifier */, std::string /* message */) + throw(CdlParseException, std::bad_alloc); + static void report_warning(CdlInterpreter, std::string /* sub-identifier */, std::string /* message */); static void clear_error_count(CdlInterpreter); static int get_error_count(CdlInterpreter); static void incr_error_count(CdlInterpreter, int=1); @@ -3116,10 +3247,12 @@ class CdlParse { static int unknown_command(CdlInterpreter, int, char**); // Property-related utilities - static std::string get_property_prefix(char*); - static std::string get_property_prefix(CdlProperty); - static void report_property_parse_error(CdlInterpreter, char*, std::string); - static void report_property_parse_error(CdlInterpreter, CdlProperty, std::string); + static void report_property_parse_error(CdlInterpreter, std::string, std::string) + throw(CdlParseException, std::bad_alloc); + static void report_property_parse_error(CdlInterpreter, CdlProperty, std::string) + throw(CdlParseException, std::bad_alloc); + static void report_property_parse_warning(CdlInterpreter, std::string, std::string); + static void report_property_parse_warning(CdlInterpreter, CdlProperty, std::string); // Utility parsing routines static int parse_minimal_property(CdlInterpreter, int, char**, std::string, @@ -3129,7 +3262,8 @@ class CdlParse { static int parse_tclcode_property(CdlInterpreter, int, char**, std::string, char**, void (*)(CdlInterpreter, CdlProperty_TclCode)); static int parse_stringvector_property(CdlInterpreter, int, char**, std::string, - char**, void (*)(CdlInterpreter, CdlProperty_StringVector)); + char**, void (*)(CdlInterpreter, CdlProperty_StringVector), + bool /* allow_empty */ = false); static int parse_reference_property(CdlInterpreter, int, char**, std::string, char**, void (*)(CdlInterpreter, CdlProperty_Reference), CdlUpdateHandler); diff --git a/host/libcdl/cdlmisc.cxx b/host/libcdl/cdlmisc.cxx --- a/host/libcdl/cdlmisc.cxx +++ b/host/libcdl/cdlmisc.cxx @@ -200,6 +200,9 @@ Cdl::string_to_integer(std::string data, CYG_REPORT_FUNCNAMETYPE("Cdl::string_to_integer", "success %d"); bool negative = false; + bool seen_plus = false; + bool seen_minus = false; + // Life is a bit easier if I can check for '\0' const char* ptr = data.c_str(); @@ -207,7 +210,23 @@ Cdl::string_to_integer(std::string data, while (isspace(*ptr)) ptr++; + if ('+' == *ptr) { + if (seen_plus) { + target = 0; + CYG_REPORT_RETVAL(false); + return false; + } + seen_plus = true; + ptr++; + } + if ('-' == *ptr) { + if (seen_minus) { + target = 0; + CYG_REPORT_RETVAL(false); + return false; + } + seen_minus = true; negative = true; ptr++; } diff --git a/host/libcdl/component.cxx b/host/libcdl/component.cxx --- a/host/libcdl/component.cxx +++ b/host/libcdl/component.cxx @@ -119,18 +119,16 @@ CdlComponentBody::parse_component(CdlInt CYG_REPORT_FUNCARG1("argc %d", argc); CYG_PRECONDITION_CLASSC(interp); - const char* diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); + std::string diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); CdlLoadable loadable = interp->get_loadable(); CdlPackage package = dynamic_cast(loadable); CdlContainer parent = interp->get_container(); CdlToplevel toplevel = interp->get_toplevel(); - std::string filename = interp->get_filename(); CYG_ASSERT_CLASSC(loadable); // There should always be a loadable during parsing CYG_ASSERT_CLASSC(package); // And packages are the only loadable for software CDL. CYG_ASSERT_CLASSC(parent); CYG_ASSERT_CLASSC(toplevel); - CYG_ASSERTC("" != filename); // The new component should be created and added to the package // early on. If there is a parsing error it will get cleaned up @@ -145,20 +143,23 @@ CdlComponentBody::parse_component(CdlInt // Currently there are no options. This may change in future. if (3 != argc) { - CdlParse::report_error(interp, std::string("Incorrect number of arguments to ") + diag_argv0 + - "\n Expecting name and properties list."); + CdlParse::report_error(interp, "", + std::string("Incorrect number of arguments to `") + diag_argv0 + + "'\nExpecting name and properties list."); ok = false; goto done; } if (!Tcl_CommandComplete(argv[2])) { - CdlParse::report_error(interp, std::string("Invalid property list for cdl_component ") + argv[1]); + CdlParse::report_error(interp, "", + std::string("Invalid property list for cdl_component `") + argv[1] + "'."); ok = false; goto done; } if (0 != toplevel->lookup(argv[1])) { - CdlParse::report_error(interp, std::string("Component ") + argv[1] + " cannot be loaded.\n" + - " The name is already in use."); + CdlParse::report_error(interp, "", + std::string("Component `") + argv[1] + + "' cannot be loaded.\nThe name is already in use."); ok = false; } else { new_component = new CdlComponentBody(argv[1]); @@ -173,13 +174,13 @@ CdlComponentBody::parse_component(CdlInt return TCL_OK; } } catch(std::bad_alloc e) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory")); result = TCL_ERROR; } catch(CdlParseException e) { interp->set_result(e.get_message()); result = TCL_ERROR; } catch(...) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); result = TCL_ERROR; } if (TCL_OK != result) { @@ -194,7 +195,7 @@ CdlComponentBody::parse_component(CdlInt // diagnostics. Also make it the new container. CdlNode old_node = interp->push_node(new_component); CdlContainer old_container = interp->push_container(new_component); - std::string old_filename; + std::string old_context; CYG_ASSERTC(parent == old_container); // Declare these outside the scope of the try statement, to allow @@ -262,10 +263,10 @@ CdlComponentBody::parse_component(CdlInt // There should be at most one each of wizard and script. if (new_component->count_properties(CdlPropertyId_Wizard) > 1) { - CdlParse::report_error(interp, "A component should have at most one `wizard' property."); + CdlParse::report_error(interp, "", "A component should have at most one `wizard' property."); } if (new_component->count_properties(CdlPropertyId_Script) > 1) { - CdlParse::report_error(interp, "A component should have at most one `script' property."); + CdlParse::report_error(interp, "", "A component should have at most one `script' property."); } // If there is a script property, life gets more interesting. @@ -277,13 +278,13 @@ CdlComponentBody::parse_component(CdlInt // Try to locate this script. std::string script_filename = package->find_absolute_file(script_name, "cdl", false); if ("" == script_filename) { - CdlParse::report_error(interp, "Unable to find script " + script_name); + CdlParse::report_error(interp, "", "Unable to find script `" + script_name + "'."); } else { // The script exists, so we need to try and execute it. // The current container is still set correctly, but we need // to change the filename and install a different set // of commands. - old_filename = interp->push_filename(script_filename); + old_context = interp->push_context(script_filename); new_commands.clear(); for (i = 0; 0 != script_commands[i].command; i++) { new_commands.push_back(script_commands[i]); @@ -291,25 +292,25 @@ CdlComponentBody::parse_component(CdlInt old_commands = interp->push_commands(new_commands); result = interp->eval_file(script_filename, tcl_result); interp->pop_commands(old_commands); - interp->pop_filename(old_filename); + interp->pop_context(old_context); } } done2: // Dummy command just to keep the compiler happy - filename = ""; + old_context = ""; } catch (std::bad_alloc e) { // Errors at this stage should be reported via Tcl, not via C++. // However there is no point in continuing with the parsing operation, // just give up. - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory")); result = TCL_ERROR; } catch (CdlParseException e) { interp->set_result(e.get_message()); result = TCL_ERROR; } catch(...) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); result = TCL_ERROR; } @@ -425,13 +426,13 @@ CdlComponentBody::savefile_component_com try { if (3 != argc) { - CdlParse::report_error(interp, "Invalid cdl_component command in savefile, expecting two arguments."); + CdlParse::report_error(interp, "", "Invalid cdl_component command in savefile, expecting two arguments."); } else { CdlNode current_node = config->lookup(argv[1]); if (0 == current_node) { // FIXME: save value in limbo - CdlParse::report_error(interp, + CdlParse::report_error(interp, "", std::string("The savefile contains a cdl_component command for an unknown component `") + argv[1] + "'"); } else { diff --git a/host/libcdl/config.cxx b/host/libcdl/config.cxx --- a/host/libcdl/config.cxx +++ b/host/libcdl/config.cxx @@ -750,7 +750,7 @@ CdlConfigurationBody::load_package(CdlTr version = *(versions.begin()); } else { if (std::find(versions.begin(), versions.end(), version) == versions.end()) { - throw CdlInputOutputException("Package " + name + " does not have an installed version " + version); + throw CdlInputOutputException("Package " + name + " does not have an installed version `" + version + "'."); } } std::string directory = database->get_package_directory(name); @@ -765,13 +765,13 @@ CdlConfigurationBody::load_package(CdlTr std::string tcl_cmd = "regsub -all -- {\\\\} [file join " + directory + " " + version + "] / result; return $result"; std::string tcl_result; if (TCL_OK != interp->eval(tcl_cmd, tcl_result)) { - throw CdlInputOutputException("Cannot load package " + name + ", internal error constructing pathname"); + throw CdlInputOutputException("Cannot load package `" + name + "', internal error constructing pathname."); } directory = tcl_result; tcl_cmd = "file isdirectory [file join \"" + database->get_component_repository() + "\" " + directory + "]"; if ((TCL_OK != interp->eval(tcl_cmd, tcl_result)) || ("1" != tcl_result)) { - throw CdlInputOutputException("Cannot load package " + name + ", there is no directory " + directory); + throw CdlInputOutputException("Cannot load package `" + name + "', there is no directory `" + directory + "'."); } // Make sure that there is no name conflict. No resources have been allocated @@ -779,11 +779,11 @@ CdlConfigurationBody::load_package(CdlTr CdlNode node = lookup(name); if (0 != node) { if (0 != dynamic_cast(node)) { - throw CdlInputOutputException("Package " + name + " is already loaded"); + throw CdlInputOutputException("Package `" + name + "' is already loaded."); } else { - std::string msg = "Name clash for package " + name + ",there is a " + - node->get_class_name() + " " + name + " already loaded"; + std::string msg = "Name clash for package `" + name + "',there is a `" + + node->get_class_name() + " " + name + "' already loaded"; CdlLoadable owner_pkg = node->get_owner(); if (0 != owner_pkg) { msg += " in package " + owner_pkg->get_name(); @@ -791,7 +791,7 @@ CdlConfigurationBody::load_package(CdlTr throw CdlInputOutputException(msg); } } - + // Now create the package object itself. CdlPackage package = 0; bool bound = false; @@ -825,12 +825,7 @@ CdlConfigurationBody::load_package(CdlTr } // The script is valid. Set up the interpreter appropriately. - CdlContainer old_container = interp->push_container(package); - std::string old_filename = interp->push_filename(actual_script); - CdlDiagnosticFnPtr old_error_fn = interp->push_error_fn_ptr(error_fn); - CdlDiagnosticFnPtr old_warn_fn = interp->push_warning_fn_ptr(warn_fn); CdlParse::clear_error_count(interp); - static CdlInterpreterCommandEntry commands[] = { CdlInterpreterCommandEntry("cdl_package", &CdlPackageBody::parse_package ), @@ -841,26 +836,17 @@ CdlConfigurationBody::load_package(CdlTr CdlInterpreterCommandEntry("cdl_wizard", &CdlWizardBody::parse_wizard ), CdlInterpreterCommandEntry("", 0 ) }; - std::vector new_commands; - for (int i = 0; 0 != commands[i].command; i++) { - new_commands.push_back(commands[i]); - } - std::vector* old_commands = interp->push_commands(new_commands); + CdlInterpreterBody::CommandSupport interp_cmds(interp, commands); + CdlInterpreterBody::ContainerSupport interp_container(interp, package); + CdlInterpreterBody::ContextSupport interp_context(interp, actual_script); // The interpreter is now ready. - if (TCL_OK != interp->eval_file(actual_script, tcl_result)) { - throw CdlInputOutputException("Package " + name + ", error executing CDL script.\n" + tcl_result); - } + (void) interp->eval_file(actual_script); // Clean out the commands etc. This interpreter may get used again // in future, and it should not be possible to define new options // etc. in that invocation. interp->remove_command("unknown"); - interp->pop_commands(old_commands); - interp->pop_container(old_container); - interp->pop_filename(old_filename); - interp->pop_error_fn_ptr(old_error_fn); - interp->pop_warning_fn_ptr(old_warn_fn); // All the data has been read in without generating an // exception. However there may have been errors reported via @@ -1059,16 +1045,20 @@ CdlConfigurationBody::set_hardware(CdlTr CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(transaction); - // Minimal consistency check before + // Minimal consistency check before attempting anything complicated. if (!database->is_known_target(target_name)) { throw CdlInputOutputException("Unknown target " + target_name); } - int i; + CdlInterpreter interp = this->get_interpreter(); + CdlInterpreterBody::DiagSupport diag_support(interp, error_fn, warn_fn); + CdlInterpreterBody::ContextSupport context_support(interp, "Hardware selection"); + CdlConfiguration_CommitCancelHardwareName* rename_op = new CdlConfiguration_CommitCancelHardwareName(current_hardware); try { transaction->add_commit_cancel_op(rename_op); const std::vector& loadables = this->get_loadables(); + int i; for (i = (int) loadables.size() - 1; i >= 0; i--) { CdlPackage package = dynamic_cast(loadables[i]); if ((0 != package) && package->belongs_to_hardware()) { @@ -1082,15 +1072,23 @@ CdlConfigurationBody::set_hardware(CdlTr const std::vector& packages = database->get_target_packages(target_name); std::vector::const_iterator name_i; for (name_i = packages.begin(); name_i != packages.end(); name_i++) { - // It is possible for a hardware package to have been - // loaded separately, in which case there is no point in - // loading it again. - CYG_ASSERTC(database->is_known_package(*name_i)); - if (0 == this->lookup(*name_i)) { - this->load_package(transaction, *name_i, "", error_fn, warn_fn, limbo); - CdlPackage package = dynamic_cast(this->lookup(*name_i)); - CYG_LOOP_INVARIANT_CLASSC(package); - package->loaded_for_hardware = true; + // Target specifications may refer to packages that are not + // installed. This is useful in e.g. an anoncvs environment. + if (database->is_known_package(*name_i)) { + // It is possible for a hardware package to have been + // loaded separately, in which case there is no point in + // loading it again. + if (0 == this->lookup(*name_i)) { + this->load_package(transaction, *name_i, "", + error_fn, warn_fn, limbo); + CdlPackage package = dynamic_cast(this->lookup(*name_i)); + CYG_LOOP_INVARIANT_CLASSC(package); + package->loaded_for_hardware = true; + } + } else { + CdlParse::report_warning(interp, "", + std::string("The target specification lists a package `") + *name_i + + "' which is not present in the component repository."); } } } @@ -1122,40 +1120,77 @@ CdlConfigurationBody::set_hardware(CdlTr CdlValueFlavor flavor; for (opt_i = enables.begin(); opt_i != enables.end(); opt_i++) { - node = this->lookup(*opt_i); + valuable = 0; + node = this->lookup(*opt_i); if (0 != node) { valuable = dynamic_cast(node); if (0 != valuable) { - flavor = valuable->get_flavor(); - if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) { - valuable->enable(transaction, CdlValueSource_User); - } } } + if (0 != valuable) { + flavor = valuable->get_flavor(); + if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) { + valuable->enable(transaction, CdlValueSource_User); + } else { + CdlParse::report_warning(interp, std::string("target `") + target_name + "'", + std::string("The option `") + *opt_i + + "' is supposed to be enabled for this target.\n" + + "However the option does not have a bool or booldata flavors."); + } + } else { + CdlParse::report_warning(interp, std::string("target `") + target_name + "'", + std::string("The option `") + *opt_i + + "' is supposed to be enabled for this target.\n" + + "However this option is not in the current configuration."); + } } for (opt_i = disables.begin(); opt_i != disables.end(); opt_i++) { + valuable = 0; node = this->lookup(*opt_i); if (0 != node) { valuable = dynamic_cast(node); - if (0 != valuable) { - flavor = valuable->get_flavor(); - if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) { - valuable->disable(transaction, CdlValueSource_User); - } + } + if (0 != valuable) { + flavor = valuable->get_flavor(); + if ((CdlValueFlavor_Bool == flavor) || (CdlValueFlavor_BoolData == flavor)) { + valuable->disable(transaction, CdlValueSource_User); + } else { + CdlParse::report_warning(interp, std::string("target `") + target_name + "'", + std::string("The option `") + *opt_i + + "' is supposed to be disabled for this target.\n" + + "However the option does not have a bool or booldata flavors."); } + } else { + CdlParse::report_warning(interp, std::string("target `") + target_name + "'", + std::string("The option `") + *opt_i + + "' is supposed to be disabled for this target.\n" + + "However this option is not in the current configuration."); } } std::vector >::const_iterator value_i; for (value_i = set_values.begin(); value_i != set_values.end(); value_i++) { + valuable = 0; node = this->lookup(value_i->first); if (0 != node) { valuable = dynamic_cast(node); - if (0 != valuable) { - flavor = valuable->get_flavor(); - if ((CdlValueFlavor_BoolData == flavor) || (CdlValueFlavor_Data == flavor)) { - valuable->set_value(transaction, value_i->second, CdlValueSource_User); - } + } + if (0 != valuable) { + flavor = valuable->get_flavor(); + if ((CdlValueFlavor_BoolData == flavor) || (CdlValueFlavor_Data == flavor)) { + valuable->set_value(transaction, value_i->second, CdlValueSource_User); + } else { + CdlParse::report_warning(interp, std::string("target `") + target_name + "'", + std::string("The option `") + *opt_i + + "' is supposed to be given the value `" + value_i->second + + "' for this target.\n" + + "However the option does not have a data or booldata flavor."); } + } else { + CdlParse::report_warning(interp, std::string("target `") + target_name + "'", + std::string("The option `") + *opt_i + + "' is supposed to be given the value `" + value_i->second + + "' for this target.\n" + + "However this option is not in the current configuration."); } } } @@ -1573,31 +1608,21 @@ CdlConfigurationBody::add(CdlTransaction CYG_ASSERTC(0 == interp->get_container()); CYG_ASSERTC(0 == interp->get_node()); CYG_ASSERTC(0 == interp->get_transaction()); - + // Keep track of enough information to undo all the changes. - std::string old_filename = interp->get_filename(); - CdlDiagnosticFnPtr old_error_fn = interp->get_error_fn_ptr(); - CdlDiagnosticFnPtr old_warn_fn = interp->get_warning_fn_ptr(); - std::vector* old_commands = 0; - std::vector commands; + CdlParse::clear_error_count(interp); + CdlInterpreterBody::DiagSupport diag_support(interp, error_fn, warn_fn); + CdlInterpreterBody::ContextSupport context_support(interp, filename); try { - - // Associate the right information with the interpreter - old_filename = interp->push_filename(filename); - old_error_fn = interp->push_error_fn_ptr(error_fn); - old_warn_fn = interp->push_warning_fn_ptr(warn_fn); - CdlParse::clear_error_count(interp); - interp->set_transaction(transaction); + std::vector commands; this->get_savefile_commands(commands); - old_commands = interp->push_commands(commands); + CdlInterpreterBody::CommandSupport interp_cmds(interp, commands); - std::string tcl_result = ""; - if (TCL_OK != interp->eval_file(filename, tcl_result)) { - throw CdlInputOutputException("Invalid savefile \"" + filename + "\".\n" + tcl_result); - } + interp->eval_file(filename); + // All the data has been read in without generating an // exception. However there may have been errors reported via // the error_fn handling, and any errors at all should result @@ -1612,21 +1637,10 @@ CdlConfigurationBody::add(CdlTransaction } } catch(...) { - - if (0 != old_commands) { - interp->pop_commands(old_commands); - } - interp->pop_filename(old_filename); - interp->pop_error_fn_ptr(old_error_fn); - interp->pop_warning_fn_ptr(old_warn_fn); interp->set_transaction(0); throw; } - interp->pop_filename(old_filename); - interp->pop_error_fn_ptr(old_error_fn); - interp->pop_warning_fn_ptr(old_warn_fn); - interp->pop_commands(old_commands); interp->set_transaction(0); CYG_REPORT_RETURN(); @@ -1664,7 +1678,7 @@ CdlConfigurationBody::savefile_configura // A broken cdl_configuration command is pretty fatal, chances are // that the entire load is going to fail. if (data_index != (argc - 2)) { - CdlParse::report_error(interp, "Invalid cdl_configuration command in savefile, expecting two arguments."); + CdlParse::report_error(interp, "", "Invalid cdl_configuration command in savefile, expecting two arguments."); } else { config->set_name(argv[1]); config->get_savefile_subcommands("cdl_configuration", subcommands); @@ -1704,7 +1718,7 @@ CdlConfigurationBody::savefile_descripti int data_index = CdlParse::parse_options(interp, "cdl_configuration/description command", 0, argc, argv, 1, options); if (data_index != (argc - 1)) { - CdlParse::report_warning(interp, + CdlParse::report_warning(interp, "", "Ignoring invalid configuration description command, expecting a single argument."); } else { config->description = argv[1]; @@ -1728,7 +1742,7 @@ CdlConfigurationBody::savefile_hardware_ int data_index = CdlParse::parse_options(interp, "cdl_configuration/hardware command", 0, argc, argv, 1, options); if (data_index != (argc - 1)) { - CdlParse::report_warning(interp, "Ignoring invalid configuration hardware command, expecting a single argument."); + CdlParse::report_warning(interp, "", "Ignoring invalid configuration hardware command, expecting a single argument."); } else { config->current_hardware = argv[1]; } @@ -1752,7 +1766,7 @@ CdlConfigurationBody::savefile_template_ int data_index = CdlParse::parse_options(interp, "cdl_configuration/template command", 0, argc, argv, 1, options); if (data_index != (argc - 1)) { - CdlParse::report_warning(interp, "Ignoring invalid configuration template command, expecting a single argument."); + CdlParse::report_warning(interp, "", "Ignoring invalid configuration template command, expecting a single argument."); } else { config->current_template = argv[1]; } @@ -1787,7 +1801,8 @@ CdlConfigurationBody::savefile_package_c int data_index = CdlParse::parse_options(interp, "cdl_configuration/package command", optlist, argc, argv, 1, options); if (data_index == (argc - 1)) { - CdlParse::report_warning(interp, std::string("Missing version information for package ") + argv[argc - 1]); + CdlParse::report_warning(interp, "", std::string("Missing version information for package `") + + argv[argc - 1] + "'."); pkgname = argv[argc - 1]; pkgversion = ""; } else if (data_index == (argc - 2)) { @@ -1796,7 +1811,7 @@ CdlConfigurationBody::savefile_package_c } else { // If we cannot load all the packages then much of the // savefile is likely to be problematical. - CdlParse::report_error(interp, "Invalid cdl_configuration/package command, expecting name and version"); + CdlParse::report_error(interp, "", "Invalid cdl_configuration/package command, expecting name and version"); CYG_REPORT_RETURN(); return TCL_OK; } @@ -1810,18 +1825,22 @@ CdlConfigurationBody::savefile_package_c pkg = dynamic_cast(node); if (0 == pkg) { // The name is in use, but it is not a package - CdlParse::report_error(interp, std::string("Unable to load package ") + pkgname + ", the name is already in use."); + CdlParse::report_error(interp, "", + std::string("Unable to load package `") + pkgname + "', the name is already in use."); } else if (pkgversion != pkg->get_value()) { - CdlParse::report_warning(interp, std::string("Cannot load version ") + pkgversion + " of package " + - pkgname + ", version " + pkg->get_value() + " already loaded."); + CdlParse::report_warning(interp, "", + std::string("Cannot load version `") + pkgversion + "' of package `" + + pkgname + "', version `" + pkg->get_value() + "' is already loaded."); } } else if (!db->is_known_package(pkgname)) { - CdlParse::report_error(interp, std::string("Attempt to load an unknown package ") + pkgname); + CdlParse::report_error(interp, "", + std::string("Attempt to load an unknown package `") + pkgname + "'."); } else { if ("" != pkgversion) { const std::vector& versions = db->get_package_versions(pkgname); if (versions.end() == std::find(versions.begin(), versions.end(), pkgversion)) { - CdlParse::report_warning(interp, std::string("The savefile specifies version `") + pkgversion + + CdlParse::report_warning(interp, "", + std::string("The savefile specifies version `") + pkgversion + "' for package `" + pkgname + "'\nThis version is not available.\n" + "Using the most recent version instead."); pkgversion = ""; diff --git a/host/libcdl/database.cxx b/host/libcdl/database.cxx --- a/host/libcdl/database.cxx +++ b/host/libcdl/database.cxx @@ -73,59 +73,25 @@ char* CdlPackagesDatabaseBody::database_name = "ecos.db"; -// ---------------------------------------------------------------------------- // The new_package etc. commands need to store the name of the // current package so that subsequent commands can do the right thing. // Using constant strings as the key avoids typo problems. -const char* dbparser_current_package = "::dbparser_current_package"; -const char* dbparser_current_target = "::dbparser_current_target"; +const char* dbparser_pkgname = "::dbparser_pkgname"; +const char* dbparser_pkgdata = "__cdl_dbparser_pkgdata"; +const char* dbparser_targetname = "::dbparser_targetname"; +const char* dbparser_targetdata = "__cdl_dbparser_targetdata"; const char* dbparser_component_repository = "::component_repository"; -const char* dbparser_database_name = "::database_name"; -const char* dbparser_pkgdir = "::pkgdir"; -const char* dbparser_current_version = "::version"; -const char* dbparser_current_script = "::script"; -const char* dbparser_database_key = "dbparser_key"; // for assoc data +const char* dbparser_database_key = "__dbparser_key"; // for assoc data const char* template_description_key = "__cdl_extract_template_description"; // ditto -const char* template_packages_key = "_cdl_extract_template_packages"; +const char* template_packages_key = "__cdl_extract_template_packages"; + +// These are useful for generating diagnostics. +static std::string diag_package = std::string("package "); +static std::string diag_target = std::string("target "); CYGDBG_DEFINE_MEMLEAK_COUNTER(CdlPackagesDatabaseBody); //}}} -//{{{ Utility Tcl scripts - -// ---------------------------------------------------------------------------- -// Utility scripts. -// -// Given a directory and a filename relative to that directory, -// extract the contents of that file and store it in a variable -// "script". - -static char* read_file_script = " \n\ -if {[file pathtype $::database_name] != \"relative\"} { \n\ - error \"Database name \\\"$::database_name\\\" should be relative\" \n\ -} \n\ -set filename [file join $::component_repository $::database_name] \n\ -if {0 == [file exists $filename]} { \n\ - error \"Component repository database $filename does not exist\" \n\ -} \n\ -if {0 == [file readable $filename]} { \n\ - error \"Component repository database $filename is not readable\" \n\ -} \n\ -set fd \"\" \n\ -set script \"\" \n\ -set status [catch { \n\ - set fd [open $filename r] \n\ - set script [read $fd] \n\ -} message] \n\ -if {$fd != \"\"} { \n\ - close $fd \n\ -} \n\ -if { $status != 0 } { \n\ - error $message \n\ -} \n\ -"; - -//}}} //{{{ Tcl commands for the parser //{{{ CdlDbParser class @@ -148,8 +114,6 @@ class CdlDbParser { static int target_description(CdlInterpreter, int, char**); static int target_alias(CdlInterpreter, int, char**); static int target_packages(CdlInterpreter, int, char**); - static int target_command_prefix(CdlInterpreter, int, char**); - static int target_cflags(CdlInterpreter, int, char**); static int target_enable(CdlInterpreter, int, char**); static int target_disable(CdlInterpreter, int, char**); static int target_set_value(CdlInterpreter, int, char**); @@ -172,34 +136,43 @@ CdlDbParser::new_package(CdlInterpreter CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); if (3 != argc) { - interp->set_result("A package definition should include name and contents"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + if (argc < 2) { + CdlParse::report_error(interp, "", "Invalid package command, missing name and contents."); + } else if (argc == 2) { + CdlParse::report_error(interp, diag_package + argv[1], "Invalid package command, missing body."); + } else { + CdlParse::report_error(interp, diag_package + argv[1], + "Invalid package command, expecting just name and body."); + } + CYG_REPORT_RETVAL(TCL_OK); + return TCL_OK; } std::string pkg_name = argv[1]; - std::string msg = std::string("Package ") + pkg_name + ": "; // Better make sure that this is not a duplicate definition. if (std::find(db->package_names.begin(), db->package_names.end(), pkg_name) != db->package_names.end()) { - interp->set_result(msg + "a package can only be defined once"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_warning(interp, diag_package + pkg_name, "Duplicate package entry, ignoring second occurence."); + CYG_REPORT_RETVAL(TCL_OK); + return TCL_OK; } - // Add this package to the list. - db->package_names.push_back(pkg_name); - - // Also create a new package structure. This requires a default structure, - // which cannot be filled in until the body is executed. - CdlPackagesDatabaseBody::package_data tmp_struct; - db->packages[pkg_name] = tmp_struct; - - CdlPackagesDatabaseBody::package_data& package = db->packages[pkg_name]; + + // The package data is constructed locally. It only gets added to + // the database in the absence of errors. + bool package_ok = true; + int old_error_count = CdlParse::get_error_count(interp); + + CdlPackagesDatabaseBody::package_data package; + package.description = ""; + package.directory = ""; + package.script = ""; + package.hardware = false; + // aliases and versions are vectors and will take care of themselves - package.description = ""; - package.directory = ""; - package.script = ""; - package.hardware = false; - + // And the name had better be valid as well. + if (!Cdl::is_valid_cdl_name(pkg_name)) { + CdlParse::report_error(interp, diag_package + pkg_name, "This is not a valid CDL name."); + } + // Sort out the commands, then invoke the script in argv[2]. There is // no need to worry about error recovery here, any errors will be // fatal anyway. @@ -211,40 +184,74 @@ CdlDbParser::new_package(CdlInterpreter CdlInterpreterCommandEntry("hardware", &CdlDbParser::package_hardware ), CdlInterpreterCommandEntry("", 0 ) }; - int i; - std::vector new_commands; - for (i = 0; 0 != commands[i].command; i++) { - new_commands.push_back(commands[i]); - } - std::vector* old_commands = interp->push_commands(new_commands); - interp->set_variable(dbparser_current_package, pkg_name); - std::string str_result; - if (TCL_OK != interp->eval(argv[2], str_result)) { - interp->set_result(msg + str_result); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - interp->pop_commands(old_commands); - interp->unset_variable(dbparser_current_package); + CdlInterpreterBody::CommandSupport cmds(interp, commands); + CdlInterpreterBody::VariableSupport interp_name(interp, dbparser_pkgname, pkg_name); + CdlInterpreterBody::AssocSupport interp_data(interp, dbparser_pkgdata, static_cast(&package)); + int result = interp->eval(argv[2]); + if (TCL_OK == result) { + + // The body has been parsed OK. Check that it is valid. + if ("" == package.directory) { + CdlParse::report_error(interp, diag_package + pkg_name, "Missing directory specification."); + } + if ("" == package.script) { + CdlParse::report_error(interp, diag_package + pkg_name, "Missing script specification."); + } + if (0 == package.aliases.size()) { + CdlParse::report_error(interp, diag_package + pkg_name, "At least one alias should be supplied."); + } + + // Additional checks. Is the package directory actually present. + if ("" != package.directory) { + std::string repo = interp->get_variable(dbparser_component_repository); + CYG_ASSERTC("" != repo); - // Some of the fields are compulsory. - if ("" == package.directory) { - interp->set_result(msg + "missing directory specification"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + std::string pkgdir = repo + "/" + package.directory; + if (!interp->is_directory(pkgdir)) { + CdlParse::report_warning(interp, diag_package + pkg_name, + std::string("This package is not present in the component repository.\nThere is no directory `") + + pkgdir + "'."); + package_ok = false; + } else { + + // Now look for version subdirectories. There should be at least one. + std::vector subdirs; + unsigned int i; + interp->locate_subdirs(pkgdir, subdirs); + std::sort(subdirs.begin(), subdirs.end(), Cdl::version_cmp()); + + for (i = 0; i < subdirs.size(); i++) { + if ("CVS" == subdirs[i]) { + continue; + } + if ("" != package.script) { + if (!(interp->is_file(pkgdir + "/" + subdirs[i] + "/cdl/" + package.script) || + interp->is_file(pkgdir + "/" + subdirs[i] + "/" + package.script))) { + CdlParse::report_warning(interp, diag_package + pkg_name, + std::string("Version subdirectory `") + subdirs[i] + + "' does not have a CDL script `" + package.script + "'."); + continue; + } + } + package.versions.push_back(subdirs[i]); + } + if (0 == package.versions.size()) { + CdlParse::report_warning(interp, diag_package + pkg_name, + "This package does not have any valid version subdirectories."); + package_ok = false; + } + } + } } - if ("" == package.script) { - interp->set_result(msg + "missing script specification"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + + // If the package is still ok, now is the time to add it to the database. + if (package_ok && (old_error_count == CdlParse::get_error_count(interp))) { + db->package_names.push_back(pkg_name); + db->packages[pkg_name] = package; } - if (0 == package.aliases.size()) { - interp->set_result(msg + "at least one alias should be supplied"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - CYG_REPORT_RETVAL(TCL_OK); - return TCL_OK; + + CYG_REPORT_RETVAL(result); + return result; } // Syntax: description @@ -255,28 +262,18 @@ CdlDbParser::package_description(CdlInte CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_package); + std::string name = interp->get_variable(dbparser_pkgname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->packages.find(name) != db->packages.end()); - - CdlPackagesDatabaseBody::package_data& package = db->packages[name]; - std::string msg = "Package " + name + ": "; + CdlPackagesDatabaseBody::package_data* package = + static_cast(interp->get_assoc_data(dbparser_pkgdata)); if (2 != argc) { - interp->set_result(msg + "the package description should be a single string"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_error(interp, diag_package + name, "Invalid description, expecting a single string."); + } else if ("" != package->description) { + CdlParse::report_warning(interp, diag_package + name, "A package should have only one description."); + } else { + package->description = argv[1]; } - if ("" != package.description) { - interp->set_result(msg + "a package can have only one description"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - - package.description = argv[1]; CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -291,45 +288,35 @@ CdlDbParser::package_alias(CdlInterprete CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_package); + std::string name = interp->get_variable(dbparser_pkgname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->packages.find(name) != db->packages.end()); - - CdlPackagesDatabaseBody::package_data& package = db->packages[name]; - std::string msg = "Package " + name + ": "; - - // The alias command should be used only once - if (0 < package.aliases.size()) { - interp->set_result(msg + "there should be only one list of aliases"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } + CdlPackagesDatabaseBody::package_data* package = + static_cast(interp->get_assoc_data(dbparser_pkgdata)); + // There should be one argument, a list of valid packages. + // Also, the alias command should be used only once if (2 != argc) { - interp->set_result(msg + "alias should be followed by a list of known aliases"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_error(interp, diag_package + name, + "The alias command should be followed by a list of known aliases."); + } else if (0 < package->aliases.size()) { + CdlParse::report_warning(interp, diag_package + name, "There should be only one list of aliases."); + } else { + int list_count = 0; + char** list_entries = 0; + Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); + if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { + CdlParse::report_error(interp, diag_package + name, Tcl_GetStringResult(tcl_interp)); + } else { + if (0 == list_count) { + CdlParse::report_error(interp, diag_package + name, "At least one alias should be supplied."); + } else { + for (int i = 0; i < list_count; i++) { + package->aliases.push_back(list_entries[i]); + } + } + Tcl_Free((char*)list_entries); + } } - int list_count = 0; - char** list_entries = 0; - Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); - if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { - interp->set_result(msg + Tcl_GetStringResult(tcl_interp)); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - if (0 == list_count) { - interp->set_result(msg + "at least one alias should be supplied"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - for (int i = 0; i < list_count; i++) { - package.aliases.push_back(list_entries[i]); - } - Tcl_Free((char*)list_entries); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -344,30 +331,20 @@ CdlDbParser::package_directory(CdlInterp CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_package); + std::string name = interp->get_variable(dbparser_pkgname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->packages.find(name) != db->packages.end()); - - CdlPackagesDatabaseBody::package_data& package = db->packages[name]; - std::string msg = "Package " + name + ": "; + CdlPackagesDatabaseBody::package_data* package = + static_cast(interp->get_assoc_data(dbparser_pkgdata)); - // The directory command should be used only once - if ("" != package.directory) { - interp->set_result(msg + "a package can be located in only one directory"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + // There should be exactly one argument, and the directory command + // should be used only once. + if (2 != argc) { + CdlParse::report_error(interp, diag_package + name, "Only one directory can be specified."); + } else if ("" != package->directory) { + CdlParse::report_warning(interp, diag_package + name, "A package can be located in only one directory."); + } else { + package->directory = argv[1]; } - // And there should be exactly one argument. - if (2 != argc) { - interp->set_result(msg + "only one directory can be specified"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - - package.directory = argv[1]; CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; } @@ -381,27 +358,18 @@ CdlDbParser::package_hardware(CdlInterpr CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_package); + std::string name = interp->get_variable(dbparser_pkgname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->packages.find(name) != db->packages.end()); - - CdlPackagesDatabaseBody::package_data& package = db->packages[name]; - std::string msg = "Package " + name + ": "; + CdlPackagesDatabaseBody::package_data* package = + static_cast(interp->get_assoc_data(dbparser_pkgdata)); if (1 != argc) { - interp->set_result(msg + "there should be no further data after hardware"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_error(interp, diag_package + name, "There should be no further data after hardware."); + } else if (package->hardware) { + CdlParse::report_warning(interp, diag_package + name, "The hardware property should be specified only once"); + } else { + package->hardware = true; } - if (package.hardware) { - interp->set_result(msg + "the hardware property should be specified only once"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - package.hardware = true; CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -415,29 +383,20 @@ CdlDbParser::package_script(CdlInterpret CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_package); + std::string name = interp->get_variable(dbparser_pkgname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->packages.find(name) != db->packages.end()); - - CdlPackagesDatabaseBody::package_data& package = db->packages[name]; - std::string msg = "Package " + name + ": "; + CdlPackagesDatabaseBody::package_data* package = + static_cast(interp->get_assoc_data(dbparser_pkgdata)); - // The script command should be used only once - if ("" != package.script) { - interp->set_result(msg + "a package can have only one starting CDL script"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + // There should be exactly one argument, and the script command + // should be used only once + if (2 != argc) { + CdlParse::report_error(interp, diag_package + name, "Only one CDL script can be specified."); + } else if ("" != package->script) { + CdlParse::report_warning(interp, diag_package + name, "A package can have only one starting CDL script."); + } else { + package->script = argv[1]; } - // And there should be exactly one argument. - if (2 != argc) { - interp->set_result(msg + "only one CDL script can be specified"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - package.script = argv[1]; CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -460,31 +419,35 @@ CdlDbParser::new_target(CdlInterpreter i CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); if (3 != argc) { - interp->set_result("A target definition should include name and contents"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + if (argc < 2) { + CdlParse::report_error(interp, "", "Invalid target command, missing name and contents."); + } else if (argc == 2) { + CdlParse::report_error(interp, diag_target + argv[1], "Invalid target command, missing body."); + } else { + CdlParse::report_error(interp, diag_target + argv[1], "Invalid target command, expecting just name and body."); + } + CYG_REPORT_RETVAL(TCL_OK); + return TCL_OK; } + std::string target_name = argv[1]; - std::string msg = std::string("Target ") + target_name + ": "; // Better make sure that this is not a duplicate definition. if (std::find(db->target_names.begin(), db->target_names.end(), target_name) != db->target_names.end()) { - interp->set_result(msg + "a target can only be defined once"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_warning(interp, diag_target + target_name, + "Duplicate target entry, ignoring second occurence."); + CYG_REPORT_RETVAL(TCL_OK); + return TCL_OK; } - // Add this target to the list. - db->target_names.push_back(target_name); - // Also create a new target structure. This requires a default structure, - // which cannot be filled in until the body is executed. - CdlPackagesDatabaseBody::target_data tmp_struct; - db->targets[target_name] = tmp_struct; + // The target data is constructed locally. It only gets added to the + // database in the absence of errors. + bool target_ok = true; + int old_error_count = CdlParse::get_error_count(interp); - CdlPackagesDatabaseBody::target_data& target = db->targets[target_name]; + CdlPackagesDatabaseBody::target_data target; + target.description = ""; // aliases, packages and compiler_flags are vectors and will take care of themselves - target.description = ""; - target.command_prefix = ""; // Sort out the commands, then invoke the script in argv[2]. There is // no need to worry about error recovery here, any errors will be @@ -493,48 +456,33 @@ CdlDbParser::new_target(CdlInterpreter i CdlInterpreterCommandEntry("description", &CdlDbParser::target_description ), CdlInterpreterCommandEntry("alias", &CdlDbParser::target_alias ), CdlInterpreterCommandEntry("packages", &CdlDbParser::target_packages ), - CdlInterpreterCommandEntry("command_prefix", &CdlDbParser::target_command_prefix ), - CdlInterpreterCommandEntry("cflags", &CdlDbParser::target_cflags ), CdlInterpreterCommandEntry("enable", &CdlDbParser::target_enable ), CdlInterpreterCommandEntry("disable", &CdlDbParser::target_disable ), CdlInterpreterCommandEntry("set_value", &CdlDbParser::target_set_value ), CdlInterpreterCommandEntry("", 0 ) }; - int i; - std::vector new_commands; - for (i = 0; 0 != commands[i].command; i++) { - new_commands.push_back(commands[i]); + CdlInterpreterBody::CommandSupport interp_cmds(interp, commands); + CdlInterpreterBody::VariableSupport interp_name(interp, dbparser_targetname, target_name); + CdlInterpreterBody::AssocSupport interp_data(interp, dbparser_targetdata, static_cast(&target)); + int result = interp->eval(argv[2]); + if (TCL_OK == result) { + + if (0 == target.aliases.size()) { + CdlParse::report_error(interp, diag_target + target_name, "At least one alias should be supplied."); + } + + // There is no check for > 0 hardware packages. This is an unlikely + // scenario but should be allowed for. + // Add this target to the list. } - std::vector* old_commands = interp->push_commands(new_commands); - interp->set_variable(dbparser_current_target, target_name); - std::string str_result; - if (TCL_OK != interp->eval(argv[2], str_result)) { - interp->set_result(msg + str_result); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - interp->pop_commands(old_commands); - interp->unset_variable(dbparser_current_target); - // Some of the fields are compulsory. - if (0 == target.aliases.size()) { - interp->set_result(msg + "at least one alias should be supplied"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + if (target_ok && (old_error_count == CdlParse::get_error_count(interp))) { + db->target_names.push_back(target_name); + db->targets[target_name] = target; } -#if 0 - // command_prefix is now handled in the configuration data. - if ("" == target.command_prefix) { - interp->set_result(msg + "missing command prefix specification"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } -#endif - // There is no check for > 0 hardware packages. This is an unlikely - // scenario but should be allowed for. - CYG_REPORT_RETVAL(TCL_OK); - return TCL_OK; + CYG_REPORT_RETVAL(result); + return result; } // Syntax: description @@ -545,28 +493,18 @@ CdlDbParser::target_description(CdlInter CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_target); + std::string name = interp->get_variable(dbparser_targetname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->targets.find(name) != db->targets.end()); - - CdlPackagesDatabaseBody::target_data& target = db->targets[name]; - std::string msg = "Target " + name + ": "; + CdlPackagesDatabaseBody::target_data* target = + static_cast(interp->get_assoc_data(dbparser_targetdata)); if (2 != argc) { - interp->set_result(msg + "the target description should be a single string"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_error(interp, diag_target + name, "The target description should be a single string."); + } else if ("" != target->description) { + CdlParse::report_warning(interp, diag_target + name, "A target should have only one description."); + } else { + target->description = argv[1]; } - if ("" != target.description) { - interp->set_result(msg + "a target can have only one description"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - - target.description = argv[1]; CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -581,45 +519,34 @@ CdlDbParser::target_alias(CdlInterpreter CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_target); + std::string name = interp->get_variable(dbparser_targetname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->targets.find(name) != db->targets.end()); - - CdlPackagesDatabaseBody::target_data& target = db->targets[name]; - std::string msg = "Target " + name + ": "; - + CdlPackagesDatabaseBody::target_data* target = + static_cast(interp->get_assoc_data(dbparser_targetdata)); + + // There should be one argument, a list of valid aliases // The alias command should be used only once - if (0 < target.aliases.size()) { - interp->set_result(msg + "there should be only one list of aliases"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - // There should be one argument, a list of valid aliases if (2 != argc) { - interp->set_result(msg + "alias should be followed by a list of known aliases"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_error(interp, diag_target + name, "The alias command should be followed by a list of known aliases"); + } else if (0 < target->aliases.size()) { + CdlParse::report_warning(interp, diag_target + name, "There should be only one list of aliases."); + } else { + int list_count = 0; + char** list_entries = 0; + Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); + if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { + CdlParse::report_error(interp, diag_target + name, Tcl_GetStringResult(tcl_interp)); + } else { + if (0 == list_count) { + CdlParse::report_error(interp, diag_target + name, "At least one alias should be supplied."); + } else { + for (int i = 0; i < list_count; i++) { + target->aliases.push_back(list_entries[i]); + } + } + Tcl_Free((char*)list_entries); + } } - int list_count = 0; - char** list_entries = 0; - Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); - if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { - interp->set_result(msg + Tcl_GetStringResult(tcl_interp)); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - if (0 == list_count) { - interp->set_result(msg + "at least one alias should be supplied"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - for (int i = 0; i < list_count; i++) { - target.aliases.push_back(list_entries[i]); - } - Tcl_Free((char*)list_entries); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -634,151 +561,33 @@ CdlDbParser::target_packages(CdlInterpre CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_target); + std::string name = interp->get_variable(dbparser_targetname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->targets.find(name) != db->targets.end()); - - CdlPackagesDatabaseBody::target_data& target = db->targets[name]; - std::string msg = "Target " + name + ": "; - - // The packages command should be used only once - if (0 < target.packages.size()) { - interp->set_result(msg + "there should be only one list of packages"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - // There should be one argument, a list of valid packages. - if (2 != argc) { - interp->set_result(msg + "packages should be followed by a list of known packages"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - int list_count = 0; - char** list_entries = 0; - Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); - if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { - interp->set_result(msg + Tcl_GetStringResult(tcl_interp)); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - if (0 == list_count) { - interp->set_result(msg + "at least one package should be supplied"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - for (int i = 0; i < list_count; i++) { - target.packages.push_back(list_entries[i]); - } - Tcl_Free((char*)list_entries); - - CYG_REPORT_RETVAL(TCL_OK); - return TCL_OK; -} - -// Syntax: command_prefix -int -CdlDbParser::target_command_prefix(CdlInterpreter interp, int argc, char** argv) -{ - CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_command_prefix", "result %d"); - CYG_REPORT_FUNCARG1XV(argc); - CYG_PRECONDITION_CLASSC(interp); - - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_target); - CYG_ASSERTC("" != name); - CYG_ASSERTC(db->targets.find(name) != db->targets.end()); - - CdlPackagesDatabaseBody::target_data& target = db->targets[name]; - std::string msg = "Target " + name + ": "; + CdlPackagesDatabaseBody::target_data* target = + static_cast(interp->get_assoc_data(dbparser_targetdata)); - // The command_prefix command should be used only once - if ("" != target.command_prefix) { - interp->set_result(msg + "a target can have only one command_prefix string"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - // And there should be exactly one argument. + // There should be one argument, a list of valid packages. + // The packages command should be used only once if (2 != argc) { - interp->set_result(msg + "only one command_prefix can be specified"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - - target.command_prefix = argv[1]; - CYG_REPORT_RETVAL(TCL_OK); - return TCL_OK; -} - -// Syntax: cflags ... -// For example: cflags { ERRFLAGS "-Wall" DBGFLAGS "-g" } -int -CdlDbParser::target_cflags(CdlInterpreter interp, int argc, char** argv) -{ - CYG_REPORT_FUNCNAMETYPE("CdlDbParser::target_cflags", "result %d"); - CYG_REPORT_FUNCARG1XV(argc); - CYG_PRECONDITION_CLASSC(interp); - - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_target); - CYG_ASSERTC("" != name); - CYG_ASSERTC(db->targets.find(name) != db->targets.end()); - - CdlPackagesDatabaseBody::target_data& target = db->targets[name]; - std::string msg = "Target " + name + ": "; - - // The cflags command should be used only once - if (0 < target.cflags.size()) { - interp->set_result(msg + "there should be only one set of compiler flags"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - // There should be one argument, a list of valid flags. - if (2 != argc) { - interp->set_result(msg + "cflags should be followed by a list of compiler flag/value pairs"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - int list_count = 0; - char** list_entries = 0; - Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); - if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { - interp->set_result(msg + Tcl_GetStringResult(tcl_interp)); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - if (0 != (list_count % 2)) { - interp->set_result(msg + "compiler flags and values must occur in pairs"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - int i; - const std::vector& valid_cflags = CdlPackagesDatabaseBody::get_valid_cflags(); - for (i = 0; i < list_count; i+= 2) { - std::vector::const_iterator j; - for (j = valid_cflags.begin(); j != valid_cflags.end(); j++) { - if (*j == list_entries[i]) { - break; + CdlParse::report_error(interp, diag_target + name, "`packages' should be followed by a list of known packages."); + } else if (0 < target->packages.size()) { + CdlParse::report_warning(interp, diag_target + name, "There should be only one list of packages."); + } else { + int list_count = 0; + char** list_entries = 0; + Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); + if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { + CdlParse::report_error(interp, diag_target + name, Tcl_GetStringResult(tcl_interp)); + } else { + // Allow for a dummy target spec, just in case it proves useful. + if (0 != list_count) { + for (int i = 0; i < list_count; i++) { + target->packages.push_back(list_entries[i]); + } } - if (j == valid_cflags.end()) { - interp->set_result(msg + "invalid cflag name " + list_entries[i]); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } + Tcl_Free((char*)list_entries); } } - // NOTE: do the quote marks have to be removed explicitly or is that done - // by splitlist? - for (i = 0; i < list_count; i+= 2) { - target.cflags.push_back(std::make_pair(list_entries[i], list_entries[i+1])); - } - Tcl_Free((char*)list_entries); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -793,34 +602,27 @@ CdlDbParser::target_enable(CdlInterprete CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_target); + std::string name = interp->get_variable(dbparser_targetname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->targets.find(name) != db->targets.end()); - - CdlPackagesDatabaseBody::target_data& target = db->targets[name]; - std::string msg = "Target " + name + ": "; + CdlPackagesDatabaseBody::target_data* target = + static_cast(interp->get_assoc_data(dbparser_targetdata)); // There should be one argument, a list of valid flags. if (2 != argc) { - interp->set_result(msg + "enable should be followed by a list of CDL options"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_error(interp, diag_target + name, "`enable' should be followed by a list of CDL options."); + } else { + int list_count = 0; + char** list_entries = 0; + Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); + if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { + CdlParse::report_error(interp, diag_target + name, Tcl_GetStringResult(tcl_interp)); + } else { + for (int i = 0; i < list_count; i++) { + target->enable.push_back(list_entries[i]); + } + Tcl_Free((char *) list_entries); + } } - int list_count = 0; - char** list_entries = 0; - Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); - if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { - interp->set_result(msg + Tcl_GetStringResult(tcl_interp)); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - for (int i = 0; i < list_count; i++) { - target.enable.push_back(list_entries[i]); - } - Tcl_Free((char *) list_entries); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -836,34 +638,27 @@ CdlDbParser::target_disable(CdlInterpret CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_target); + std::string name = interp->get_variable(dbparser_targetname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->targets.find(name) != db->targets.end()); - - CdlPackagesDatabaseBody::target_data& target = db->targets[name]; - std::string msg = "Target " + name + ": "; + CdlPackagesDatabaseBody::target_data* target = + static_cast(interp->get_assoc_data(dbparser_targetdata)); // There should be one argument, a list of valid flags. if (2 != argc) { - interp->set_result(msg + "disable should be followed by a list of CDL options"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_error(interp, diag_target + name, "`disable' should be followed by a list of CDL options."); + } else { + int list_count = 0; + char** list_entries = 0; + Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); + if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { + CdlParse::report_error(interp, diag_target + name, Tcl_GetStringResult(tcl_interp)); + } else { + for (int i = 0; i < list_count; i++) { + target->disable.push_back(list_entries[i]); + } + Tcl_Free((char *) list_entries); + } } - int list_count = 0; - char** list_entries = 0; - Tcl_Interp* tcl_interp = interp->get_tcl_interpreter(); - if (TCL_OK != Tcl_SplitList(tcl_interp, argv[1], &list_count, &list_entries)) { - interp->set_result(msg + Tcl_GetStringResult(tcl_interp)); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; - } - for (int i = 0; i < list_count; i++) { - target.disable.push_back(list_entries[i]); - } - Tcl_Free((char *) list_entries); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -878,23 +673,17 @@ CdlDbParser::target_set_value(CdlInterpr CYG_REPORT_FUNCARG1XV(argc); CYG_PRECONDITION_CLASSC(interp); - CdlPackagesDatabase db = static_cast(interp->get_assoc_data(dbparser_database_key)); - CYG_INVARIANT_CLASSC(CdlPackagesDatabaseBody, db); - - std::string name = interp->get_variable(dbparser_current_target); + std::string name = interp->get_variable(dbparser_targetname); CYG_ASSERTC("" != name); - CYG_ASSERTC(db->targets.find(name) != db->targets.end()); - - CdlPackagesDatabaseBody::target_data& target = db->targets[name]; - std::string msg = "Target " + name + ": "; + CdlPackagesDatabaseBody::target_data* target = + static_cast(interp->get_assoc_data(dbparser_targetdata)); // There should be one argument, a list of valid flags. if (3 != argc) { - interp->set_result(msg + "set_value command should be followed by an option name and its value"); - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + CdlParse::report_error(interp, diag_target + name, "`set_value' should be followed by an option name and its value."); + } else { + target->set_values.push_back(std::make_pair(std::string(argv[1]), std::string(argv[2]))); } - target.set_values.push_back(std::make_pair(std::string(argv[1]), std::string(argv[2]))); CYG_REPORT_RETVAL(TCL_OK); return TCL_OK; @@ -903,7 +692,6 @@ CdlDbParser::target_set_value(CdlInterpr //}}} //}}} - //{{{ CdlPackagesDatabase:: creation // ---------------------------------------------------------------------------- @@ -911,7 +699,7 @@ CdlDbParser::target_set_value(CdlInterpr // constructor. CdlPackagesDatabase -CdlPackagesDatabaseBody::make(std::string repo) +CdlPackagesDatabaseBody::make(std::string repo, CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn) throw(CdlInputOutputException, std::bad_alloc) { CYG_REPORT_FUNCNAMETYPE("CdlPackagesDatabase::make", "database %p"); @@ -936,14 +724,14 @@ CdlPackagesDatabaseBody::make(std::strin repo[i] = '/'; } } - CdlPackagesDatabase result = new CdlPackagesDatabaseBody(repo); + CdlPackagesDatabase result = new CdlPackagesDatabaseBody(repo, error_fn, warn_fn); CYG_REPORT_RETVAL(result); return result; } // ---------------------------------------------------------------------------- -CdlPackagesDatabaseBody::CdlPackagesDatabaseBody(std::string repo) +CdlPackagesDatabaseBody::CdlPackagesDatabaseBody(std::string repo, CdlDiagnosticFnPtr error_fn, CdlDiagnosticFnPtr warn_fn) throw(CdlInputOutputException, std::bad_alloc) { CYG_REPORT_FUNCNAME("CdlPackagesDatabase:: constructor"); @@ -960,99 +748,36 @@ CdlPackagesDatabaseBody::CdlPackagesData // For now it is assumed that the supplied pathname is acceptable to // Tcl. // - // A Tcl interpreter can be used to read in the file. It must not start - // off as a safe interpreter because file I/O is needed. However it has - // to be turned into a safe interpreter before the packages script is - // actually executed. + // No attempt is made at this stage to use a safe interpreter. + // Some file I/O operations are needed while processing the data, + // for example to check that a package is actually installed. + // Additional file I/O may prove useful in future, e.g. to create + // some or all of a database on the fly. Obviously some + // restrictions are desirable (no modify access to the repository, + // no network capabilities, and so on.) These have to be added + // in future. - // No need for a try/catch here, there are no resources to free yet. CdlInterpreter interp = CdlInterpreterBody::make(); try { - interp->set_variable(dbparser_component_repository, repo); - interp->set_variable(dbparser_database_name, database_name); - } - catch(std::bad_alloc) { - delete interp; - throw; - } - std::string str_result; - if (TCL_OK != interp->eval(read_file_script, str_result)) { - delete interp; - throw CdlInputOutputException(str_result); - } - - // We have the script. It comes from a source that is not completely - // trusted so it can only be executed in a safe interpreter. However - // after the script is read it will still be necessary to perform - // glob commands afterwards to locate version subdirectories - // and to check for the existence of the script files. - try { + + CdlInterpreterBody::ContextSupport context(interp, database_name); CdlInterpreterCommandEntry commands[] = { CdlInterpreterCommandEntry("package", &CdlDbParser::new_package ), CdlInterpreterCommandEntry("target", &CdlDbParser::new_target ), CdlInterpreterCommandEntry("", 0 ) }; - unsigned int i; - std::vector new_commands; - for (i = 0; 0 != commands[i].command; i++) { - new_commands.push_back(commands[i]); - } - interp->set_assoc_data(dbparser_database_key, static_cast(this)); - interp->push_commands(new_commands); - - if (TCL_OK != interp->eval(" \n\ - set parser [interp create -safe] \n\ - $parser alias package ::package \n\ - $parser alias target ::target \n\ - $parser eval $script \n\ - ", str_result)) { - throw CdlInputOutputException(str_result); - } + CdlInterpreterBody::CommandSupport cmds(interp, commands); + CdlInterpreterBody::DiagSupport diag(interp, error_fn, warn_fn); + CdlInterpreterBody::AssocSupport assoc(interp, dbparser_database_key, static_cast(this)); + CdlInterpreterBody::VariableSupport var(interp, dbparser_component_repository, repo); + interp->add_command("unknown", &CdlParse::unknown_command); + CdlParse::clear_error_count(interp); - // There should be at least one package and target. - if (0 == package_names.size()) { - throw CdlInputOutputException("There are no packages in the database."); - } - if (0 == target_names.size()) { - throw CdlInputOutputException("There are no targets in the database."); - } - - // All of the package names should be valid CDL names. - std::vector::const_iterator name_i; - std::vector::const_iterator name_j; - for (name_i = package_names.begin(); name_i != package_names.end(); name_i++) { - if (!Cdl::is_valid_cdl_name(*name_i)) { - throw CdlInputOutputException("Package " + *name_i + ", this is not a valid CDL name."); - } - } - - // The ecos.db data has been read in. For each package, find - // the subdirectories and list them as versions. Each package - // should have at least one version. Any errors will be - // handled by the catch statement further down. - for (std::map::iterator pkg_i = packages.begin(); pkg_i != packages.end(); pkg_i++) { - - std::string pkgdir = repo + "/" + pkg_i->second.directory; - std::vector subdirs; - unsigned int i; - interp->locate_subdirs(pkgdir, subdirs); - - for (i = 0; i < subdirs.size(); i++) { - if (("CVS" != subdirs[i]) && - (interp->is_file(pkgdir + "/" + subdirs[i] + "/cdl/" + pkg_i->second.script) || - interp->is_file(pkgdir + "/" + subdirs[i] + "/" + pkg_i->second.script))) { - pkg_i->second.versions.push_back(subdirs[i]); - } - } - - if (0 == pkg_i->second.versions.size()) { - throw CdlInputOutputException("Package " + pkg_i->first + ": there are no version subdirectories"); - } - std::sort(pkg_i->second.versions.begin(), pkg_i->second.versions.end(), Cdl::version_cmp()); - } - + // Ignore errors at this stage, instead check error count at the end. + (void) interp->eval_file(component_repository + "/" + database_name); + // Now start looking for templates. These should reside in the // templates subdirectory of the component repository. Each template // should be in its own directory, and inside each directory should @@ -1061,6 +786,7 @@ CdlPackagesDatabaseBody::CdlPackagesData std::vector subdirs; interp->locate_subdirs(templates_dir, subdirs); + unsigned int i; for (i = 0; i < subdirs.size(); i++) { // Do not add the template to the known ones until we are sure there is // at least one valid template. @@ -1082,20 +808,34 @@ CdlPackagesDatabaseBody::CdlPackagesData } } - // Consistency checks. All target-specific packages should have the - // hardware attribute. Also, all the packages should exist. + // Consistency checks. All target-specific packages should + // have the hardware attribute. Also, all the packages should + // exist. Problems only result in warnings, to allow for + // somewhat inconsistent repositories e.g. an anoncvs tree. + std::vector::const_iterator name_i; + std::vector::const_iterator name_j; for (name_i = target_names.begin(); name_i != target_names.end(); name_i++) { for (name_j = targets[*name_i].packages.begin(); name_j != targets[*name_i].packages.end(); name_j++) { if (std::find(package_names.begin(), package_names.end(), *name_j) == package_names.end()) { - throw CdlInputOutputException("Target " + *name_i + " refers to an unknown package " + *name_j); + CdlParse::report_warning(interp, diag_target + *name_i, + std::string("This target refers to an unknown package `") + *name_j + "'."); } if (!packages[*name_j].hardware) { - throw CdlInputOutputException("Target " + *name_i + " refers to a non-hardware package " + *name_j); + CdlParse::report_warning(interp, diag_target + *name_i, + std::string("This target refers to a package `") + *name_j + + "' that is not hardware-specific."); } } } - } - catch(...) { + + // Now, were there any errors while reading in the database? + // If so it is necessary to throw an exception here, to make sure + // that things get cleaned up properly. + int error_count = CdlParse::get_error_count(interp); + if (0 != error_count) { + throw CdlInputOutputException("Invalid package database."); + } + } catch(...) { // Something has gone wrong. Clear out all of the data accumulated so far, as well // as the interpreter. delete interp; @@ -1452,40 +1192,6 @@ CdlPackagesDatabaseBody::get_target_pack return dummy; } -const std::string& -CdlPackagesDatabaseBody::get_target_command_prefix(std::string target_name) const -{ - CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_target_command_prefix"); - CYG_PRECONDITION_THISC(); - - std::map::const_iterator target_i = targets.find(target_name); - if (target_i != targets.end()) { - CYG_REPORT_RETURN(); - return target_i->second.command_prefix; - } - - CYG_FAIL("Invalid target name passed to CdlPackagesDatabase::get_target_command_prefix()"); - static std::string dummy = ""; - return dummy; -} - -const std::vector >& -CdlPackagesDatabaseBody::get_target_compiler_flags(std::string target_name) const -{ - CYG_REPORT_FUNCNAME("CdlPackagesDatabase::get_target_compiler_flags"); - CYG_PRECONDITION_THISC(); - - std::map::const_iterator target_i = targets.find(target_name); - if (target_i != targets.end()) { - CYG_REPORT_RETURN(); - return target_i->second.cflags; - } - - CYG_FAIL("Invalid target name passed to CdlPackagesDatabase::get_target_compiler_flags()"); - static std::vector > dummy; - return dummy; -} - const std::vector& CdlPackagesDatabaseBody::get_target_enables(std::string target_name) const { diff --git a/host/libcdl/dialog.cxx b/host/libcdl/dialog.cxx --- a/host/libcdl/dialog.cxx +++ b/host/libcdl/dialog.cxx @@ -148,16 +148,14 @@ CdlDialogBody::parse_dialog(CdlInterpret CYG_REPORT_FUNCARG1("argc %d", argc); CYG_PRECONDITION_CLASSC(interp); - const char* diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); + std::string diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); CdlLoadable loadable = interp->get_loadable(); CdlContainer parent = interp->get_container(); CdlToplevel toplevel = interp->get_toplevel(); - std::string filename = interp->get_filename(); CYG_ASSERT_CLASSC(loadable); // There should always be a loadable during parsing CYG_ASSERT_CLASSC(parent); CYG_ASSERT_CLASSC(toplevel); - CYG_ASSERTC("" != filename); // The new dialog should be created and added to the loadable // early on. If there is a parsing error it will get cleaned up @@ -172,13 +170,13 @@ CdlDialogBody::parse_dialog(CdlInterpret // Currently there are no command-line options. This may change in future. if (3 != argc) { - CdlParse::report_error(interp, std::string("Incorrect number of arguments to ") + diag_argv0 + - "\n Expecting name and properties list."); + CdlParse::report_error(interp, "", std::string("Incorrect number of arguments to `") + diag_argv0 + + "'\nExpecting name and properties list."); } else if (!Tcl_CommandComplete(argv[2])) { - CdlParse::report_error(interp, std::string("Invalid property list for cdl_dialog ") + argv[1]); + CdlParse::report_error(interp, "", std::string("Invalid property list for cdl_dialog `") + argv[1] + "'."); } else if (0 != toplevel->lookup(argv[1])) { - CdlParse::report_error(interp, std::string("Dialog ") + argv[1] + " cannot be loaded.\n" + - " The name is already in use."); + CdlParse::report_error(interp, "", std::string("Dialog `") + argv[1] + "' cannot be loaded.\n" + + "The name is already in use."); } else { try { @@ -231,19 +229,19 @@ CdlDialogBody::parse_dialog(CdlInterpret // The display_proc, confirm_proc and cancel_proc properties // are compulsory. if (new_dialog->count_properties(CdlPropertyId_InitProc) > 1) { - CdlParse::report_error(interp, "A dialog should have only one `init_proc' property."); + CdlParse::report_error(interp, "", "A dialog should have only one `init_proc' property."); } if (new_dialog->count_properties(CdlPropertyId_UpdateProc) > 1) { - CdlParse::report_error(interp, "A dialog should have only one `update_proc' property."); + CdlParse::report_error(interp, "", "A dialog should have only one `update_proc' property."); } if (new_dialog->count_properties(CdlPropertyId_DisplayProc) != 1) { - CdlParse::report_error(interp, "A dialog should have one `display_proc' property."); + CdlParse::report_error(interp, "", "A dialog should have one `display_proc' property."); } if (new_dialog->count_properties(CdlPropertyId_ConfirmProc) != 1) { - CdlParse::report_error(interp, "A dialog should have one `confirm_proc' property."); + CdlParse::report_error(interp, "", "A dialog should have one `confirm_proc' property."); } if (new_dialog->count_properties(CdlPropertyId_CancelProc) != 1) { - CdlParse::report_error(interp, "A dialog should have one `cancel_proc' property."); + CdlParse::report_error(interp, "", "A dialog should have one `cancel_proc' property."); } } diff --git a/host/libcdl/expr.cxx b/host/libcdl/expr.cxx --- a/host/libcdl/expr.cxx +++ b/host/libcdl/expr.cxx @@ -1017,6 +1017,7 @@ initialise_tokenisation(std::string data // ::= [ ] + - // ::= [ ] * / % // ::= - | + | ! | * | ? | +// ~ | // | | // | | // ( ) @@ -2247,7 +2248,7 @@ CdlExpressionBody::parse(std::string dat // exception, or we should be at the end of the expression string. if (CdlExprOp_EOD != next_op) { delete result; - throw CdlParseException("unexpected data at end of expression.\n" + get_error_location()); + throw CdlParseException("Unexpected data at end of expression.\n" + get_error_location()); } // Keep a copy of the original string for diagnostics purposes. @@ -2789,7 +2790,7 @@ CdlListExpressionBody::eval_internal(Cdl } result.double_ranges.push_back(std::make_pair(x1, x2)); } else { - throw CdlEvalException("range expression involves non-numerical limits"); + throw CdlEvalException("Range expression involves non-numerical limits"); } } diff --git a/host/libcdl/infer.cxx b/host/libcdl/infer.cxx --- a/host/libcdl/infer.cxx +++ b/host/libcdl/infer.cxx @@ -194,7 +194,7 @@ infer_make_active(CdlTransaction transac CdlContainer parent = node->get_parent(); CYG_ASSERT_CLASSC(parent); if (!transaction->is_active(parent)) { - if (!infer_make_active(transaction, node, level)) { + if (!infer_make_active(transaction, parent, level)) { CYG_REPORT_RETVAL(result); return result; } diff --git a/host/libcdl/interface.cxx b/host/libcdl/interface.cxx --- a/host/libcdl/interface.cxx +++ b/host/libcdl/interface.cxx @@ -118,16 +118,14 @@ CdlInterfaceBody::parse_interface(CdlInt CYG_REPORT_FUNCARG1("argc %d", argc); CYG_PRECONDITION_CLASSC(interp); - const char* diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); + std::string diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); CdlLoadable loadable = interp->get_loadable(); CdlContainer parent = interp->get_container(); CdlToplevel toplevel = interp->get_toplevel(); - std::string filename = interp->get_filename(); CYG_ASSERT_CLASSC(loadable); // There should always be a loadable during parsing CYG_ASSERT_CLASSC(parent); CYG_ASSERT_CLASSC(toplevel); - CYG_ASSERTC("" != filename); // The new interface should be created and added to the loadable. // early on. If there is a parsing error it will get cleaned up @@ -142,19 +140,19 @@ CdlInterfaceBody::parse_interface(CdlInt // Currently there are no command-line options. This may change in future. if (3 != argc) { - CdlParse::report_error(interp, std::string("Incorrect number of arguments to ") + diag_argv0 + - "\n Expecting name and properties list."); + CdlParse::report_error(interp, "", std::string("Incorrect number of arguments to `") + diag_argv0 + + "'\nExpecting name and properties list."); ok = false; } else if (!Tcl_CommandComplete(argv[2])) { - CdlParse::report_error(interp, std::string("Invalid property list for cdl_interface ") + argv[1]); + CdlParse::report_error(interp, "", std::string("Invalid property list for cdl_interface `") + argv[1] + "'."); ok = false; } else if (0 != toplevel->lookup(argv[1])) { // FIXME: interfaces can be generated implicitly because of an // unresolved implements property. This code should look for // an existing auto-generated interface object and replace it // if necessary. - CdlParse::report_error(interp, std::string("Interface ") + argv[1] + " cannot be loaded.\n" + - " The name is already in use."); + CdlParse::report_error(interp, "", std::string("Interface `") + argv[1] + + "' cannot be loaded.\nThe name is already in use."); ok = false; } else { new_interface = new CdlInterfaceBody(argv[1], false); @@ -168,13 +166,13 @@ CdlInterfaceBody::parse_interface(CdlInt return TCL_OK; } } catch(std::bad_alloc e) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory")); result = TCL_ERROR; } catch(CdlParseException e) { interp->set_result(e.get_message()); result = TCL_ERROR; } catch(...) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); result = TCL_ERROR; } if (TCL_OK != result) { @@ -237,30 +235,30 @@ CdlInterfaceBody::parse_interface(CdlInt // Start with the value-related ones. Interfaces always // have the flavor Data. if (new_interface->has_property(CdlPropertyId_Flavor)) { - CdlParse::report_error(interp, "An interface should not have a `flavor' property."); + CdlParse::report_error(interp, "", "An interface should not have a `flavor' property."); } // Interfaces cannot be modified directly by the user, so // there is no point in entry_proc, check_proc, dialog or // wizard if (new_interface->has_property(CdlPropertyId_EntryProc)) { - CdlParse::report_error(interp, "An interface should not have an `entry_proc' property."); + CdlParse::report_error(interp, "", "An interface should not have an `entry_proc' property."); } if (new_interface->has_property(CdlPropertyId_CheckProc)) { - CdlParse::report_error(interp, "An interface should not have a `check_proc' property."); + CdlParse::report_error(interp, "", "An interface should not have a `check_proc' property."); } if (new_interface->has_property(CdlPropertyId_Dialog)) { - CdlParse::report_error(interp, "An interface should not have a `dialog' property."); + CdlParse::report_error(interp, "", "An interface should not have a `dialog' property."); } if (new_interface->has_property(CdlPropertyId_Wizard)) { - CdlParse::report_error(interp, "An interface should not have a `wizard' property."); + CdlParse::report_error(interp, "", "An interface should not have a `wizard' property."); } // Calculated does not make sense, an interface is implicitly calculated // Nor does default_value. if (new_interface->has_property(CdlPropertyId_Calculated)) { - CdlParse::report_error(interp, "An interface should not have a `calculated' property."); + CdlParse::report_error(interp, "", "An interface should not have a `calculated' property."); } if (new_interface->has_property(CdlPropertyId_DefaultValue)) { - CdlParse::report_error(interp, "An interface should not have a `default_value' property."); + CdlParse::report_error(interp, "", "An interface should not have a `default_value' property."); } // active_if might make sense, as a way of controlling // whether or not a #define will be generated. @@ -283,13 +281,13 @@ CdlInterfaceBody::parse_interface(CdlInt // Errors at this stage should be reported via Tcl, not via C++. // However there is no point in continuing with the parsing operation, // just give up. - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory")); result = TCL_ERROR; } catch (CdlParseException e) { interp->set_result(e.get_message()); result = TCL_ERROR; } catch(...) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); result = TCL_ERROR; } @@ -386,15 +384,15 @@ CdlInterfaceBody::savefile_interface_com try { if (3 != argc) { - CdlParse::report_error(interp, "Invalid cdl_interface command in savefile, expecting two arguments."); + CdlParse::report_error(interp, "", "Invalid cdl_interface command in savefile, expecting two arguments."); } else { CdlNode current_node = toplevel->lookup(argv[1]); if (0 == current_node) { // FIXME: save value in limbo - CdlParse::report_error(interp, + CdlParse::report_error(interp, "", std::string("The savefile contains a cdl_interface command for an unknown interface `") - + argv[1] + "'"); + + argv[1] + "'."); } else { toplevel->get_savefile_subcommands("cdl_interface", subcommands); toplevel_commands = interp->push_commands(subcommands); diff --git a/host/libcdl/interp.cxx b/host/libcdl/interp.cxx --- a/host/libcdl/interp.cxx +++ b/host/libcdl/interp.cxx @@ -91,10 +91,12 @@ CdlInterpreterBody::CdlInterpreterBody(T loadable = 0; container = 0; node = 0; - filename = ""; + context = ""; error_fn_ptr = 0; warning_fn_ptr = 0; current_commands = 0; + cdl_result = false; + CYGDBG_MEMLEAK_CONSTRUCTOR(); cdlinterpreterbody_cookie = CdlInterpreterBody_Magic; @@ -264,10 +266,11 @@ CdlInterpreterBody::~CdlInterpreterBody( loadable = 0; container = 0; node = 0; - filename = ""; + context = ""; error_fn_ptr = 0; warning_fn_ptr = 0; current_commands = 0; + cdl_result = false; // Make sure slave interpreters get deleted before the current one for (std::vector::iterator i = slaves.begin(); i != slaves.end(); i++) { @@ -416,14 +419,14 @@ CdlInterpreterBody::get_node() const } std::string -CdlInterpreterBody::get_filename() const +CdlInterpreterBody::get_context() const { - CYG_REPORT_FUNCNAME("CdlInterpreter::get_filename"); + CYG_REPORT_FUNCNAME("CdlInterpreter::get_context"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); - return filename; + return context; } CdlDiagnosticFnPtr @@ -532,27 +535,27 @@ CdlInterpreterBody::pop_node(CdlNode old } std::string -CdlInterpreterBody::push_filename(std::string new_filename) +CdlInterpreterBody::push_context(std::string new_context) { - CYG_REPORT_FUNCNAME("CdlInterpreter::push_filename"); + CYG_REPORT_FUNCNAME("CdlInterpreter::push_context"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); - CYG_PRECONDITIONC("" != new_filename); + CYG_PRECONDITIONC("" != new_context); - std::string result = filename; - filename = new_filename; + std::string result = context; + context = new_context; return result; } void -CdlInterpreterBody::pop_filename(std::string old_filename) +CdlInterpreterBody::pop_context(std::string old_context) { - CYG_REPORT_FUNCNAME("CdlInterpreter::pop_filename"); + CYG_REPORT_FUNCNAME("CdlInterpreter::pop_context"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); - CYG_PRECONDITIONC("" != filename); + CYG_PRECONDITIONC("" != context); - filename = old_filename; + context = old_context; CYG_REPORT_RETURN(); } @@ -650,34 +653,48 @@ CdlInterpreterBody::eval(std::string scr int result = TCL_OK; int size = script.size(); - + + // Distinguish between results set by the Tcl interpreter and results + // set by CDL-related commands running in that interpreter. + cdl_result = false; + if (size < 2048) { char buf[2048]; script.copy(buf, size, 0); buf[size] = '\0'; result = Tcl_Eval(tcl_interp, buf); } else { - char* buf = static_cast(malloc(script.size() + 1)); + char* buf = static_cast(malloc(script.size() + 1)); if (0 == buf) { - // Stay within Tcl's error handling mechanism rather than - // throw an exception. - char *msg = "Out of memory"; - Tcl_SetResult(tcl_interp, msg, TCL_STATIC); - str_result = msg; - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + this->set_result(CdlParse::construct_diagnostic(this, "internal error", "", "Out of memory")); + result = TCL_ERROR; + } else { + script.copy(buf, size, 0); + buf[size] = '\0'; + result = Tcl_Eval(tcl_interp, buf); + free(buf); } - script.copy(buf, size, 0); - buf[size] = '\0'; - result = Tcl_Eval(tcl_interp, buf); - free(buf); } - str_result = Tcl_GetStringResult(tcl_interp); + // The distinction between TCL_OK and TCL_RETURN is probably not worth // worrying about. if (TCL_RETURN == result) { result = TCL_OK; } + + // If we have an error condition that was raised by the Tcl + // interpreter rather than by the library, it needs to be + // raised up to the library level. That way the error count + // etc. are kept accurate. + if ((TCL_OK != result) && !cdl_result) { + char* tcl_result = Tcl_GetStringResult(tcl_interp); + if ((0 == tcl_result) || ('\0' == tcl_result[0])) { + tcl_result = "Internal error, no additional information available."; + } + CdlParse::report_error(this, "", tcl_result); + } + + str_result = Tcl_GetStringResult(tcl_interp); CYG_REPORT_RETVAL(result); return result; } @@ -694,33 +711,46 @@ CdlInterpreterBody::eval_cdl_code(const int result = TCL_OK; int size = script.size(); + // Distinguish between results set by the Tcl interpreter and results + // set by CDL-related commands running in that interpreter. + cdl_result = false; + if (size < 2048) { char buf[2048]; script.copy(buf, size, 0); buf[size] = '\0'; result = Tcl_Eval(tcl_interp, buf); } else { - char* buf = static_cast(malloc(script.size() + 1)); + char* buf = static_cast(malloc(script.size() + 1)); if (0 == buf) { - // Stay within Tcl's error handling mechanism rather than - // throw an exception. - char *msg = "Out of memory"; - Tcl_SetResult(tcl_interp, msg, TCL_STATIC); - str_result = msg; - CYG_REPORT_RETVAL(TCL_ERROR); - return TCL_ERROR; + this->set_result(CdlParse::construct_diagnostic(this, "internal error", "", "Out of memory")); + result = TCL_ERROR; + } else { + script.copy(buf, size, 0); + buf[size] = '\0'; + result = Tcl_Eval(tcl_interp, buf); + free(buf); } - script.copy(buf, size, 0); - buf[size] = '\0'; - result = Tcl_Eval(tcl_interp, buf); - free(buf); } - str_result = Tcl_GetStringResult(tcl_interp); // The distinction between TCL_OK and TCL_RETURN is probably not worth // worrying about. if (TCL_RETURN == result) { result = TCL_OK; } + + // If we have an error condition that was raised by the Tcl + // interpreter rather than by the library, it needs to be + // raised up to the library level. That way the error count + // etc. are kept accurate. + if ((TCL_OK != result) && !cdl_result) { + char* tcl_result = Tcl_GetStringResult(tcl_interp); + if ((0 == tcl_result) || ('\0' == tcl_result[0])) { + tcl_result = "Internal error, no additional information available."; + } + CdlParse::report_error(this, "", tcl_result); + } + + str_result = Tcl_GetStringResult(tcl_interp); CYG_REPORT_RETVAL(result); return result; } @@ -734,17 +764,56 @@ CdlInterpreterBody::eval_file(std::strin CYG_PRECONDITION_THISC(); CYG_PRECONDITIONC("" != script); + // Distinguish between results set by the Tcl interpreter and results + // set by CDL-related commands running in that interpreter. + cdl_result = false; + int result = Tcl_EvalFile(tcl_interp, const_cast(script.c_str())); - str_result = Tcl_GetStringResult(tcl_interp); // The distinction between TCL_OK and TCL_RETURN is probably not worth // worrying about. if (TCL_RETURN == result) { result = TCL_OK; } + + // If we have an error condition that was raised by the Tcl + // interpreter rather than by the library, it needs to be + // raised up to the library level. That way the error count + // etc. are kept accurate. + if ((TCL_OK != result) && !cdl_result) { + char* tcl_result = Tcl_GetStringResult(tcl_interp); + if ((0 == tcl_result) || ('\0' == tcl_result[0])) { + tcl_result = "Internal error, no additional information available."; + } + CdlParse::report_error(this, "", tcl_result); + } + + str_result = Tcl_GetStringResult(tcl_interp); CYG_REPORT_RETVAL(result); return result; } +// Variants for when the result string is of no interest +int +CdlInterpreterBody::eval(std::string script) +{ + std::string result_string; + return this->eval(script, result_string); +} + +int +CdlInterpreterBody::eval_cdl_code(const cdl_tcl_code script) +{ + std::string result_string; + return this->eval_cdl_code(script, result_string); +} + +int +CdlInterpreterBody::eval_file(std::string filename) +{ + std::string result_string; + return this->eval_file(filename, result_string); +} + //}}} //{{{ CdlInterpreter:: set_result() @@ -759,9 +828,22 @@ CdlInterpreterBody::set_result(std::stri CYG_PRECONDITION_THISC(); Tcl_SetResult(tcl_interp, const_cast(result.c_str()), TCL_VOLATILE); + this->cdl_result = true; + CYG_REPORT_RETURN(); } +bool +CdlInterpreterBody::result_set_by_cdl() +{ + CYG_REPORT_FUNCNAMETYPE("CdlInterpreter::result_set_by_cdl", "result %d"); + CYG_PRECONDITION_THISC(); + + bool result = this->cdl_result; + CYG_REPORT_RETVAL(result); + return result; +} + // ---------------------------------------------------------------------------- // Also allow the result to be extracted again. std::string @@ -807,14 +889,14 @@ CdlInterpreterBody::tcl_command_proc(Cli try { result = (*command)(interp, argc, argv); } catch(std::bad_alloc e) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory.")); result = TCL_ERROR; } catch(CdlStringException e) { interp->set_result(e.get_message()); result = TCL_ERROR; } catch(...) { CYG_FAIL("Unexpected C++ exception"); - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Internal error, unexpected C++ exception."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception.")); result = TCL_ERROR; } @@ -1225,7 +1307,7 @@ CdlInterpreterBody::write_data(Tcl_Chann CYG_PRECONDITION_THISC(); if (-1 == Tcl_Write(chan, const_cast(data.data()), data.size())) { - std::string msg = "Unexpected error writing to file " + this->get_filename() + " : " + Tcl_PosixError(tcl_interp); + std::string msg = "Unexpected error writing to file " + this->get_context() + " : " + Tcl_PosixError(tcl_interp); throw CdlInputOutputException(msg); } diff --git a/host/libcdl/option.cxx b/host/libcdl/option.cxx --- a/host/libcdl/option.cxx +++ b/host/libcdl/option.cxx @@ -119,18 +119,16 @@ CdlOptionBody::parse_option(CdlInterpret CYG_REPORT_FUNCARG1("argc %d", argc); CYG_PRECONDITION_CLASSC(interp); - const char* diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); + std::string diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); CdlLoadable loadable = interp->get_loadable(); CdlPackage package = dynamic_cast(loadable); CdlContainer parent = interp->get_container(); CdlToplevel toplevel = interp->get_toplevel(); - std::string filename = interp->get_filename(); CYG_ASSERT_CLASSC(loadable); // There should always be a loadable during parsing CYG_ASSERT_CLASSC(package); // And packages are the only loadable for software CDL CYG_ASSERT_CLASSC(parent); CYG_ASSERT_CLASSC(toplevel); - CYG_ASSERTC("" != filename); // The new option should be created and added to the package // early on. If there is a parsing error it will get cleaned up @@ -145,15 +143,17 @@ CdlOptionBody::parse_option(CdlInterpret // Currently there are no command-line options. This may change in future. if (3 != argc) { - CdlParse::report_error(interp, std::string("Incorrect number of arguments to ") + diag_argv0 + - "\n Expecting name and properties list."); + CdlParse::report_error(interp, "", + std::string("Incorrect number of arguments to `") + diag_argv0 + + "'\nExpecting name and properties list."); ok = false; } else if (!Tcl_CommandComplete(argv[2])) { - CdlParse::report_error(interp, std::string("Invalid property list for cdl_option ") + argv[1]); + CdlParse::report_error(interp, "", + std::string("Invalid property list for cdl_option `") + argv[1] + "'."); ok = false; } else if (0 != toplevel->lookup(argv[1])) { - CdlParse::report_error(interp, std::string("Option ") + argv[1] + " cannot be loaded.\n" + - " The name is already in use."); + CdlParse::report_error(interp, "", + std::string("Option `") + argv[1] + "' cannot be loaded.\nThe name is already in use."); ok = false; } else { new_option = new CdlOptionBody(argv[1]); @@ -167,13 +167,13 @@ CdlOptionBody::parse_option(CdlInterpret return TCL_OK; } } catch(std::bad_alloc e) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory")); result = TCL_ERROR; } catch(CdlParseException e) { interp->set_result(e.get_message()); result = TCL_ERROR; } catch(...) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); result = TCL_ERROR; } if (TCL_OK != result) { @@ -237,13 +237,13 @@ CdlOptionBody::parse_option(CdlInterpret // Errors at this stage should be reported via Tcl, not via C++. // However there is no point in continuing with the parsing operation, // just give up. - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory")); result = TCL_ERROR; } catch (CdlParseException e) { interp->set_result(e.get_message()); result = TCL_ERROR; } catch(...) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); result = TCL_ERROR; } @@ -326,13 +326,13 @@ CdlOptionBody::savefile_option_command(C try { if (3 != argc) { - CdlParse::report_error(interp, "Invalid cdl_option command in savefile, expecting two arguments."); + CdlParse::report_error(interp, "", "Invalid cdl_option command in savefile, expecting two arguments."); } else { CdlNode current_node = config->lookup(argv[1]); if (0 == current_node) { // FIXME: save value in limbo - CdlParse::report_error(interp, + CdlParse::report_error(interp, "", std::string("The savefile contains a cdl_option for an unknown option `") + argv[1] + "'"); } else { diff --git a/host/libcdl/package.cxx b/host/libcdl/package.cxx --- a/host/libcdl/package.cxx +++ b/host/libcdl/package.cxx @@ -145,13 +145,13 @@ CdlPackageBody::parse_package(CdlInterpr CYG_REPORT_FUNCARG1("argc %d", argc); CYG_PRECONDITION_CLASSC(interp); - const char* diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); + std::string diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); CdlLoadable loadable = interp->get_loadable(); CdlPackage package = dynamic_cast(loadable); CdlContainer parent = package->get_parent(); CdlToplevel toplevel = interp->get_toplevel(); - std::string filename = interp->get_filename(); + std::string filename = interp->get_context(); CYG_ASSERT_CLASSC(loadable); // There should always be a loadable during parsing CYG_ASSERT_CLASSC(package); // And packages are the only loadable for software CDL @@ -161,24 +161,19 @@ CdlPackageBody::parse_package(CdlInterpr CYG_UNUSED_PARAM(CdlContainer, parent); CYG_UNUSED_PARAM(CdlToplevel, toplevel); - // Push the package as the current base object early on. - // This aids diagnostics. - CdlNode old_node = interp->push_node(package); - // There should be no current node, in fact the cdl_package command // can only exist at the toplevel of the original script courtesy // of commands being pushed and popped. - CYG_ASSERTC(0 == old_node); - + CYG_ASSERTC(0 == interp->get_node()); + // Also, the package should be the current container. CYG_ASSERTC(package == dynamic_cast(interp->get_container())); - + // Declare these outside the scope of the try statement, to allow // goto calls for the error handling. const std::vector& properties = package->get_properties(); - std::string tcl_result; - std::vector new_commands; - std::vector* old_commands = 0; + + CdlInterpreterBody::NodeSupport interp_node(interp, package); static CdlInterpreterCommandEntry commands[] = { CdlInterpreterCommandEntry("hardware", &parse_hardware ), @@ -191,6 +186,7 @@ CdlPackageBody::parse_package(CdlInterpr CdlInterpreterCommandEntry("cdl_wizard", &CdlWizardBody::parse_wizard ), CdlInterpreterCommandEntry("", 0 ) }; + std::vector new_commands; int i; // All parsing errors may result in an exception, under the control of @@ -200,142 +196,106 @@ CdlPackageBody::parse_package(CdlInterpr // Currently there are no options. This may change in future. if (3 != argc) { - CdlParse::report_error(interp, std::string("Incorrect number of arguments to ") + diag_argv0 + - "\n Expecting name and properties list."); - goto done; - } - if (argv[1] != loadable->get_name()) { - CdlParse::report_error(interp, std::string("Incorrect package name in CDL script.\n") + - " This package is " + loadable->get_name() + "\n" + - " The CDL script " + filename + " defines a package " + argv[1]); - goto done; - } - - if (0 != properties.size()) { - CdlParse::report_error(interp, std::string("Duplicate cdl_package commands for package ") + argv[1]); - goto done; - } - - if (!Tcl_CommandComplete(argv[2])) { - CdlParse::report_error(interp, std::string("Invalid property list for cdl_package ") + argv[1]); - goto done; - } + CdlParse::report_error(interp, "", + std::string("Incorrect number of arguments to `") + diag_argv0 + + "'\nExpecting name and properties list."); + } else if (argv[1] != loadable->get_name()) { + CdlParse::report_error(interp, "", + std::string("Incorrect package name in CDL script.\n") + + "This package is `" + loadable->get_name() + "'\n" + + "The CDL script `" + filename + "' defines a package `" + argv[1] + "'."); + } else if (0 != properties.size()) { + CdlParse::report_error(interp, "", + std::string("Duplicate cdl_package commands for package `") + argv[1] + "'."); + } else if (!Tcl_CommandComplete(argv[2])) { + CdlParse::report_error(interp, "", + std::string("Invalid property list for cdl_package `") + argv[1] + "'."); + } else { - for (i = 0; 0 != commands[i].command; i++) { - new_commands.push_back(commands[i]); - } + for (i = 0; 0 != commands[i].command; i++) { + new_commands.push_back(commands[i]); + } - CdlBuildLoadableBody::add_property_parsers(new_commands); - CdlBuildableBody::add_property_parsers(new_commands); - CdlDefineLoadableBody::add_property_parsers(new_commands); - CdlDefinableBody::add_property_parsers(new_commands); - CdlParentableBody::add_property_parsers(new_commands); - CdlValuableBody::add_property_parsers(new_commands); - CdlUserVisibleBody::add_property_parsers(new_commands); - CdlNodeBody::add_property_parsers(new_commands); + CdlBuildLoadableBody::add_property_parsers(new_commands); + CdlBuildableBody::add_property_parsers(new_commands); + CdlDefineLoadableBody::add_property_parsers(new_commands); + CdlDefinableBody::add_property_parsers(new_commands); + CdlParentableBody::add_property_parsers(new_commands); + CdlValuableBody::add_property_parsers(new_commands); + CdlUserVisibleBody::add_property_parsers(new_commands); + CdlNodeBody::add_property_parsers(new_commands); - // Now evaluate the body. If an error occurs then typically - // this will be reported via CdlParse::report_error(), - // but any exceptions will have been intercepted and - // turned into a Tcl error. - old_commands = interp->push_commands(new_commands); - result = interp->eval(argv[2], tcl_result); - interp->pop_commands(old_commands); - if (TCL_OK != result) { - // No point in taking any further action, just go with the flow - goto done; - } - - // Even if there were errors, they were not fatal. There may - // now be a number of properties for this package, and some - // validation should take place. Start with the base classes. - package->CdlNodeBody::check_properties(interp); - package->CdlUserVisibleBody::check_properties(interp); - package->CdlValuableBody::check_properties(interp); - package->CdlParentableBody::check_properties(interp); - package->CdlBuildableBody::check_properties(interp); - package->CdlBuildLoadableBody::check_properties(interp); - package->CdlDefinableBody::check_properties(interp); - package->CdlDefineLoadableBody::check_properties(interp); + // Now evaluate the body. If an error occurs then typically + // this will be reported via CdlParse::report_error(), + // but any exceptions will have been intercepted and + // turned into a Tcl error. + CdlInterpreterBody::CommandSupport interp_cmds(interp, new_commands); + result = interp->eval(argv[2]); + if (TCL_OK == result) { - // Some of the properties in the base classes are not actually - // appropriate. A package is valuable, but it can only be - // modified by loading and unloading. Many of the value-related - // properties do not make sense. - if (package->count_properties(CdlPropertyId_Flavor) > 0) { - CdlParse::report_error(interp, "A package should not have a `flavor' property."); - } - if (package->count_properties(CdlPropertyId_EntryProc) > 0) { - CdlParse::report_error(interp, "A package should not have an `entry_proc' property."); - } - if (package->count_properties(CdlPropertyId_CheckProc) > 0) { - CdlParse::report_error(interp, "A package should not have a `check_proc' property."); - } - // BLV: this reasoning is faulty, it should be possible to - // control the enabled aspect via an expression. That would - // need option processing for the default_value property. - if (package->count_properties(CdlPropertyId_DefaultValue) > 0) { - CdlParse::report_error(interp, "A package should not have a `default_value' property."); - } - if (package->count_properties(CdlPropertyId_LegalValues) > 0) { - CdlParse::report_error(interp, "A package should not have a `legal_values' property."); - } - if (package->count_properties(CdlPropertyId_Calculated) > 0) { - CdlParse::report_error(interp, "A package should not have a `calculated' property."); - } - if (package->count_properties(CdlPropertyId_Dialog) > 0) { - CdlParse::report_error(interp, "A package should not have a `dialog' property."); - } + // Even if there were errors, they were not fatal. There may + // now be a number of properties for this package, and some + // validation should take place. Start with the base classes. + package->CdlNodeBody::check_properties(interp); + package->CdlUserVisibleBody::check_properties(interp); + package->CdlValuableBody::check_properties(interp); + package->CdlParentableBody::check_properties(interp); + package->CdlBuildableBody::check_properties(interp); + package->CdlBuildLoadableBody::check_properties(interp); + package->CdlDefinableBody::check_properties(interp); + package->CdlDefineLoadableBody::check_properties(interp); -#if 0 - // BLV: this reasoning is faulty, since packages can get loaded - // because of templates or hardware without the user - // necesssarily understanding all the implications. - // Packages should not have active_if statements, only - // requires statements. It makes little sense to load - // a package and have it inactive, instead there should - // be conflicts re. unsatisfied goals. - if (package->count_properties(CdlPropertyId_ActiveIf) > 0) { - CdlParse::report_error(interp, "A package should not have an `active_if' property."); + // Some of the properties in the base classes are not actually + // appropriate. A package is valuable, but it can only be + // modified by loading and unloading. Many of the value-related + // properties do not make sense. + if (package->count_properties(CdlPropertyId_Flavor) > 0) { + CdlParse::report_error(interp, "", "A package should not have a `flavor' property."); + } + if (package->count_properties(CdlPropertyId_EntryProc) > 0) { + CdlParse::report_error(interp, "", "A package should not have an `entry_proc' property."); + } + if (package->count_properties(CdlPropertyId_CheckProc) > 0) { + CdlParse::report_error(interp, "", "A package should not have a `check_proc' property."); + } + // BLV: this reasoning is faulty, it should be possible to + // control the enabled aspect via an expression. That would + // need option processing for the default_value property. + if (package->count_properties(CdlPropertyId_DefaultValue) > 0) { + CdlParse::report_error(interp, "", "A package should not have a `default_value' property."); + } + if (package->count_properties(CdlPropertyId_LegalValues) > 0) { + CdlParse::report_error(interp, "", "A package should not have a `legal_values' property."); + } + if (package->count_properties(CdlPropertyId_Calculated) > 0) { + CdlParse::report_error(interp, "", "A package should not have a `calculated' property."); + } + if (package->count_properties(CdlPropertyId_Dialog) > 0) { + CdlParse::report_error(interp, "", "A package should not have a `dialog' property."); + } + + // There should be at most one each of license_proc, install_proc, include_dir, + // export_to, library, makefile, and wizard. + if (package->count_properties(CdlPropertyId_LicenseProc) > 1) { + CdlParse::report_error(interp, "", "A package should have at most one `license_proc' property."); + } + if (package->count_properties(CdlPropertyId_InstallProc) > 1) { + CdlParse::report_error(interp, "", "A package should have at most one `install_proc' property."); + } + } } -#endif -#if 0 - // BLV: allow hardware packages to have a define_header property for now. - // This simplifies things during the transition - // If this is a hardware package then it cannot also have a define_header property. - // Hardware packages always send their output to hardware.h - if (package->has_property(CdlPropertyId_Hardware) && package->has_property(CdlPropertyId_DefineHeader)) { - CdlParse::report_error(interp, "Hardware packages cannot specify their configuration header"); - } -#endif - - // There should be at most one each of license_proc, install_proc, include_dir, - // export_to, library, makefile, and wizard. - if (package->count_properties(CdlPropertyId_LicenseProc) > 1) { - CdlParse::report_error(interp, "A package should have at most one `license_proc' property."); - } - if (package->count_properties(CdlPropertyId_InstallProc) > 1) { - CdlParse::report_error(interp, "A package should have at most one `install_proc' property."); - } - - done: - // Dummy command just to keep the compiler happy - filename = ""; } catch (std::bad_alloc e) { // Errors at this stage should be reported via Tcl, not via C++ - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "Out of memory."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Out of memory")); result = TCL_ERROR; } catch (CdlParseException e) { interp->set_result(e.get_message()); result = TCL_ERROR; } catch(...) { - interp->set_result(CdlParse::get_diagnostic_prefix(interp) + "internal error, unexpected C++ exception."); + interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); result = TCL_ERROR; } - - // Restore the interpreter to its prior state. - interp->pop_node(old_node); CYG_REPORT_RETVAL(result); return result; @@ -574,12 +534,13 @@ CdlPackageBody::savefile_package_command try { if (3 != argc) { - CdlParse::report_error(interp, "Invalid cdl_package command in savefile, expecting two arguments."); + CdlParse::report_error(interp, "", "Invalid cdl_package command in savefile, expecting two arguments."); } else { CdlNode current_node = config->lookup(argv[1]); if (0 == current_node) { - CdlParse::report_error(interp, std::string("The savefile contains a cdl_package command for `") + + CdlParse::report_error(interp, "", + std::string("The savefile contains a cdl_package command for `") + argv[1] + "' which has not been loaded."); } else { config->get_savefile_subcommands("cdl_package", subcommands); diff --git a/host/libcdl/parse.cxx b/host/libcdl/parse.cxx --- a/host/libcdl/parse.cxx +++ b/host/libcdl/parse.cxx @@ -112,14 +112,17 @@ static std::string property_string = "pr // Some of the properties have aliases in the CDL data, so argv[0] has to be // used to work out what is actually being parsed. However the Tcl interpreter // may prefix the command name with :: to indicate the global namespace. -const char* -CdlParse::get_tcl_cmd_name(const char* name) +std::string +CdlParse::get_tcl_cmd_name(std::string name) { + std::string result; + if ((name[0] == ':') && (name[1] == ':')) { - return &(name[2]); + result = std::string(name, 2, name.size() - 2); } else { - return name; + result = name; } + return result; } // Given a list of arguments, concatenate them together into a C++ string. @@ -252,7 +255,7 @@ CdlParse::parse_options(CdlInterpreter i if ("" == name) { // One of "-", "-=xxx", or "--=x" - CdlParse::report_warning(interp, diag_prefix + ", invalid option string " + argv[index]); + CdlParse::report_warning(interp, diag_prefix, std::string("Invalid option string `") + argv[index] + "'."); } // Do not try to extract the value unless we are sure there @@ -270,9 +273,10 @@ CdlParse::parse_options(CdlInterpreter i for (i = 0; 0 != options[i]; i++) { if (0 == strncmp(name.c_str(), options[i], name.size())) { if (-1 != opt_index) { - CdlParse::report_warning(interp, diag_prefix + ", ambiguous option name " + name + - ", it can match " + get_option_string(options[opt_index]) + - " or " + get_option_string(options[i])); + CdlParse::report_warning(interp, diag_prefix, + std::string("Ambiguous option name `") + name + "'.\n" + + "It can match `" + get_option_string(options[opt_index]) + "'\n" + + "or `" + get_option_string(options[i]) + "'."); index++; break; } else { @@ -282,7 +286,7 @@ CdlParse::parse_options(CdlInterpreter i } } if (-1 == opt_index) { - CdlParse::report_warning(interp, diag_prefix + ", invalid option " + name); + CdlParse::report_warning(interp, diag_prefix, std::string("Invalid option `") + name + "'."); index++; break; } @@ -315,7 +319,7 @@ CdlParse::parse_options(CdlInterpreter i // There should not be a value. If the current argument is of the // form x=y then this is an error. if ('=' == *arg_ptr) { - CdlParse::report_warning(interp, diag_prefix + ", option " + name + " does not take any data"); + CdlParse::report_warning(interp, diag_prefix, std::string("Option `") + name + "' does not take any data."); } // Leave index pointing at the next argument to be processed. index++; @@ -323,7 +327,7 @@ CdlParse::parse_options(CdlInterpreter i if ('=' == *arg_ptr) { value = std::string(++arg_ptr); } else if (++index == argc) { - CdlParse::report_warning(interp, diag_prefix + ", missing data for option " + name); + CdlParse::report_warning(interp, diag_prefix, std::string("Missing data for option `") + name + "'."); } else { value = argv[index]; } @@ -337,8 +341,7 @@ CdlParse::parse_options(CdlInterpreter i if (!multiple_flag) { for (i = 0; i < result.size(); i++) { if (name == result[i].first) { - CdlParse::report_warning(interp, diag_prefix + ", option " + name + - " can only be used once."); + CdlParse::report_warning(interp, diag_prefix, std::string("Option `") + name + "' can only be used once."); break; } } @@ -353,25 +356,121 @@ CdlParse::parse_options(CdlInterpreter i } //}}} -//{{{ Diagnostic prefix +//{{{ Diagnostic construction -// Construct a suitable prefix for any warning or error message. This -// should include the filename and the entity name. +// Construct a suitable diagnostic for a parsing error. This may occur +// when reading in a CDL script, a savefile, a database, or anything +// similar. +// +// A diagnostic should take the following form: +// +// [, ] [, ] : [, ] +// +// The context should be set in the Tcl interpreter. Typically it +// will be a filename. +// +// In practice generating the line number is not really feasible at +// present, the Tcl interpreter does not keep track of sufficient +// information. At least, not in the public data structures, there is +// a termOffset field in the internal data structures which might +// be used to do the right thing. I do not want to start relying +// on Tcl internals just yet, or add support to the Tcl core for +// keeping track of line numbers. // -// Obviously a line number would be rather useful as well, but this is not -// very easy because of the way Tcl interpreters work. +// For many data files there will the concept of a current node, +// e.g. an option whose properties or savefile information are +// being processed. The CdlInterpreter class keeps track of the +// current node, so if it is defined then the node's class and +// name can be part of the message. This happens automatically, +// no effort is required on the part of calling code. +// +// There may also be additional information, for example +// identifying the specific property where the error was detected. +// This is handled by an extra argument. +// +// The classification is likely to be something like "warning", +// "error", or "internal error". It is controlled by the calling +// code, but typically it is provided by calling via report_warning() +// etc. +// +// The message should identify the actual error. It should be +// a proper sentence, i.e. begin with a capital error and end with +// a full stop, unless the last word is an identifier or filename +// or something similarly special in which case the trailing +// dot will be discarded. The message should not end with a +// newline character, and the result string will not end with one +// either. That is left to higher level code. std::string -CdlParse::get_diagnostic_prefix(CdlInterpreter interp) +CdlParse::construct_diagnostic(CdlInterpreter interp, std::string classification, std::string sub_id, std::string message) { - std::string filename = interp->get_filename(); - CdlNode current_node = interp->get_node(); + CYG_REPORT_FUNCNAME("CdlParse::construct_diagnostic"); + CYG_PRECONDITION_CLASSC(interp); + + std::string context = interp->get_context(); + CdlNode current_node = interp->get_node(); - std::string result = ("" != filename) ? filename : ""; + std::string result; + if ("" == context) { + result = ""; + } else { + result = context; + } if (0 != current_node) { result += ", " + current_node->get_class_name() + " " + current_node->get_name(); } - result += "\n "; + if ("" != sub_id) { + result += ", " + sub_id; + } + result += ": " + classification; + + // Now it is time to start worrying about layout, indenting + // subsequent lines, and so on. + int index = result.length(); + int message_len = message.length(); + int message_index; + bool indent_needed = false; + + // Find out how many characters there are in the message up to the first newline + for (message_index = 0; (message_index < message_len) && ('\n' != message[message_index]); message_index++) { + ; + } + + // Should the message start on the next line, suitably indented? + // This depends in part on whether or not there was a classification. + if ("" == classification) { + // The current result ends with a colon and a space. + if ((index + message_index) <= 72) { + // The first line of the message can still fit. No need to do anything. + } else { + // Start indenting immediately, do not add anything else to the current line. + indent_needed = true; + } + } else { + // We may want a comma and a space after the classification + if ((index + 2 + message_index) <= 72) { + result += ", "; + } else { + indent_needed = true; + } + } + + // Now we can process the message one character at a time, adding + // newlines and indentation just in time. + for (message_index = 0; message_index < message_len; message_index++) { + if (indent_needed) { + result += "\n "; + indent_needed = false; + } + + if ('\n' == message[message_index]) { + indent_needed = true; + } else { + result += message[message_index]; + } + } + + CYG_REPORT_RETURN(); return result; } @@ -448,47 +547,76 @@ CdlParse::get_error_count(CdlInterpreter //}}} //{{{ Error and warning reporting -// Report an error or warning. This involves adding a suitable prefix -// and invoking the reporting callback currently associated with the -// interpreter. For errors it is also necessary to increment the error -// counter so that later count can detect the number of errors that -// have occurred. +// Report errors and warnings. These will be called during parsing +// operations, both of CDL and similar data scripts and for savefiles. +// The parsing involves running a Tcl interpreter extended with the +// appropriate set of commands. Typically the call graph will look +// something like this: +// +// libcdl C++ code such as load_package() +// libcdl CdlInterpreter::eval() +// Tcl interpreter +// libcdl parsing code +// report_error() +// +// If the Tcl script is invalid then parsing errors may get reported +// at the higher level code as well. // -// The error callback is allowed to raise a CdlParseException. This should -// not be caught here. Instead this exception is caught in every parse -// routine, before it can go back through the Tcl interpreter. +// There are two classes of diagnostic: errors and warnings. +// Additional levels may be added in future, but there does not seem +// to be an urgent need for them. Client code should provide callback +// functions so that the messages can be displayed to the user, and +// these callbacks will be registered with the current CdlInterpreter. // -// FIXME: cope with prefixing multiline error messages. +// If no error callback is defined then a ParseException will be +// raised instead, and the rest of the current script will not be +// processed. Alternatively the error callback itself can raise a +// ParseException. Care is taken to ensure that the exception does not +// go straight through the Tcl interpreter, since that would prevent +// the Tcl code from cleaning up appropriately. If no exception is +// raised then the library keeps track of the number of errors, and +// this information is accessible once the script has been fully +// processed. This allows multiple errors to be reported in a single +// run. +// +// If no warning callback is provided then warnings are ignored. void -CdlParse::report_error(CdlInterpreter interp, std::string message) +CdlParse::report_error(CdlInterpreter interp, std::string sub_id, std::string message) + throw(CdlParseException, std::bad_alloc) { CYG_REPORT_FUNCNAME("CdlParse::report_error"); CYG_REPORT_FUNCARG1("interp %p", interp); CYG_PRECONDITION_CLASSC(interp); incr_error_count(interp); - - message = get_diagnostic_prefix(interp) + message; + std::string full_message = construct_diagnostic(interp, "error", sub_id, message); + + // Now, either invoke the callback if it is provided, or throw the exception. CdlDiagnosticFnPtr fn = interp->get_error_fn_ptr(); - CYG_ASSERT(0 != fn, "during parsing an interpreter should have an associated error reporting function"); - (*fn)(message); - + if (0 == fn) { + throw CdlParseException(full_message); + } else { + (*fn)(full_message); + } + CYG_REPORT_RETURN(); } void -CdlParse::report_warning(CdlInterpreter interp, std::string message) +CdlParse::report_warning(CdlInterpreter interp, std::string sub_id, std::string message) { CYG_REPORT_FUNCNAME("CdlParse::report_warning"); CYG_REPORT_FUNCARG1("interp %p", interp); CYG_PRECONDITION_CLASSC(interp); - - message = get_diagnostic_prefix(interp) + message; + + // If there is no warning callback, do nothing. This is really a + // bug in the calling application. CdlDiagnosticFnPtr fn = interp->get_warning_fn_ptr(); if (0 != fn) { - (*fn)(message); + std::string full_message = construct_diagnostic(interp, "warning", sub_id, message); + (*fn)(full_message); } CYG_REPORT_RETURN(); @@ -512,8 +640,8 @@ CdlParse::unknown_command(CdlInterpreter CYG_REPORT_FUNCARG3XV(interp, argc, argv); CYG_PRECONDITIONC(2 <= argc); CYG_PRECONDITION_CLASSC(interp); - - report_error(interp, std::string("Unknown command `") + argv[1] + "'."); + + report_error(interp, "", std::string("Unknown command `") + argv[1] + "'."); CYG_UNUSED_PARAM(int, argc); return TCL_OK; @@ -527,49 +655,61 @@ CdlParse::unknown_command(CdlInterpreter // ---------------------------------------------------------------------------- // Utilities related to parsing properties, rather than more general parsing. -// Provide a prefix that matches the current property. -std::string -CdlParse::get_property_prefix(char* argv0) -{ - CYG_REPORT_FUNCNAME("CdlParse::get_property_prefix"); - - std::string result = std::string("Property " ) + CdlParse::get_tcl_cmd_name(argv0) + ", "; - - CYG_REPORT_RETURN(); - return result; -} - -std::string -CdlParse::get_property_prefix(CdlProperty prop) -{ - CYG_REPORT_FUNCNAME("CdlParse::get_property_prefix"); - - std::string result = std::string("Property "); - const std::vector& argv = prop->get_argv(); - result = result + argv[0] + ", "; - - CYG_REPORT_RETURN(); - return result; -} - // A variant of report_parse_error() which also adds the property prefix. void -CdlParse::report_property_parse_error(CdlInterpreter interp, char* argv0, std::string msg) +CdlParse::report_property_parse_error(CdlInterpreter interp, std::string argv0, std::string msg) + throw(CdlParseException, std::bad_alloc) { CYG_REPORT_FUNCNAME("CdlPase::report_property_parse_error"); - report_error(interp, get_property_prefix(argv0) + msg); + incr_error_count(interp); + + std::string diag = construct_diagnostic(interp, "error", + std::string("property ") + CdlParse::get_tcl_cmd_name(argv0), + msg); + + // Now, either invoke the callback if it is provided, or throw the exception. + CdlDiagnosticFnPtr fn = interp->get_error_fn_ptr(); + if (0 == fn) { + throw CdlParseException(diag); + } else { + (*fn)(diag); + } CYG_REPORT_RETURN(); } void CdlParse::report_property_parse_error(CdlInterpreter interp, CdlProperty prop, std::string msg) + throw(CdlParseException, std::bad_alloc) { CYG_REPORT_FUNCNAME("CdlParse::report_property_parse_error"); + report_property_parse_error(interp, (prop->get_argv())[0], msg); + CYG_REPORT_RETURN(); +} - report_error(interp, get_property_prefix(prop) + msg); +// Repeat for warnings +void +CdlParse::report_property_parse_warning(CdlInterpreter interp, std::string argv0, std::string msg) +{ + CYG_REPORT_FUNCNAME("CdlPase::report_property_parse_warning"); + CdlDiagnosticFnPtr fn = interp->get_error_fn_ptr(); + if (0 != fn) { + std::string diag = construct_diagnostic(interp, "error", + std::string("property ") + CdlParse::get_tcl_cmd_name(argv0), + msg); + (*fn)(diag); + } + + CYG_REPORT_RETURN(); +} + +void +CdlParse::report_property_parse_warning(CdlInterpreter interp, CdlProperty prop, std::string msg) +{ + CYG_REPORT_FUNCNAME("CdlParse::report_property_parse_warning"); + report_property_parse_warning(interp, (prop->get_argv())[0], msg); CYG_REPORT_RETURN(); } @@ -604,7 +744,7 @@ CdlParse::parse_minimal_property(CdlInte int data_index = CdlParse::parse_options(interp, property_string + argv[0], options_desc, argc, argv, 1, options); if (data_index < argc) { - CdlParse::report_property_parse_error(interp, argv[0], std::string("Unexpected data ") + argv[data_index]); + CdlParse::report_property_parse_error(interp, argv[0], std::string("Unexpected data `") + argv[data_index] + "'."); } else { // The command is valid, turn it into a property. @@ -646,7 +786,7 @@ CdlParse::parse_string_property(CdlInter int data_index = CdlParse::parse_options(interp, property_string + argv[0], options_desc, argc, argv, 1, options); if (data_index == argc) { - CdlParse::report_property_parse_error(interp, argv[0], "missing argument."); + CdlParse::report_property_parse_error(interp, argv[0], "Missing argument."); } else if ((data_index + 1) < argc) { CdlParse::report_property_parse_error(interp, argv[0], std::string("Too many arguments, expecting just one.")); } else { @@ -686,12 +826,12 @@ CdlParse::parse_tclcode_property(CdlInte int data_index = CdlParse::parse_options(interp, property_string + argv[0], options_desc, argc, argv, 1, options); if (data_index == argc) { - CdlParse::report_property_parse_error(interp, argv[0], "missing Tcl code."); + CdlParse::report_property_parse_error(interp, argv[0], "Missing Tcl code."); } else if ((data_index + 1) < argc) { CdlParse::report_property_parse_error(interp, argv[0], std::string("Invalid number of arguments.\n") + - " Expecting one argument, a Tcl code fragment."); + "Expecting one argument, a Tcl code fragment."); } else if (!Tcl_CommandComplete(argv[data_index])) { - CdlParse::report_property_parse_error(interp, argv[0], "incomplete Tcl code fragment."); + CdlParse::report_property_parse_error(interp, argv[0], "Incomplete Tcl code fragment."); } else { CdlNode current_node = interp->get_node(); @@ -718,7 +858,8 @@ CdlParse::parse_tclcode_property(CdlInte int CdlParse::parse_stringvector_property(CdlInterpreter interp, int argc, char** argv, std::string name, - char** options_desc, void (*final_parser)(CdlInterpreter, CdlProperty_StringVector)) + char** options_desc, void (*final_parser)(CdlInterpreter, CdlProperty_StringVector), + bool allow_empty) { CYG_REPORT_FUNCNAME("parse_tclcode_property"); CYG_PRECONDITION_CLASSC(interp); @@ -728,8 +869,8 @@ CdlParse::parse_stringvector_property(Cd std::vector > options; int data_index = CdlParse::parse_options(interp, property_string + argv[0], options_desc, argc, argv, 1, options); - if (data_index == argc) { - CdlParse::report_property_parse_error(interp, argv[0], "missing arguments."); + if (!allow_empty && (data_index == argc)) { + CdlParse::report_property_parse_error(interp, argv[0], "Missing arguments."); } else { // Creating the property requires a vector of strings. @@ -774,9 +915,9 @@ CdlParse::parse_reference_property(CdlIn int data_index = CdlParse::parse_options(interp, property_string + argv[0], options_desc, argc, argv, 1, options); if (data_index == argc) { - CdlParse::report_property_parse_error(interp, argv[0], "missing argument."); + CdlParse::report_property_parse_error(interp, argv[0], "Missing argument."); } else if ((data_index + 1) < argc) { - CdlParse::report_property_parse_error(interp, argv[0], "too many arguments, expecting just one."); + CdlParse::report_property_parse_error(interp, argv[0], "Too many arguments, expecting just one."); } else { std::string refname = argv[data_index]; if (!Cdl::is_valid_cdl_name(refname)) { @@ -822,7 +963,7 @@ CdlParse::parse_expression_property(CdlI std::string all_args = CdlParse::concatenate_argv(argc, argv, data_index); if ("" == all_args) { - CdlParse::report_property_parse_error(interp, argv[0], "missing expression data."); + CdlParse::report_property_parse_error(interp, argv[0], "Missing expression data."); } else { // The CdlExpression class has its own parsing routine. This @@ -881,7 +1022,7 @@ CdlParse::parse_listexpression_property( std::string all_args = CdlParse::concatenate_argv(argc, argv, data_index); if ("" == all_args) { - CdlParse::report_property_parse_error(interp, argv[0], "missing list expression data."); + CdlParse::report_property_parse_error(interp, argv[0], "Missing list expression data."); } else { try { @@ -935,7 +1076,7 @@ CdlParse::parse_goalexpression_property( std::string all_args = CdlParse::concatenate_argv(argc, argv, data_index); if ("" == all_args) { - CdlParse::report_property_parse_error(interp, argv[0], "missing goal expression data."); + CdlParse::report_property_parse_error(interp, argv[0], "Missing goal expression data."); } else { try { diff --git a/host/libcdl/property.cxx b/host/libcdl/property.cxx --- a/host/libcdl/property.cxx +++ b/host/libcdl/property.cxx @@ -449,7 +449,6 @@ CdlProperty_StringVectorBody::CdlPropert { CYG_REPORT_FUNCNAME("CdlProperty_StringVector:: constructor"); CYG_REPORT_FUNCARG1("this %p", this); - CYG_PRECONDITION(0 < data_arg.size(), "there should be some data"); data = data_arg; cdlproperty_stringvectorbody_cookie = CdlProperty_StringVectorBody_Magic; @@ -479,8 +478,14 @@ CdlProperty_StringVectorBody::get_first_ CYG_REPORT_FUNCARG1("this %p", this); CYG_PRECONDITION_THISC(); + std::string result; + if (0 == data.size()) { + result = ""; + } else { + result = data[0]; + } CYG_REPORT_RETURN(); - return data[0]; + return result; } unsigned int diff --git a/host/libcdl/value.cxx b/host/libcdl/value.cxx --- a/host/libcdl/value.cxx +++ b/host/libcdl/value.cxx @@ -3402,28 +3402,28 @@ CdlValuableBody::check_properties(CdlInt // This could prove useful if there are a sensible number // of library check_proc's. if (count_properties(CdlPropertyId_Flavor) > 1) { - CdlParse::report_error(interp, "There should be at most one flavor property."); + CdlParse::report_error(interp, "", "There should be at most one flavor property."); } if (count_properties(CdlPropertyId_EntryProc) > 1) { - CdlParse::report_error(interp, "There should be at most one entry_proc property."); + CdlParse::report_error(interp, "", "There should be at most one entry_proc property."); } if (count_properties(CdlPropertyId_CheckProc) > 1) { - CdlParse::report_error(interp, "There should be at most one check_proc property."); + CdlParse::report_error(interp, "", "There should be at most one check_proc property."); } if (count_properties(CdlPropertyId_DefaultValue) > 1) { - CdlParse::report_error(interp, "There should be at most one default_value property."); + CdlParse::report_error(interp, "", "There should be at most one default_value property."); } if (count_properties(CdlPropertyId_LegalValues) > 1) { - CdlParse::report_error(interp, "There should be at most one legal_values property."); + CdlParse::report_error(interp, "", "There should be at most one legal_values property."); } if (count_properties(CdlPropertyId_Dialog) > 1) { - CdlParse::report_error(interp, "There should be at most one dialog property."); + CdlParse::report_error(interp, "", "There should be at most one dialog property."); } if (count_properties(CdlPropertyId_Wizard) > 1) { - CdlParse::report_error(interp, "There should be at most one wizard property."); + CdlParse::report_error(interp, "", "There should be at most one wizard property."); } if (count_properties(CdlPropertyId_Calculated) > 1) { - CdlParse::report_error(interp, "There should be at most one calculated property."); + CdlParse::report_error(interp, "", "There should be at most one calculated property."); } // If there is a flavor property, update the flavor in the base class @@ -3435,7 +3435,7 @@ CdlValuableBody::check_properties(CdlInt CdlValueFlavor flavor; // The property parsing code should have caught any problems already. if (!Cdl::string_to_flavor(flavor_string, flavor)) { - CdlParse::report_error(interp, "Invalid flavor " + flavor_string); + CdlParse::report_error(interp, "", "Invalid flavor " + flavor_string); } else { value.set_flavor(flavor); } @@ -3456,13 +3456,13 @@ CdlValuableBody::check_properties(CdlInt // that the current value is legal. if (CdlValueFlavor_Bool == get_flavor()) { if (has_property(CdlPropertyId_LegalValues)) { - CdlParse::report_error(interp, "The \"legal_values\" property is not applicable to boolean entities."); + CdlParse::report_error(interp, "", "The \"legal_values\" property is not applicable to boolean entities."); } } // default_value and calculated are mutually exclusive if (has_property(CdlPropertyId_Calculated) && has_property(CdlPropertyId_DefaultValue)) { - CdlParse::report_error(interp, "The properties \"default_value\" and \"calculated\" cannot be used together."); + CdlParse::report_error(interp, "", "The properties \"default_value\" and \"calculated\" cannot be used together."); } #if 0 @@ -3471,7 +3471,7 @@ CdlValuableBody::check_properties(CdlInt // a text entry widget will be used and an entry_proc may well be // applicable. if (has_property(CdlPropertyId_Dialog) && has_property(CdlPropertyId_EntryProc)) { - CdlParse::report_error(interp, "The properties \"dialog\" and \"entry_proc\" cannot be used together."); + CdlParse::report_error(interp, "", "The properties \"dialog\" and \"entry_proc\" cannot be used together."); } #endif @@ -3943,7 +3943,7 @@ CdlValuableBody::savefile_value_source_c } else { msg += "The specified value source is not valid."; } - CdlParse::report_error(interp, msg); + CdlParse::report_error(interp, "", msg); } else { valuable->set_source(transaction, source); } @@ -4012,9 +4012,9 @@ CdlValuableBody::savefile_xxx_value_comm msg = std::string("Invalid value command for ") + valuable->get_class_name() + " " + valuable->get_name() + "\n" + msg; if (error) { - CdlParse::report_error(interp, msg); - }else { - CdlParse::report_warning(interp, msg); + CdlParse::report_error(interp, "", msg); + } else { + CdlParse::report_warning(interp, "", msg); } } diff --git a/host/libcdl/wizard.cxx b/host/libcdl/wizard.cxx --- a/host/libcdl/wizard.cxx +++ b/host/libcdl/wizard.cxx @@ -116,16 +116,14 @@ CdlWizardBody::parse_wizard(CdlInterpret CYG_PRECONDITION_CLASSC(interp); int result = TCL_OK; - const char* diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); + std::string diag_argv0 = CdlParse::get_tcl_cmd_name(argv[0]); CdlLoadable loadable = interp->get_loadable(); CdlContainer parent = interp->get_container(); CdlToplevel toplevel = interp->get_toplevel(); - std::string filename = interp->get_filename(); CYG_ASSERT_CLASSC(loadable); // There should always be a loadable during parsing CYG_ASSERT_CLASSC(parent); CYG_ASSERT_CLASSC(toplevel); - CYG_ASSERTC("" != filename); // The new wizard should be created and added to the loadable // early on. If there is a parsing error it will get cleaned up @@ -138,13 +136,13 @@ CdlWizardBody::parse_wizard(CdlInterpret // Currently there are no command-line options. This may change in future. if (3 != argc) { - CdlParse::report_error(interp, std::string("Incorrect number of arguments to ") + diag_argv0 + - "\n Expecting name and properties list."); + CdlParse::report_error(interp, "", std::string("Incorrect number of arguments to `") + diag_argv0 + + "'\nExpecting name and properties list."); } else if (!Tcl_CommandComplete(argv[2])) { - CdlParse::report_error(interp, std::string("Invalid property list for cdl_wizard ") + argv[1]); + CdlParse::report_error(interp, "", std::string("Invalid property list for cdl_wizard `") + argv[1]+ "'."); } else if (0 != toplevel->lookup(argv[1])) { - CdlParse::report_error(interp, std::string("Wizard ") + argv[1] + " cannot be loaded.\n" + - " The name is already in use."); + CdlParse::report_error(interp, "", std::string("Wizard `") + argv[1] + + "' cannot be loaded.\nThe name is already in use."); } else { new_wizard = new CdlWizardBody(argv[1]); toplevel->add_node(loadable, parent, new_wizard); @@ -199,19 +197,19 @@ CdlWizardBody::parse_wizard(CdlInterpret // are compulsory, and there should be at least one screen // definition. if (new_wizard->count_properties(CdlPropertyId_InitProc) > 1) { - CdlParse::report_error(interp, "A wizard should have only one `init_proc' property."); + CdlParse::report_error(interp, "", "A wizard should have only one `init_proc' property."); } if (new_wizard->count_properties(CdlPropertyId_DecorationProc) > 1) { - CdlParse::report_error(interp, "A wizard should have only one `decoration_proc' property."); + CdlParse::report_error(interp, "", "A wizard should have only one `decoration_proc' property."); } if (new_wizard->count_properties(CdlPropertyId_ConfirmProc) != 1) { - CdlParse::report_error(interp, "A wizard should have one `confirm_proc' property."); + CdlParse::report_error(interp, "", "A wizard should have one `confirm_proc' property."); } if (new_wizard->count_properties(CdlPropertyId_CancelProc) != 1) { - CdlParse::report_error(interp, "A wizard should have one `cancel_proc' property."); + CdlParse::report_error(interp, "", "A wizard should have one `cancel_proc' property."); } if (new_wizard->count_properties(CdlPropertyId_Screen) < 1) { - CdlParse::report_error(interp, "A wizard should have at least one `screen' property."); + CdlParse::report_error(interp, "", "A wizard should have at least one `screen' property."); } // It is necessary to check that all the screen properties have unique numbers @@ -236,7 +234,7 @@ CdlWizardBody::parse_wizard(CdlInterpret if (num1 == num2) { std::string tmp = ""; Cdl::integer_to_string(num1, tmp); - CdlParse::report_error(interp, "Duplicate definition of screen " + tmp); + CdlParse::report_error(interp, "", "Duplicate definition of screen `" + tmp + "'."); break; } } diff --git a/host/tools/Utils/ChangeLog b/host/tools/Utils/ChangeLog --- a/host/tools/Utils/ChangeLog +++ b/host/tools/Utils/ChangeLog @@ -1,3 +1,25 @@ +2000-04-13 Simon FitzMaurice + * common\eCosSerial.cpp + common\eCosSocket.cpp + common\eCosTrace.cpp + + Tidy up timestamp output. + +2000-04-11 Simon FitzMaurice + * common\Collections.cpp + common\Collections.h + common\Properties.cpp + common\Properties.h + common\eCosStd.h + common\eCosThreadUtils.cpp + common\eCosThreadUtils.h + common\eCosTrace.cpp + common\eCosTrace.h + common\wcharunix.h + win32\CTUtils.cpp + + General tidy-up. + 2000-03-13 Simon FitzMaurice * common\Collections.cpp common\Properties.cpp diff --git a/host/tools/Utils/common/Collections.cpp b/host/tools/Utils/common/Collections.cpp --- a/host/tools/Utils/common/Collections.cpp +++ b/host/tools/Utils/common/Collections.cpp @@ -32,6 +32,16 @@ void String::Format (LPCTSTR const pszF va_end(args); } +String String::SFormat (LPCTSTR const pszFormat,...) +{ + String s; + va_list args; + va_start(args, pszFormat); + s.vFormat(pszFormat,args); + va_end(args); + return s; +} + void String::vFormat(LPCTSTR pszFormat, va_list marker) { for(int nLength=100;nLength;) { @@ -40,7 +50,7 @@ void String::vFormat(LPCTSTR pszFormat, if(-1==n){ nLength*=2; // NT behavior } else if (n0) { + c++; } - String strTok; - if(bObserveStrings){ - bool bInString=false; - do{ - if(*c==_TCHAR('\\') && c[1]){ - strTok+=c[1]; - c++; - } else if(*c==_TCHAR('"')){ - bInString ^= 1; - } else if (!bInString && IsSep(*c)) { - break; - } else { - strTok+=*c; - } - } while (*++c); - } else { - do { - if(IsSep(*c)) { - break; - } else { - strTok+=*c; - } - } while (*++c); + if(*c){ + String strTok; + if(bObserveStrings){ + bool bInString=false; + do{ + if(*c==_TCHAR('\\') && c[1]){ + strTok+=c[1]; + c++; + } else if(*c==_TCHAR('"')){ + bInString ^= 1; + } else if (!bInString && IsSep(*c)) { + break; + } else { + strTok+=*c; + } + } while (*++c); + } else { + do { + if(IsSep(*c)) { + break; + } else { + strTok+=*c; + } + } while (*++c); + } + ar.push_back(strTok); } - ar.push_back(strTok); } return ar.size(); } char * String::GetCString() const - { - char *psz=new char[1+GetLength()]; +{ + char *psz=new char[1+size()]; #ifdef _UNICODE - WideCharToMultiByte(CP_ACP, 0, c_str(), -1, psz, 1+GetLength(), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, c_str(), -1, psz, 1+size(), NULL, NULL); #else - strcpy(psz,c_str()); + strcpy(psz,c_str()); #endif - return psz; + return psz; +} + +void String::Replace(LPCTSTR psz1, LPCTSTR psz2, bool bObserveEscapes) +{ + for(unsigned int nOffset=0;nOffsetpsz && _TCHAR('\\')==pc[-1]){ + // Substitution protected by escape + nOffset=(pc-psz)+_tcslen(psz1); + } else { + String strNew(psz,pc-psz); // before the substitution + strNew+=psz2; // substitution text + pc+=_tcslen(psz1); // past the substituted text + strNew+=pc; // after the substitution + string::operator=(strNew); + nOffset=(pc-psz)+_tcslen(psz2); + } + } else { + break; + } } - - +} diff --git a/host/tools/Utils/common/Collections.h b/host/tools/Utils/common/Collections.h --- a/host/tools/Utils/common/Collections.h +++ b/host/tools/Utils/common/Collections.h @@ -22,12 +22,20 @@ // ---------------------------------------------------------------------------- // //####COPYRIGHTEND#### + +// ---------------------------------------------------------------------------- +// This file defines some useful collection classes: +// String (a slightly extended string class, based on TCHAR) +// StringArray (array of the above) +// PtrArray (array of pointers) +// IntArray (array of ints) +// Buffer (untyped memory) +// ---------------------------------------------------------------------------- + #ifndef _ECOS_COLLECTIONS_H #define _ECOS_COLLECTIONS_H #ifdef _MSC_VER - //#ifdef _AFXDLL - //#include "stdafx.h" - //#endif + // Some standard warning-suppressions to avoid STL header verbosity: #pragma warning (push) #pragma warning(disable:4018) // signed/unsigned mismatch #pragma warning(disable:4097) // typedef-name 'string' used as synonym for class-name @@ -50,12 +58,22 @@ #include "eCosStd.h" class String; + +// An array of strings: typedef std::vector StringArray; +// An array of integers: +typedef std::vector IntArray; + +// Some extensions to the STL string class. +// The semantics of the like-named functions is as for the MFC class CString. +// The instantiation of the string class is based on TCHAR (the typedef is just below) +// which of course will be a wide character when building UNICODE on Windows. typedef std::basic_string string; - class String : public string { public: + void Replace (LPCTSTR psz1,LPCTSTR psz2,bool bObserveEscapes=false); + // Standard ctors String() : string(),m_pszBuf(0){} String(const String& rhs) : string(rhs),m_pszBuf(0){} String(const String& rhs, size_type pos, size_type n) : string(rhs,pos,n),m_pszBuf(0){} @@ -64,35 +82,52 @@ public: String(size_type n, TCHAR c) : string(n,c),m_pszBuf(0){} String(const_iterator first, const_iterator last) : string(first,last),m_pszBuf(0){} virtual ~String() { delete [] m_pszBuf; } + + // Comparators bool operator==(const String& str) const {return 0==compare(str); } bool operator==(const LPCTSTR psz) const {return 0==compare(psz); } + // Implicit conversion to LPCTSTR operator LPCTSTR () const { return c_str(); } - unsigned int GetLength() const { return size(); } + + // Access to the buffer LPTSTR GetBuffer (unsigned int nLength=0); + void ReleaseBuffer(); + + // Format the contents of a string, as printf would do it: void Format(LPCTSTR pszFormat,...); + static String SFormat(LPCTSTR pszFormat,...); + + // Tokenize (split into pieces at separator cSep). + // The bObserveStrings argument controls whether double quotes can be used to group words int Chop(StringArray &ar,TCHAR cSep=_TCHAR(' '),bool bObserveStrings=true) const; - void SetLength(unsigned int nLen) { resize(nLen); } - void ReleaseBuffer(); + + // UNICODE-ANSI conversions: char * GetCString () const; static String CStrToUnicodeStr(const char *psz); + void vFormat(LPCTSTR pszFormat, va_list marker); + protected: + TCHAR *m_pszBuf; int m_nBufferLength; }; +// Use this class to allocate chunks of untyped memory without needing to worry about memory leaks: class Buffer { - unsigned int m_nSize; - void *pData; public: Buffer(unsigned int nSize) : m_nSize(nSize), pData(malloc(nSize)) {} ~Buffer() { free(pData); } void *Data() { return pData; } void Resize(int nSize) { pData=realloc(pData,nSize); m_nSize=nSize; } unsigned int Size() const { return m_nSize; } +protected: + unsigned int m_nSize; + void *pData; }; +// An array of untyped pointers: typedef std::vector PtrArray; #ifdef _MSC_VER diff --git a/host/tools/Utils/common/Properties.cpp b/host/tools/Utils/common/Properties.cpp --- a/host/tools/Utils/common/Properties.cpp +++ b/host/tools/Utils/common/Properties.cpp @@ -26,46 +26,22 @@ // ////////////////////////////////////////////////////////////////////// #include "Properties.h" -#if defined (_AFXDLL) || defined(_AFXEXT) - // MFC - //#ifdef _DEBUG - //#undef THIS_FILE - //static char THIS_FILE[]=__FILE__; - //#define new DEBUG_NEW - //#endif - #include - #include - #include - #include -#endif - +#include "eCosTrace.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// -CProperties::CProperties(LPCTSTR pszKey,void *hKey): - m_strName(pszKey), - m_hKey(hKey) +CProperties::CProperties() { } CProperties::~CProperties() { - RemoveAll(); -} - -void CProperties::RemoveAll() -{ - for(int i=ar.size()-1;i>=0;--i){ - delete (CProperties::CProperty *)ar[i]; - } - ar.clear(); } #ifdef _WIN32 -bool CProperties::LoadFromRegistry(HKEY hTopKey,LPCTSTR szRegKey,LPCTSTR pszPrefix) +bool CProperties::LoadFromRegistry(HKEY hTopKey,LPCTSTR szRegKey) { - int nPrefixlen=_tcslen(pszPrefix); HKEY hKey; LONG l=RegOpenKeyEx (hTopKey, szRegKey, 0L, KEY_QUERY_VALUE, &hKey); bool rc=(ERROR_SUCCESS==l); @@ -78,67 +54,63 @@ bool CProperties::LoadFromRegistry(HKEY char *Data=new char[dwMaxDatalen]; DWORD dwDatalen=dwMaxDatalen; for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumValue(hKey, dwIndex, szName, &dwSizeName, NULL, &dwType, (LPBYTE)Data, &dwDatalen);dwIndex++){ - if(0!=_tcsncmp(pszPrefix,szName,nPrefixlen)){ - continue; - } - CProperties::CProperty *p=Lookup(szName+nPrefixlen); + CProperties::CProperty *p=Lookup(szName); if(p){ switch(p->Type){ - case CProperty::Integer: - if(REG_DWORD==dwType){ - p->SetValue(*(int *)Data); - } else { - //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); - rc=false; - } - break; - case CProperty::Bool: - if(REG_DWORD==dwType){ - p->SetValue((bool)0!=*(int *)Data); - } else { - //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); - rc=false; - } - break; - case CProperty::Char: - if(REG_DWORD==dwType){ - p->SetValue(*(char *)Data); - } else { - //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); - rc=false; - } - break; - case CProperty::Short: - if(REG_DWORD==dwType){ - p->SetValue(*(short *)Data); - } else { - //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); - rc=false; - } - break; - case CProperty::Float: - case CProperty::Double: - case CProperty::szString: - case CProperty::GPString: - if(REG_SZ==dwType){ - rc&=p->SetValue((LPCTSTR)Data); - } else { - //TRACE(_T("Type mismatch - %s: expected REG_SZ, got %d\n"),(LPCTSTR)p->strName,dwType); - rc=false; - } - break; - case CProperty::Void: - if(REG_BINARY==dwType){ - memcpy(p->pData,Data,min(dwDatalen,p->nLength)); - } else { - //TRACE(_T("Type mismatch - %s: expected REG_BINARY, got %d\n"),(LPCTSTR)p->strName,dwType); - rc=false; - } - break; + case CProperty::Integer: + if(REG_DWORD==dwType){ + p->SetValue(*(int *)Data); + } else { + TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); + rc=false; + } + break; + case CProperty::Bool: + if(REG_DWORD==dwType){ + p->SetValue((bool)0!=*(int *)Data); + } else { + TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); + rc=false; + } + break; + case CProperty::Char: + if(REG_DWORD==dwType){ + p->SetValue(*(char *)Data); + } else { + TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); + rc=false; + } + break; + case CProperty::Short: + if(REG_DWORD==dwType){ + p->SetValue(*(short *)Data); + } else { + TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); + rc=false; + } + break; + case CProperty::Float: + case CProperty::Double: + case CProperty::szString: + if(REG_SZ==dwType){ + rc&=p->SetValue((LPCTSTR)Data); + } else { + TRACE(_T("Type mismatch - %s: expected REG_SZ, got %d\n"),(LPCTSTR)p->strName,dwType); + rc=false; + } + break; + case CProperty::Void: + if(REG_BINARY==dwType){ + memcpy(p->pData,Data,min(dwDatalen,p->nLength)); + } else { + TRACE(_T("Type mismatch - %s: expected REG_BINARY, got %d\n"),(LPCTSTR)p->strName,dwType); + rc=false; + } + break; } } else { - //TRACE(_T("CProperties::LoadFromRegistry - unrecognized value %s\\%s\n"),szRegKey,szName); + TRACE(_T("CProperties::LoadFromRegistry - unrecognized value %s in key %s\n"),szName,szRegKey); rc=false; } dwSizeName=sizeof szName; @@ -149,13 +121,13 @@ bool CProperties::LoadFromRegistry(HKEY } RegCloseKey(hKey); } else { - //TRACE(_T("Failed to open %s\n"),szRegKey); + TRACE(_T("Failed to open %s\n"),szRegKey); } return rc; } -bool CProperties::SaveToRegistry(HKEY hTopKey,LPCTSTR szRegKey,LPCTSTR pszPrefix) const +bool CProperties::SaveToRegistry(HKEY hTopKey,LPCTSTR szRegKey) const { HKEY hKey; CreateKey(szRegKey); @@ -169,38 +141,35 @@ bool CProperties::SaveToRegistry(HKEY hT // strValue and dw *must* be in scope for RegSetValueEx below. DWORD dw; String strValue; - CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; - switch(p->Type){ + const CProperty &p=ar[i]; + switch(p.Type){ case CProperties::CProperty::Integer: case CProperties::CProperty::Bool: case CProperties::CProperty::Char: case CProperties::CProperty::Short: dwType=REG_DWORD; dwDatalen=sizeof(DWORD); - dw=p->GetValue(); + dw=p.GetValue(); Data=(BYTE *)&dw; break; case CProperties::CProperty::Float: case CProperties::CProperty::Double: case CProperties::CProperty::szString: - case CProperties::CProperty::GPString: - strValue=p->GetStringValue(); + strValue=p.GetStringValue(); Data=(BYTE *)(LPCTSTR)strValue; dwType=REG_SZ; - dwDatalen=(1+strValue.GetLength())*sizeof(_TCHAR); + dwDatalen=(1+strValue.size())*sizeof(_TCHAR); break; case CProperties::CProperty::Void: - Data=(BYTE *)p->pData; + Data=(BYTE *)p.pData; dwType=REG_BINARY; - dwDatalen=p->nLength; + dwDatalen=p.nLength; break; default: assert(false); break; } - String strName(pszPrefix); - strName+=p->strName; - rc&=(ERROR_SUCCESS==RegSetValueEx(hKey,strName,0,dwType,Data,dwDatalen)); + rc&=(ERROR_SUCCESS==RegSetValueEx(hKey,p.strName,0,dwType,Data,dwDatalen)); } } RegCloseKey(hKey); @@ -210,50 +179,49 @@ bool CProperties::SaveToRegistry(HKEY hT // Create all keys down to the one specified bool CProperties::CreateKey(LPCTSTR pszKey,HKEY hKey/*=HKEY_CURRENT_USER*/) { - bool rc=true; - LPCTSTR pcStart=pszKey; - LPCTSTR pcEnd; - do { - HKEY hKey2; - pcEnd=_tcschr(pcStart,_TCHAR('\\')); - if(NULL==pcEnd){ - pcEnd=pcStart+_tcslen(pcStart); - } - String strKey(pcStart,pcEnd-pcStart); - if(ERROR_SUCCESS!=RegCreateKeyEx(hKey, // handle to an open key - strKey, // address of subkey name - 0, // reserved - 0, // address of class string - REG_OPTION_NON_VOLATILE, // special options flag - KEY_ALL_ACCESS, // desired security access - NULL, - // address of key security structure - &hKey2, // address of buffer for opened handle - NULL// address of disposition value buffer); - )){ - rc=false; - break; - } - RegCloseKey(hKey); - hKey=hKey2; - pcStart=pcEnd+1; - } while (_TCHAR('\0')!=*pcEnd); + bool rc=true; + LPCTSTR pcStart=pszKey; + LPCTSTR pcEnd; + do { + HKEY hKey2; + pcEnd=_tcschr(pcStart,_TCHAR('\\')); + if(NULL==pcEnd){ + pcEnd=pcStart+_tcslen(pcStart); + } + String strKey(pcStart,pcEnd-pcStart); + if(ERROR_SUCCESS!=RegCreateKeyEx(hKey, // handle to an open key + strKey, // address of subkey name + 0, // reserved + 0, // address of class string + REG_OPTION_NON_VOLATILE, // special options flag + KEY_ALL_ACCESS, // desired security access + NULL, + // address of key security structure + &hKey2, // address of buffer for opened handle + NULL// address of disposition value buffer); + )){ + rc=false; + break; + } RegCloseKey(hKey); - return rc; + hKey=hKey2; + pcStart=pcEnd+1; + } while (_TCHAR('\0')!=*pcEnd); + RegCloseKey(hKey); + return rc; } #endif -bool CProperties::LoadFromCommandString(LPCTSTR psz,LPCTSTR pszPrefix/*=_T("-")*/) +bool CProperties::LoadFromCommandString(LPCTSTR psz) { bool rc=true; const TCHAR *cNext; - int nPrefixlen=_tcslen(pszPrefix); - for(LPCTSTR c=_tcsstr(psz,pszPrefix);c;c=_tcsstr(cNext,pszPrefix)){ - c+=nPrefixlen; + for(LPCTSTR c=_tcschr(psz,_TCHAR('-'));c;c=_tcschr(cNext,_TCHAR('-'))){ + c++; const TCHAR *pEq=_tcschr(c,_TCHAR('=')); if(NULL==pEq){ - //TRACE(_T("Failed to find '=' after %s\n"),c); + TRACE(_T("Failed to find '=' after %s\n"),c); rc=false; break; } @@ -277,45 +245,57 @@ bool CProperties::LoadFromCommandString( if(p){ rc&=p->SetValue(str); } else { - //TRACE(_T("Properties: unrecognized attribute %s in command string\n"),(LPCTSTR)strName); + TRACE(_T("Properties: unrecognized attribute %s in command string\n"),(LPCTSTR)strName); rc=false; } + c=cNext; } return rc; } CProperties::CProperty * CProperties::Lookup(LPCTSTR pszName) { - for(int i=ar.size()-1;i>=0;--i){ - CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; - if(p->strName==pszName){ - return p; - } + for(int i=ar.size()-1;i>=0;--i){ + CProperties::CProperty &p=ar[i]; + if(0==_tcsicmp(p.strName,pszName)){ + return &p; } - return NULL; + } + return NULL; } -String CProperties::MakeCommandString(LPCTSTR pszPrefix/*=_T("-")*/) const +String CProperties::MakeCommandString() const { String strResult; bool bFirst=true; for(int i=ar.size()-1;i>=0;--i){ String str; - CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; - switch(p->Type){ - case CProperties::CProperty::Integer: - case CProperties::CProperty::Bool: - case CProperties::CProperty::Char: - case CProperties::CProperty::Short: - str.Format(_T("%s%s=%u"),pszPrefix,(LPCTSTR)p->strName,p->GetValue()); - break; - case CProperties::CProperty::szString: - case CProperties::CProperty::GPString: - case CProperties::CProperty::Float: - case CProperties::CProperty::Double: - case CProperties::CProperty::Void: - str.Format(_T("%s%s=\"%s\""),pszPrefix,(LPCTSTR)p->strName,(LPCTSTR)p->GetStringValue()); - break; + const CProperty &p=ar[i]; + switch(p.Type){ + case CProperties::CProperty::Integer: + case CProperties::CProperty::Bool: + case CProperties::CProperty::Char: + case CProperties::CProperty::Short: + str.Format(_T("-%s=%u"),(LPCTSTR)p.strName,p.GetValue()); + break; + case CProperties::CProperty::szString: + { + // Quote the string, escaping existing quotes as necessary + str.Format(_T("-%s=\""),(LPCTSTR)p.strName); + for(LPCTSTR c=p.GetStringValue();*c;c++){ + if(_TCHAR('"')==*c){ + str+=_TCHAR('\\'); + } + str+=*c; + } + str+=_TCHAR('"'); + } + break; + case CProperties::CProperty::Float: + case CProperties::CProperty::Double: + case CProperties::CProperty::Void: + str.Format(_T("-%s=%s"),(LPCTSTR)p.GetStringValue()); + break; } if(!bFirst){ strResult+=_TCHAR(' '); @@ -328,60 +308,53 @@ String CProperties::MakeCommandString(LP bool CProperties::CreatePathToFile(LPCTSTR pszDir) { - // Create intermediate directories - #ifdef _WIN32 - const TCHAR cSep='\\'; - #else // UNIX - const TCHAR cSep='/'; - #endif - for(LPCTSTR c=_tcschr(pszDir,cSep);c;c=_tcschr(c+1,cSep)){ - #ifdef _WIN32 - if(c==pszDir+2 && _istalpha(pszDir[0]) && _TCHAR(':')==pszDir[1]){ - continue; // don't attempt to create "C:" - } - #endif - String strDir(pszDir,c-pszDir); - struct _stat buf; - if(!(0==_tstat(strDir,&buf) && (S_IFDIR&buf.st_mode))){ - // Need to create directory - bool b=(0==_tmkdir(strDir)); - //TRACE(_T("Create directory %s rc=%d\n"),(LPCTSTR)strDir,b); - if(!b){ - return false; - } - } + // Create intermediate directories +#ifdef _WIN32 + const TCHAR cSep='\\'; +#else // UNIX + const TCHAR cSep='/'; +#endif + for(LPCTSTR c=_tcschr(pszDir,cSep);c;c=_tcschr(c+1,cSep)){ +#ifdef _WIN32 + if(c==pszDir+2 && _istalpha(pszDir[0]) && _TCHAR(':')==pszDir[1]){ + continue; // don't attempt to create "C:" } - return true; +#endif + String strDir(pszDir,c-pszDir); + struct _stat buf; + if(!(0==_tstat(strDir,&buf) && (S_IFDIR&buf.st_mode))){ + // Need to create directory + bool b=(0==_tmkdir(strDir)); + TRACE(_T("Create directory %s rc=%d\n"),(LPCTSTR)strDir,b); + if(!b){ + return false; + } + } + } + return true; } -bool CProperties::SaveToFile(LPCTSTR pszFileName,LPCTSTR pszPrefix) const +bool CProperties::SaveToFile(LPCTSTR pszFileName) const { CreatePathToFile(pszFileName); - // If we have a prefix, we assume we're tagging on to an existing file - FILE *f=_tfopen(pszFileName,(_TCHAR('\0')==*pszPrefix)?_T("wt"):_T("at")); + FILE *f=_tfopen(pszFileName,_T("w") MODE_TEXT); if(f){ for(int i=ar.size()-1;i>=0;--i){ - CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; - String str(pszPrefix); - str+=p->strName; + const CProperty &p=ar[i]; + String str(p.strName); str+=_TCHAR('='); - switch(p->Type){ + switch(p.Type){ case CProperties::CProperty::Integer: case CProperties::CProperty::Bool: case CProperties::CProperty::Char: case CProperties::CProperty::Short: - { - String strN; - strN.Format(_T("%u"),p->GetValue()); - str+=strN; - } + str+=String::SFormat(_T("%u"),p.GetValue()); break; case CProperties::CProperty::Float: case CProperties::CProperty::Double: case CProperties::CProperty::szString: - case CProperties::CProperty::GPString: case CProperties::CProperty::Void: - str+=p->GetStringValue(); + str+=p.GetStringValue(); break; } str+=_TCHAR('\n'); @@ -392,36 +365,50 @@ bool CProperties::SaveToFile(LPCTSTR psz return (0!=f); } -bool CProperties::LoadFromFile(LPCTSTR pszFileName,LPCTSTR pszPrefix) +bool CProperties::LoadFromFile(LPCTSTR pszFileName) { - int nPrefixlen=_tcslen(pszPrefix); - FILE *f=_tfopen(pszFileName,_T("rt")); + FILE *f=_tfopen(pszFileName,_T("r") MODE_TEXT); bool rc=(0!=f); if(rc){ - TCHAR c[256]; - while(_fgetts(c,sizeof(c)-1,f)){ - if(_TCHAR('\0')!=c[0]){ - c[_tcslen(c)-1]=_TCHAR('\0'); // remove trailing \n - } - if((signed)_tcslen(c)>nPrefixlen && 0==_tcsncmp(c,pszPrefix,nPrefixlen)){ - TCHAR *pEq=_tcschr(c,_TCHAR('=')); - if(pEq){ - const String strName(c+nPrefixlen,pEq-c-nPrefixlen); - CProperties::CProperty *p=Lookup(strName); - if(p){ - pEq++; - rc&=p->SetValue(pEq); - } else { - //TRACE(_T("Failed to find %s\n"),(LPCTSTR)strName); - rc=false; + TCHAR buf[4096]; + int nLine=0; + String str; + while(_fgetts(buf,sizeof(buf)-1,f)){ + + nLine++; + int nLen=_tcslen(buf); + if(nLen>0){ + // Remove trailing '\n' + if(_TCHAR('\n')==buf[nLen-1]){ + buf[--nLen]=_TCHAR('\0'); + } + + // Check for continuation lines + if(_TCHAR('\\')==buf[nLen-1]){ + buf[--nLen]=_TCHAR('\0'); + str+=buf; + } else { + str+=buf; + LPCTSTR c=(LPCTSTR)str; + const TCHAR *pEq=_tcschr(c,_TCHAR('=')); + if(pEq){ + const String strName(c,pEq-c); + CProperties::CProperty *p=Lookup(strName); + if(p){ + pEq++; + rc&=p->SetValue(pEq); + } else { + ERROR(_T("Unknown attribute %s found in %s line %d\n"),(LPCTSTR)strName,pszFileName,nLine); + rc=false; + } } + str=_T(""); } } } fclose(f); } return rc; - } CProperties::CProperty::CProperty(LPCTSTR pszName,Typetype type,void *_pData): @@ -435,310 +422,212 @@ CProperties::CProperty::~CProperty() { } -void CProperties::Add(LPCTSTR pszName,int &n,int _nDefault) +void CProperties::Add(LPCTSTR pszName,int &n) { - CProperty *p=new CProperty(pszName,CProperty::Integer,&n); - p->nDefault=_nDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Integer,&n); + ar.push_back(p); } -void CProperties::Add(LPCTSTR pszName,unsigned int &n,unsigned int _nDefault) +void CProperties::Add(LPCTSTR pszName,unsigned int &n) { - CProperty *p=new CProperty(pszName,CProperty::Integer,&n); - p->nDefault=_nDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Integer,&n); + ar.push_back(p); } -void CProperties::Add(LPCTSTR pszName,bool &b,bool _bDefault) +void CProperties::Add(LPCTSTR pszName,bool &b) { - CProperty *p=new CProperty(pszName,CProperty::Bool,&b); - p->nDefault=_bDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Bool,&b); + ar.push_back(p); } -void CProperties::Add(LPCTSTR pszName,char &c,char _cDefault) +void CProperties::Add(LPCTSTR pszName,char &c) { - CProperty *p=new CProperty(pszName,CProperty::Char,&c); - p->nDefault=_cDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Char,&c); + ar.push_back(p); } -void CProperties::Add(LPCTSTR pszName,unsigned char &c,unsigned char _cDefault) +void CProperties::Add(LPCTSTR pszName,unsigned char &c) { - CProperty *p=new CProperty(pszName,CProperty::Char,&c); - p->nDefault=_cDefault; - ar.push_back(p); -} - -void CProperties::Add(LPCTSTR pszName,short &s,short _sDefault) -{ - CProperty *p=new CProperty(pszName,CProperty::Short,&s); - p->nDefault=_sDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Char,&c); + ar.push_back(p); } -void CProperties::Add(LPCTSTR pszName,unsigned short &s,unsigned short _sDefault) +void CProperties::Add(LPCTSTR pszName,short &s) { - CProperty *p=new CProperty(pszName,CProperty::Short,&s); - p->nDefault=_sDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Short,&s); + ar.push_back(p); } -void CProperties::Add(LPCTSTR pszName,float &f,float _fDefault) +void CProperties::Add(LPCTSTR pszName,unsigned short &s) { - CProperty *p=new CProperty(pszName,CProperty::Float,&f); - p->dDefault=_fDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Short,&s); + ar.push_back(p); } -void CProperties::Add(LPCTSTR pszName,double &f,double dDefault) +void CProperties::Add(LPCTSTR pszName,float &f) { - CProperty *p=new CProperty(pszName,CProperty::Double,&f); - p->dDefault=dDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Float,&f); + ar.push_back(p); } -void CProperties::Add(LPCTSTR pszName,void *pv,unsigned int _nLength,void *pvDefault) +void CProperties::Add(LPCTSTR pszName,double &f) { - CProperty *p=new CProperty(pszName,CProperty::Void,pv); - p->nLength=_nLength; - p->pvDefault=pvDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Double,&f); + ar.push_back(p); } -void CProperties::Add(LPCTSTR pszName,LPTSTR s,unsigned int _nLength,LPCTSTR _pszDefault) +void CProperties::Add(LPCTSTR pszName,void *pv,unsigned int _nLength) { - CProperty *p=new CProperty(pszName,CProperty::szString,s); - p->nLength=_nLength; - p->strDefault=_pszDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::Void,pv); + p.nLength=_nLength; + ar.push_back(p); } -void CProperties::Add (LPCTSTR pszName,void *pObj,getFn *getFn,putFn *putFn,LPCTSTR pszDefault) +void CProperties::Add(LPCTSTR pszName,String &s) { - CProperty *p=new CProperty(pszName,CProperty::GPString,pObj); - p->strDefault=pszDefault; - p->pgetFn=getFn; - p->pputFn=putFn; - p->strDefault=pszDefault; - ar.push_back(p); + CProperty p(pszName,CProperty::szString,(void *)&s); + ar.push_back(p); } unsigned long CProperties::CProperty::GetValue() const { - unsigned long dw; - switch(Type){ - case Integer: - dw=*(int *)pData; - break; - case Bool: - dw=*(bool *)pData; - break; - case Char: - dw=*(char *)pData; - break; - case Short: - dw=*(short *)pData; - break; - default: - dw=0; - assert(false); - } - return dw; + unsigned long dw; + switch(Type){ + case Integer: + dw=*(int *)pData; + break; + case Bool: + dw=*(bool *)pData; + break; + case Char: + dw=*(char *)pData; + break; + case Short: + dw=*(short *)pData; + break; + default: + dw=0; + assert(false); + } + return dw; } const String CProperties::CProperty::GetStringValue() const { - String str; - switch(Type){ - case szString: - str=(LPCTSTR)(pData); - break; - case GPString: - str=pgetFn(pData); - break; - case CProperties::CProperty::Integer: - case CProperties::CProperty::Bool: - case CProperties::CProperty::Char: - case CProperties::CProperty::Short: - str.Format(_T("%u"),GetValue()); - break; - case CProperties::CProperty::Float: - str.Format(_T("%e"),*(float *)(pData)); - break; - case CProperties::CProperty::Double: - str.Format(_T("%e"),*(double *)(pData)); - break; - case CProperties::CProperty::Void: - { - unsigned char *c=(unsigned char *)pData; - for(unsigned int i=0;i=0;--i){ - ((CProperty*)ar[i])->SetDefault(); - } -} - -bool CProperties::Load(LPCTSTR pszPrefix) -{ - #ifdef _WIN32 - return m_hKey?LoadFromRegistry((HKEY)m_hKey,m_strName,pszPrefix):LoadFromFile(m_strName,pszPrefix); - #else // UNIX - return LoadFromFile(m_strName,pszPrefix); - #endif -} - -bool CProperties::Save(LPCTSTR pszPrefix) -{ - #ifdef _WIN32 - return m_hKey?SaveToRegistry((HKEY)m_hKey,m_strName,pszPrefix):SaveToFile(m_strName,pszPrefix); - #else // UNIX - return SaveToFile(m_strName,pszPrefix); - #endif -} -/* -bool CProperties::Remove(LPCTSTR pszName) -{ - for(int i=ar.size()-1;i>=0;--i){ - CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; - if(p->strName==pszName){ - delete p; - ar.RemoveAt(i); - return true; - } - } - return false; -} -*/ diff --git a/host/tools/Utils/common/Properties.h b/host/tools/Utils/common/Properties.h --- a/host/tools/Utils/common/Properties.h +++ b/host/tools/Utils/common/Properties.h @@ -36,70 +36,69 @@ #include "eCosStd.h" #include "Collections.h" +////////////////////////////////////////////////////////////////////// +// This class manages properties and their serialization. +// What you do is this: +// 1. Declare the CProperties object +// 2. Call one or more "Add" functions to associate variables with names +// 3. Call one of the "Load" or "Save" functions to load or save the values +// There are three ways in which the "Load" or "Save" functions operate +// a. Loading/saving to/from a file [LoadFromFile/SaveToFile] +// In this case the contents of the file will look like +// name1=value1 +// name2=value2 +// ... +// b. Loading/saving to/from a command string [LoadFromCommandString/MakeCommandString] +// In this case the contents of the string will look like +// -name1=value1 -name2=value2 ... +// c. Loading/saving to/from the registry [LoadFromRegistry/SaveToRegistry] +// In this case the registry will contain a set of values (name1, name2,...) each of whose +// value data is the corresponding value. +////////////////////////////////////////////////////////////////////// + class CProperties { public: -// bool Remove (LPCTSTR pszName); - void RemoveAll (); + CProperties(); + virtual ~CProperties(); + // Declare various types of property. The functions associate names with // variables, but no values are assigned here. That comes later when a // load function (such as LoadFromRegistry) is called. - void Add (LPCTSTR pszName,int &n,int nDefault=0); - void Add (LPCTSTR pszName,unsigned int &n,unsigned int nDefault=0); - void Add (LPCTSTR pszName,bool &b,bool bDefault=false); - void Add (LPCTSTR pszName,char &c,char cDefault='\0'); - void Add (LPCTSTR pszName,unsigned char &c,unsigned char cDefault='\0'); - void Add (LPCTSTR pszName,short&s,short sDefault=0); - void Add (LPCTSTR pszName,unsigned short&s,unsigned short sDefault=0); - void Add (LPCTSTR pszName,float&f,float fDefault=0.0); - void Add (LPCTSTR pszName,double&f,double fDefault=0.0); - void Add (LPCTSTR pszName,void *d,unsigned int nLength,void *pvDefault=0); - void Add (LPCTSTR pszName,LPTSTR s,unsigned int nLength,LPCTSTR sDefault=_T("")); - // String adding with caller defining get and put. This is here to preserve the neutrality of - // the class - cannot assume MFC's String, for example. Implementation of these fns might be: - // static LPCTSTR CALLBACK GetFn (void *pObj) { return (LPCTSTR)*(String *)pObj; } - // static void CALLBACK PutFn (void *pObj,LPCTSTR psz) { *(String *)pObj=psz; } - - typedef void (CALLBACK putFn)(void *,LPCTSTR); - typedef LPCTSTR (CALLBACK getFn)(void *); - void Add (LPCTSTR pszName,void *pObj,getFn *pgetFn,putFn *pputFn,LPCTSTR pszDefault=_T("")); - - // Set all Added variables to their default values - void SetDefaults(); - // Load (from registry ro f - bool Load(LPCTSTR pszPrefix=_T("")); - bool Save(LPCTSTR pszPrefix=_T("")); + void Add (LPCTSTR pszName,int &n); + void Add (LPCTSTR pszName,unsigned int &n); + void Add (LPCTSTR pszName,bool &b); + void Add (LPCTSTR pszName,char &c); + void Add (LPCTSTR pszName,unsigned char &c); + void Add (LPCTSTR pszName,short&s); + void Add (LPCTSTR pszName,unsigned short&s); + void Add (LPCTSTR pszName,float&f); + void Add (LPCTSTR pszName,double&f); + void Add (LPCTSTR pszName,String &s); + void Add (LPCTSTR pszName,void *d,unsigned int nLength); // Load from and save to a command string. - String MakeCommandString (LPCTSTR pszPrefix=_T("-")) const; // caller must delete [] - bool LoadFromCommandString (LPCTSTR psz,LPCTSTR pszPrefix=_T("-")); - - CProperties(LPCTSTR pszFile,void *hKey=0); - virtual ~CProperties(); + String MakeCommandString () const; // caller must delete [] + bool LoadFromCommandString (LPCTSTR psz); + + // Load from and save to a given file. The format is name=value, one per line. + bool LoadFromFile(LPCTSTR pszFileName); + bool SaveToFile (LPCTSTR pszFileName) const; + #ifdef _WIN32 + bool LoadFromRegistry (HKEY,LPCTSTR); + bool SaveToRegistry(HKEY,LPCTSTR) const; static bool CreateKey (LPCTSTR pszKey,HKEY hKey=HKEY_CURRENT_USER); #endif + protected: static bool CreatePathToFile(LPCTSTR pszDir); - String m_strName; - // Load from and save to a given file. The format is name=value, one per line. - bool LoadFromFile(LPCTSTR pszFileName,LPCTSTR pszPrefix=_T("")); - bool SaveToFile (LPCTSTR pszFileName,LPCTSTR pszPrefix=_T("")) const; - // Load from and save to the registry - void *m_hKey; -#ifdef _WIN32 - bool SaveToRegistry(HKEY,LPCTSTR,LPCTSTR pszPrefix=_T("")) const; - bool LoadFromRegistry (HKEY,LPCTSTR,LPCTSTR pszPrefix=_T("")); -#endif - - PtrArray ar; // Holds declared properties class CProperty { public: - enum Typetype {Integer, szString, GPString, Bool, Char, Short, Float, Double, Void}; + enum Typetype {Integer, szString, Bool, Char, Short, Float, Double, Void}; CProperty(LPCTSTR pszName,Typetype type,void *_pData); virtual ~CProperty(); - void SetDefault(); friend class CProperties; bool SetValue(int n); bool SetValue(double n); @@ -112,17 +111,10 @@ protected: String strName; Typetype Type; void *pData; - union { - int nDefault; - double dDefault; - void* pvDefault; - }; - String strDefault; // can't be in union - has copy ctor - getFn *pgetFn; - putFn *pputFn; - unsigned int nLength; // for szString and Void + unsigned int nLength; // for Void }; CProperty * Lookup (LPCTSTR pszName); + std::vector ar; // Holds declared properties }; #endif // !defined(AFX_PROPERTIES_H__DA938D29_135A_11D3_A50B_00A0C949ADAC__INCLUDED_) diff --git a/host/tools/Utils/common/Subprocess.cpp b/host/tools/Utils/common/Subprocess.cpp new file mode 100644 --- /dev/null +++ b/host/tools/Utils/common/Subprocess.cpp @@ -0,0 +1,874 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contact(s): sdf +// Date: 1998/08/11 +// Version: 0.01 +// Purpose: +// Description: This is the implementation of the class which allows for spawning subprocesses +// +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== +#include "eCosTrace.h" +#include "Subprocess.h" +#ifdef _WIN32 + #include + + HINSTANCE CSubprocess::hInstLib1 = VER_PLATFORM_WIN32_NT==CSubprocess::GetPlatform()?LoadLibrary(_T("PSAPI.DLL")):LoadLibrary(_T("Kernel32.DLL")) ; + HINSTANCE CSubprocess::hInstLib2 = VER_PLATFORM_WIN32_NT==CSubprocess::GetPlatform()?LoadLibrary(_T("NTDLL.DLL")):NULL; + +#endif + +//#define CloseHandle(x) TRACE(_T("CSubprocess::CloseHandle %x\n"),x);::CloseHandle(x) + +const unsigned int CSubprocess::PROCESS_KILL_EXIT_CODE=0xCCFFCCFF; + +CSubprocess::CSubprocess(bool bAutoDelete): + m_pfnContinue(DefaultContinuationFunc), + m_pContinuationFuncParam(0), + m_bAutoDelete(bAutoDelete), + m_bThreadTerminated(true), + m_bVerbose(false), + m_nExitCode(-1), + m_idProcess(0), + m_pLogparam(0), + m_pfnLogfunc(0), + m_bKillThread(false) +{ + #ifdef _WIN32 + InitializeCriticalSection(&m_cs); + #endif +} + +CSubprocess::~CSubprocess() +{ + Kill(); + if(!CeCosThreadUtils::WaitFor(m_bThreadTerminated,1000)){ + m_bKillThread=true; + CeCosThreadUtils::WaitFor(m_bThreadTerminated); + } + #ifdef _WIN32 + DeleteCriticalSection(&m_cs); + #endif +} + +bool CSubprocess::Run(LogFunc *pfnLog,void * pLogparam, LPCTSTR pszCmd,bool bBlock/*=true*/) +{ + bool rc; + if(!m_bThreadTerminated){ + rc=false; + } else { + m_pfnLogfunc=pfnLog; + m_pLogparam=pLogparam; +#ifdef _WIN32 + // UNIX does it from the thread func. WIN32 could too, but it's nice to know at the time + // of calling run whether the process is successfully created. + rc=CreateProcess(pszCmd); +#else + m_strCmd=pszCmd; + rc=true; +#endif + if(rc){ + m_bKillThread=false; + if(bBlock){ + // When using RunThread, the manipulation of this Boolean is taken care of. + // Here we must do it ourselves. + m_bThreadTerminated=false; + ThreadFunc(); + m_bThreadTerminated=true; + } else { + CeCosThreadUtils::RunThread(SThreadFunc,this,&m_bThreadTerminated,String::SFormat(_T("subprocess %d read"),m_idProcess)); + } + } + } + return rc; +} + +#ifdef _WIN32 +bool CSubprocess::CreateProcess(LPCTSTR pszCmdline) +{ + + STARTUPINFO si; // For CreateProcess call + HANDLE hrPipe,hwPipe,hwPipe2,m_hrPipeTemp,m_hwPipeTemp; + // Create the anonymous pipe + + SECURITY_ATTRIBUTES saPipe; // Security for anonymous pipe + saPipe.nLength = sizeof(SECURITY_ATTRIBUTES); + saPipe.lpSecurityDescriptor = NULL; + saPipe.bInheritHandle = true; + + ::CreatePipe(&m_hrPipeTemp,&hwPipe,&saPipe,10240); + + // In most cases you can get away with using the same anonymous + // pipe write handle for both the child's standard output and + // standard error, but this may cause problems if the child app + // explicitly closes one of its standard output or error handles. If + // that happens, the anonymous pipe will close, since the child's + // standard output and error handles are really the same handle. The + // child won't be able to write to the other write handle since the + // pipe is now gone, and parent reads from the pipe will return + // ERROR_BROKEN_PIPE and child output will be lost. To solve this + // problem, simply duplicate the write end of the pipe to create + // another distinct, separate handle to the write end of the pipe. + // One pipe write handle will serve as standard out, the other as + // standard error. Now *both* write handles must be closed before the + // write end of the pipe actually closes. + + ::DuplicateHandle(::GetCurrentProcess(), // Source process + hwPipe, // Handle to duplicate + ::GetCurrentProcess(), // Destination process + &hwPipe2, // New handle, used as stderr by child + 0, // New access flags - ignored since DUPLICATE_SAME_ACCESS + true, // It's inheritable + DUPLICATE_SAME_ACCESS); + + ::CreatePipe(&hrPipe,&m_hwPipeTemp,&saPipe,10240); + + + // Create new output read handle and the input write handles, setting + // the Properties to FALSE. Otherwise, the child inherits the + // properties and, as a result, non-closeable handles to the pipes + // are created. + DuplicateHandle(GetCurrentProcess(),m_hrPipeTemp, + GetCurrentProcess(), + &m_hrPipe, // Address of new handle. + 0,FALSE, // Make it uninheritable. + DUPLICATE_SAME_ACCESS); + + DuplicateHandle(GetCurrentProcess(),m_hwPipeTemp, + GetCurrentProcess(), + &m_hwPipe, // Address of new handle. + 0,FALSE, // Make it uninheritable. + DUPLICATE_SAME_ACCESS); + + // Close inheritable copies of the handles we do not want to be inherited: + CloseHandle(m_hrPipeTemp); + CloseHandle(m_hwPipeTemp); + + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + + si.hStdOutput = hwPipe; + si.hStdError = hwPipe2; + si.hStdInput = hrPipe; + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.wShowWindow = SW_SHOW; + + LPCTSTR pszDir; + if(m_strDir.empty()){ + pszDir=NULL; // current directory + } else { + pszDir=m_strDir; + } + + PROCESS_INFORMATION pi; + String strCmd(pszCmdline); + + String strOrigpath; + if(!m_strPath.empty()){ + int nSize=GetEnvironmentVariable(_T("PATH"), NULL, 0); + if(nSize>0){ + GetEnvironmentVariable(_T("PATH"),strOrigpath.GetBuffer(nSize),nSize); + strOrigpath.ReleaseBuffer(); + SetEnvironmentVariable(_T("PATH"),m_strPath); + } + } + + bool rc=(TRUE==::CreateProcess(NULL,strCmd.GetBuffer(),NULL,NULL,true,DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP,NULL,pszDir,&si,&pi)); + + if(!m_strPath.empty()){ + SetEnvironmentVariable(_T("PATH"),strOrigpath); + } + + m_nErr=GetLastError(); + + strCmd.ReleaseBuffer(); + + if(rc){ + m_idProcess=pi.dwProcessId; + m_hProcess=pi.hProcess; + if(m_bVerbose){ + Output(String::SFormat(_T("*** Process %d created \"%s\"\n"),m_idProcess,pszCmdline)); + } + TRACE(String::SFormat(_T("*** Process %d created \"%s\"\n"),m_idProcess,pszCmdline)); + m_nExitCode=STILL_ACTIVE; + CloseHandle(pi.hThread); + } else { + m_idProcess=0; + if(m_bVerbose){ + Output(String::SFormat(_T("*** Failed to create process \"%s\" %s\n"),pszCmdline,(LPCTSTR)ErrorString())); + } + TRACE(String::SFormat(_T("*** Failed to create process \"%s\" %s\n"),pszCmdline,(LPCTSTR)ErrorString())); + m_nExitCode=GetLastError(); + CloseHandle(m_hrPipe);m_hrPipe=INVALID_HANDLE_VALUE; + CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE; + } + + CloseHandle(hrPipe); + CloseHandle(hwPipe); + CloseHandle(hwPipe2); + + return rc; + +} + +void CSubprocess::ThreadFunc() +{ + + TRACE(_T("Reading from process %d\n"),m_idProcess); + + DWORD dwAvail; + + while (!m_bKillThread && m_pfnContinue(m_pContinuationFuncParam) && ::PeekNamedPipe(m_hrPipe, NULL, 0, 0, &dwAvail, NULL)){ +//TRACE(_T("P%d\n"),dwAvail); + if(dwAvail){ + dwAvail=MIN(dwAvail,80); // Read a maximum of 80 characters at a time + DWORD dwRead; + char *buf=new char[dwAvail+1]; +//TRACE(_T("R%d\n"),dwAvail); + if(!::ReadFile(m_hrPipe, buf, dwAvail, &dwRead, NULL)){ + TRACE(_T("ReadFile returns false\n")); + delete [] buf; + break; + } + buf[dwRead]='\0'; + Output(String::CStrToUnicodeStr(buf)); + delete [] buf; + } else if(!ProcessAlive()){ + TRACE(_T("m_bThreadTerminated=%d\n"),m_bThreadTerminated); + break; + } else { + CeCosThreadUtils::Sleep(250); + } + } + + DWORD dwExitCode; + ::GetExitCodeProcess(m_hProcess, &dwExitCode); + m_nExitCode=dwExitCode; + +#ifdef _DEBUG + String str; + switch(dwExitCode){ + case STILL_ACTIVE: + str=_T("still alive"); + if(m_bKillThread){ + str+=_T(" - requested to stop reading"); + } + break; + case PROCESS_KILL_EXIT_CODE: + str=_T("killed"); + break; + default: + str.Format(_T("terminated rc=%d"),dwExitCode); + break; + } + TRACE(_T("Finished reading from process %d (%s)\n"),m_idProcess,(LPCTSTR)str); +#endif + + CloseHandle(m_hrPipe);m_hrPipe=INVALID_HANDLE_VALUE; + CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE; + EnterCriticalSection(&m_cs); + CloseHandle(m_hProcess); + m_hProcess=0; // Do not use INVALID_HANDLE_VALUE, which is also the pseudo-handle returned by GetCurrentProcess() + LeaveCriticalSection(&m_cs); + + if(m_bAutoDelete){ + m_bThreadTerminated=true; // or else the dtor will block + delete this; + } +} + +#else // UNIX + +bool CSubprocess::CreateProcess(LPCTSTR pszCmdline) +{ + m_idProcess=0; + int fdchild=-1; // the file descriptor for the child (slave) half of the pseudo-tty pair + + // Get a free /dev/ptyp0 (master) and /dev/ttyp0 (slave) tty pair + String strMasterTty,strChildTty; + for(unsigned int c=0;c<64;c++){ + strMasterTty.Format("/dev/pty%c%x",'p'+c/16,c%16); + + m_tty=open(strMasterTty, O_RDWR | O_NOCTTY); + if (-1!=m_tty) { + strChildTty.Format("/dev/tty%c%x",'p'+c/16,c%16); + + fdchild = open(strChildTty, O_RDWR); + if (-1==fdchild) { + close(m_tty); + m_tty=fdchild=-1; + } else { + VTRACE("opened %s - fd=%d\n",(LPCTSTR)strMasterTty,m_tty); + break; + } + } + } + + if(-1==m_tty){ + ERROR(_T("Failed to get a pty\n")); + return false; + } + + TRACE(_T("Master pty %s (fd %d) slave pty %s (fd %d)\n"),(LPCTSTR)strMasterTty,m_tty,(LPCTSTR)strChildTty,fdchild); + + m_idProcess=fork(); + + switch (m_idProcess) { + // Fork failed + case -1: + TRACE(_T("Failed to create process - %s\n"),strerror(errno)); + m_idProcess=0; + break; + case 0: + // Process is created (we're the child) + { + // Close all descriptors except the slave side of the pseudo-terminal + for (int fd = 0; fd < (int) sysconf(_SC_OPEN_MAX); fd++) { + if(fd!=fdchild){ + close(fd); + } + } + setsid(); + + dup2(fdchild, 0); + dup2(fdchild, 1); + dup2(fdchild, 2); + + close(fdchild); + + if(!m_strDir.empty()){ + if(0!=chdir(m_strDir)){ + if(m_bVerbose){ + fprintf(stderr,_T("*** Failed to change directory to %s\n"),(LPCTSTR)m_strDir); + } + exit (5); + } + } + if(m_bVerbose){ + fprintf(stderr,_T("*** Process %d created \"%s\"\n"),m_idProcess,pszCmdline); + } + + StringArray ar; + int argc=String(pszCmdline).Chop(ar,_TCHAR(' '),true); + TCHAR **argv=new TCHAR *[1+argc]; + for(int i=0;i\n"), pszCmdline, m_idProcess); + break; + } + return 0!=m_idProcess; +} + +void CSubprocess::ThreadFunc() +{ + if(!CreateProcess(m_strCmd)){ + ERROR(_T("Failed to create process for %s\n"),(LPCTSTR)m_strCmd); + } else { + fcntl(m_tty,F_SETFL,O_NONBLOCK); + int rc; + do { + TCHAR buf[4096]; + rc=read(m_tty, buf, sizeof(buf)-1); + if(rc>=0){ + buf[rc]='\0'; + } + switch(rc){ + case -1: + if(EAGAIN==errno){ + CeCosThreadUtils::Sleep(250); + } else { + goto Done; + } + break; + case 0: + goto Done; + continue; + default: + buf[rc]=_TCHAR('\0'); + Output(String::CStrToUnicodeStr(buf)); + continue; + } + } while(!m_bKillThread && m_pfnContinue(m_pContinuationFuncParam)); +Done: + TRACE(_T("Closing fd %d\n"),m_tty); + close (m_tty); + + switch(waitpid(m_idProcess,&m_nExitCode,WNOHANG)); + } + + if(m_bAutoDelete){ + delete this; + } +} +#endif + +void CSubprocess::Output (LPCTSTR psz) +{ + m_pfnLogfunc(m_pLogparam,psz); +} + +void CSubprocess::Send(LPCTSTR str) +{ + char *psz=String(str).GetCString(); + int nToWrite=strlen(psz); + const char *c=psz; + do { +#ifdef _WIN32 + DWORD dwWritten; + if(!::WriteFile(m_hwPipe,psz,nToWrite,&dwWritten,0)){ + break; + } +#else + int dwWritten = write(m_tty, c, nToWrite); + if(-1==dwWritten){ + break; + } +#endif + nToWrite-=(int)dwWritten; + c+=(int)dwWritten; + } while (nToWrite>0); + //::FlushFileBuffers(m_hwPipe); + delete [] psz; +} + +bool CSubprocess::Kill(bool bRecurse) +{ +TRACE(_T("CSubprocess::Kill pid %d recurse=%d\n"),m_idProcess,bRecurse); + PInfoArray arPinfo; + bool rc=false; + if(m_idProcess && -1!=m_idProcess){ + // Start of with the easy one: + if(bRecurse) { + // Need to gather this information before we orphan our grandchildren: + PSExtract(arPinfo); + } + +#ifdef _WIN32 + + EnterCriticalSection(&m_cs); // because the thread func may be closing it + if(m_hProcess){ + TRACE(_T("Terminate m_idProcess %d [%s]\n"),m_idProcess,(LPCTSTR)Name(m_idProcess)); + rc=(TRUE==::TerminateProcess(m_hProcess,PROCESS_KILL_EXIT_CODE)); + // Threadfunc's responsibility alone to close the handle + } + LeaveCriticalSection(&m_cs); +#else + rc=(0==kill(m_idProcess,SIGTERM)); + int status; + waitpid(m_idProcess,&status,WNOHANG); +#endif + + if(bRecurse) { + // kill process *and* its children + // FIXME: needs to be top-down + for(int i=0;i<(signed)arPinfo.size();i++){ + if(arPinfo[i].IsChildOf(m_idProcess)){ + +#ifdef _WIN32 + // begin hack + const String strName(Name(arPinfo[i].PID)); + if(_tcsstr(strName,_T("eCosTest")) || _tcsstr(strName,_T("cmd.EXE")) || _tcsstr(strName,_T("CMD.EXE")) || arPinfo[i].PID==(signed)GetCurrentProcessId()){ + continue; + } + // end hack + HANDLE hProcess=::OpenProcess(PROCESS_TERMINATE,false,arPinfo[i].PID); + if(hProcess){ + TRACE(_T("Terminate m_idProcess %d [%s]\n"),arPinfo[i].PID,(LPCTSTR)Name(arPinfo[i].PID)); + + rc&=(TRUE==::TerminateProcess(hProcess,PROCESS_KILL_EXIT_CODE)); + CloseHandle(hProcess); + } else { + rc=false; + } +#else + rc&=(0==kill(arPinfo[i].PID,SIGTERM)); + int status; + waitpid(arPinfo[i].PID,&status,WNOHANG); +#endif + } + } + } + } + return rc; +} + +Time CSubprocess::CpuTime(bool bRecurse) const +{ + Time t=0; + // kill process *and* its children + // FIXME: needs to be top-down + +#ifdef _WIN32 + EnterCriticalSection(&m_cs); // because the thread func may be closing it + __int64 ftCreation,ftExit,ftKernel,ftUser; + if(m_hProcess && ::GetProcessTimes (m_hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){ + t+=Time((ftKernel+ftUser)/10000); + } + LeaveCriticalSection(&m_cs); + + if(bRecurse){ + PInfoArray arPinfo; + PSExtract(arPinfo); + if(m_idProcess && -1!=m_idProcess){ + for(int i=0;i<(signed)arPinfo.size();i++){ + if(arPinfo[i].IsChildOf(m_idProcess)){ + t+=arPinfo[i].tCpu; + } + } + } + } +#else + PInfoArray arPinfo; + PSExtract(arPinfo); + for(int i=0;i<(signed)arPinfo.size();i++){ + if(arPinfo[i].PID==m_idProcess || arPinfo[i].IsChildOf(m_idProcess)){ + t+=arPinfo[i].tCpu; + } + } +#endif + return t; +} + +#ifdef _WIN32 +bool CSubprocess::PSExtract(CSubprocess::PInfoArray &arPinfo) +{ + bool rc=false; + arPinfo.clear(); + // If Windows NT: + switch(GetPlatform()) { + case VER_PLATFORM_WIN32_NT: + if(hInstLib1) { + + // Get procedure addresses. + static BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ) = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))GetProcAddress( hInstLib1, "EnumProcesses" ) ; + if( lpfEnumProcesses) { + + if(hInstLib2) { + + static DWORD (WINAPI *lpfNtQueryInformationProcess)( HANDLE, int, void *, DWORD, LPDWORD ) = + (DWORD(WINAPI *)(HANDLE, int, void *, DWORD, LPDWORD)) GetProcAddress( hInstLib2,"NtQueryInformationProcess" ) ; + + if(lpfNtQueryInformationProcess){ + DWORD dwMaxPids=256; + DWORD dwPidSize; + DWORD *arPids = NULL ; + do { + delete [] arPids; + arPids=new DWORD[dwMaxPids]; + } while(lpfEnumProcesses(arPids, dwMaxPids, &dwPidSize) && dwPidSize/sizeof(DWORD)==dwMaxPids) ; + + if(dwPidSize/sizeof(DWORD)=0 && + TRUE==::GetProcessTimes (hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){ + // The second test is important. It excludes orphaned processes who appear to have been adopted by virtue of a new + // process having been created with the same ID as their original parent. + PInfo p; + p.PID=pid; + p.PPID=pbi.InheritedFromUniqueProcessId; + p.tCreation=ftCreation; + p.tCpu=Time((ftKernel+ftUser)/10000); + arPinfo.push_back(p); + } + + CloseHandle(hProcess); + + } + } + } + delete [] arPids; + } + } + } + } + break; + case VER_PLATFORM_WIN32_WINDOWS: + + if( hInstLib1) { + + static HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD)= + (HANDLE(WINAPI *)(DWORD,DWORD))GetProcAddress( hInstLib1,"CreateToolhelp32Snapshot" ) ; + static BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32)= + (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( hInstLib1, "Process32First" ) ; + static BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32)= + (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( hInstLib1, "Process32Next" ) ; + if( lpfProcess32Next && lpfProcess32First && lpfCreateToolhelp32Snapshot) { + + // Get a handle to a Toolhelp snapshot of the systems + // processes. + HANDLE hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ; + if(INVALID_HANDLE_VALUE != hSnapShot) { + // Get the first process' information. + PROCESSENTRY32 procentry; + procentry.dwSize = sizeof(PROCESSENTRY32) ; + if(lpfProcess32First( hSnapShot, &procentry )){ + rc=true; + do { + PInfo p; + p.PID=procentry.th32ProcessID; + p.PPID=procentry.th32ParentProcessID; + arPinfo.push_back(p); + } while(lpfProcess32Next( hSnapShot, &procentry )); + } + CloseHandle(hSnapShot); + } + } + } + break; + default: + break; + } + + SetParents(arPinfo); + +/* +for(int k=0;k<(signed)arPinfo.size();k++){ + const PInfo &p=arPinfo[k]; + TRACE(_T("%d%c pid=%4d ppid=%4d t=%I64d [%s]\n"),k,p.IsChildOf(GetCurrentProcessId())?_TCHAR('*'):_TCHAR(':'),p.PID,p.PPID,p.t,(LPCTSTR)Name(p.PID)); +} +*/ + if(!rc){ + ERROR(_T("Couldn't get process information!\n")); + } + return rc; +} + +#else // UNIX + +bool CSubprocess::PSExtract(CSubprocess::PInfoArray &arPinfo) +{ + arPinfo.clear(); + int i; + FILE *f=popen("ps -l",_T("r") MODE_TEXT); + if(f){ + char buf[100]; + while(fgets(buf,sizeof(buf)-1,f)){ + TCHAR discard[100]; + PInfo p; + // Output is in the form + // F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD + //100 S 490 877 876 0 70 0 - 368 wait4 pts/0 00:00:00 bash + int F,UID,C,PRI,NI,SZ,HH,MM,SS; + bool rc=(15==_stscanf(buf,_T("%d %s %d %d %d %d %d %d %s %d %s %s %d:%d:%d"),&F,discard,&UID,&p.PID,&p.PPID,&C,&PRI,&NI,discard,&SZ,discard,discard,&HH,&MM,&SS)); + if(rc){ + p.tCpu=1000*(SS+60*(60*HH+MM)); + arPinfo.push_back(p); + } + } + pclose(f); + for(i=0;i<(signed)arPinfo.size();i++){ + int pid=arPinfo[i].PPID; + arPinfo[i].pParent=0; + for(int j=0;j<(signed)arPinfo.size();j++){ + if(i!=j && arPinfo[j].PID==pid){ + arPinfo[i].pParent=&arPinfo[j]; + break; + } + } + } + } else { + ERROR(_T("Failed to run ps -l\n")); + } + return true; //FIXME +} + +#endif + +void CSubprocess::SetParents(CSubprocess::PInfoArray &arPinfo) +{ + int i; + for(i=0;i<(signed)arPinfo.size();i++){ + PInfo &p=arPinfo[i]; + p.pParent=0; + for(int j=0;j<(signed)arPinfo.size();j++){ + if(arPinfo[j].PID==p.PPID +#ifdef _WIN32 + && arPinfo[j].tCreationpParent; + } + // If all is well, p should be NULL here. Otherwise we have a loop. + if(p){ + // Make sure it can't foul things up: + arPinfo[i].pParent=0; + bCircularity=true; + } + } + + if(bCircularity){ + ERROR(_T("!!! Circularly linked process list at index %d\n"),i); + for(int k=0;k<(signed)arPinfo.size();k++){ + const PInfo &p=arPinfo[k]; + ERROR(_T("%d: pid=%4d ppid=%4d [%s]\n"),k,p.PID,p.PPID,(LPCTSTR)Name(p.PID)); + } + } +} + +bool CSubprocess::PInfo::IsChildOf(int pid) const +{ + for(PInfo *p=pParent;p && p!=this;p=p->pParent) { // guard against circular linkage + if(p->PID==pid){ + return true; + } + } + return false; +} + +const String CSubprocess::Name(int pid) +{ + String str; +#ifdef _DEBUG +#ifdef _WIN32 + if(VER_PLATFORM_WIN32_NT==GetPlatform() && hInstLib1){ + static BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, DWORD, LPDWORD ) = + (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( hInstLib1,"EnumProcessModules" ) ; + static DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE, LPTSTR, DWORD )= + (DWORD (WINAPI *)(HANDLE, HMODULE,LPTSTR, DWORD )) GetProcAddress( hInstLib1,"GetModuleFileNameExA" ) ; + if( lpfEnumProcessModules && lpfGetModuleFileNameEx ) { + HANDLE hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,pid); + if(hProcess) { + HMODULE hMod; + DWORD dwSize; + if(lpfEnumProcessModules( hProcess, &hMod, sizeof(HMODULE), &dwSize ) ){ + // Get Full pathname: + LPTSTR buf=str.GetBuffer(MAX_PATH); + lpfGetModuleFileNameEx( hProcess, hMod, buf, MAX_PATH); + str.ReleaseBuffer(); + } + CloseHandle(hProcess); + } + } + } +#endif +#endif + return str; +} + +#ifdef _WIN32 +DWORD CSubprocess::GetPlatform() +{ + OSVERSIONINFO osver; + osver.dwOSVersionInfoSize = sizeof( osver ) ; + return GetVersionEx( &osver ) ? osver.dwPlatformId : (DWORD)-1; +} +#endif + +bool CSubprocess::ProcessAlive() +{ + return !m_bThreadTerminated; +} + +void CSubprocess::CloseInput() +{ +#ifdef _WIN32 + CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE; +#else + close(m_tty); +#endif +} + +bool CSubprocess::Wait(Duration dTimeout) +{ + return CeCosThreadUtils::WaitFor(m_bThreadTerminated,dTimeout); +} + +const String CSubprocess::ErrorString() const +{ +#ifdef _WIN32 + TCHAR *pszMsg; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + m_nErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&pszMsg, + 0, + NULL + ); + return pszMsg; +#else + return strerror(errno); +#endif +} + diff --git a/host/tools/Utils/common/Subprocess.h b/host/tools/Utils/common/Subprocess.h new file mode 100644 --- /dev/null +++ b/host/tools/Utils/common/Subprocess.h @@ -0,0 +1,183 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contact(s): sdf +// Date: 1998/08/11 +// Version: 0.01 +// Purpose: +// Description: Interface of the subprocess clas +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== +#ifndef _SUBPROCESS_H +#define _SUBPROCESS_H + +//=========================================================================== +// This class spawns subprocesses in a host-independent manner [almost] +//=========================================================================== + +#include "eCosStd.h" +#include "eCosThreadUtils.h" +#include "Collections.h" + +class CSubprocess { + +public: + void SetPath (LPCTSTR pszPath) { m_strPath=pszPath; } + const String ErrorString() const; + + // If bAutodelete is set, the class object will delete itself when the process is finished. + // This must only be used if the class object is allocated on the heap. + CSubprocess(bool bAutodelete=false); + virtual ~CSubprocess(); + + void SetVerbose (bool b) { m_bVerbose=b; } + void SetDirectory (LPCTSTR pszDir) { m_strDir=pszDir; } + + // Various forms of the Run function. In each case under UNIX the Run results will always return true + // (because we can't determine the result of the exec after fork). Under NT the result correctly represents + // whether the process creation was successful + + // Run (blocking) sending the output to strOutput. + bool Run(String &strOutput,LPCTSTR pszCmd) { return Run(AppendFunc,&strOutput,pszCmd,true); } + + // Run sending output to callback + bool Run(LogFunc *pfnLog,void * pLogparam,LPCTSTR pszCmd,bool bBlock=true); + + int Pid() const { return m_idProcess; } // returns process id (even when process is terminated) + + // Get the CPU time of the process (and, optionally, its children) + // Note that under UNIX this involves running ps and so may not be that cheap. + Time CpuTime(bool bRecurse=true) const; + + // Get the process exit code. This can be: + // exit code of process (if terminated) + // 0xffffffff (if process not yet run) + // GetLastError result (if process could not be run) + int GetExitCode() { return m_nExitCode; } + + // Kill the process: + bool Kill(bool bRecurse=true); + + // Send some input to the process: + void Send (LPCTSTR psz); + // Close it (cause EOF to be read) + void CloseInput(); + // Is the process running? + bool ProcessAlive(); + + // Appendfunc can be used to achieve a non-blocking addition to some string + static void CALLBACK AppendFunc(void *pParam,LPCTSTR psz) { + ENTERCRITICAL; + *((String *)pParam)+=psz; + LEAVECRITICAL; + } + + // This function may be used to stop a process given some condition evaluated externally, + // As long as the function returns true the process will be allowed to continue + typedef bool (CALLBACK ContinuationFunc)(void *); + void SetContinuationFunc(ContinuationFunc *pfnContinue,void *pParam){m_pfnContinue=pfnContinue;m_pContinuationFuncParam=pParam;} + + // Wait for completion of the process, with optional timeout. If the timeout occurs without the process + // having terminated, the result will be false. + bool Wait(Duration dTimeout=0x7fffffff); + +protected: + String m_strPath; + + static const String Name (int pid); // for debugging - only works under NT + + ContinuationFunc *m_pfnContinue; + void *m_pContinuationFuncParam; + static bool CALLBACK DefaultContinuationFunc(void *) { return true; } + + static void CALLBACK NullLogFunc(void *,LPCTSTR) {} + + struct PInfo; + struct PInfo { + PInfo *pParent; +#ifdef _WIN32 + __int64 tCreation; +#endif + Time tCpu; + int PID; + int PPID; + bool IsChildOf(int pid) const; + }; + + typedef std::vector PInfoArray; + + static bool PSExtract(PInfoArray &arPinfo); + static void SetParents(PInfoArray &arPinfo); + +#ifdef _WIN32 + static DWORD GetPlatform(); + HANDLE m_hrPipe; + HANDLE m_hwPipe; + HANDLE m_hProcess; // This handle is "owned" by the ThreadFunc + mutable CRITICAL_SECTION m_cs; // protects m_hProcess + static HINSTANCE hInstLib1, hInstLib2; + int m_nErr; +#else + int m_tty; + String m_strCmd; +#endif + + static void CALLBACK SThreadFunc(void *pParam) { ((CSubprocess *)pParam)->ThreadFunc(); } + void ThreadFunc(); + bool m_bAutoDelete; + bool m_bThreadTerminated; + bool m_bVerbose; + int m_nExitCode; + int m_idProcess; + void *m_pLogparam; + LogFunc *m_pfnLogfunc; + bool m_bKillThread; + + static const unsigned int PROCESS_KILL_EXIT_CODE; + bool CreateProcess(LPCTSTR pszCmdline); + + struct CygProcessInfo { + int nPid; + int nPpid; + int nPgid; + int nWinpid; + }; + + + void Output(LPCTSTR psz); + String m_strDir; +}; + +#endif diff --git a/host/tools/Utils/common/eCosSerial.cpp b/host/tools/Utils/common/eCosSerial.cpp new file mode 100644 --- /dev/null +++ b/host/tools/Utils/common/eCosSerial.cpp @@ -0,0 +1,542 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//================================================================= +// +// eCosSerial.cpp +// +// Serial test class +// +//================================================================= +//================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contributors: sdf +// Date: 1999-04-01 +// Description: This class abstracts the serial port for use in the testing infrastructure +// Usage: +// +//####DESCRIPTIONEND#### + +#include "eCosStd.h" +#include "eCosSerial.h" +#include "eCosThreadUtils.h" +#include "eCosTrace.h" + +CeCosSerial::CeCosSerial(): + m_nErr(0), + m_pHandle(0), + m_nDataBits(8), + m_nStopBits(ONE_STOP_BIT), + m_bParity(false), + m_nBaud(0), + m_nTotalReadTimeout(10*1000), + m_nTotalWriteTimeout(10*1000), + m_nInterCharReadTimeout(500), + m_nInterCharWriteTimeout(500), + m_bBlockingReads(true) +{ +} + +CeCosSerial::~CeCosSerial() +{ + Close(); +} + +CeCosSerial::CeCosSerial(LPCTSTR pszPort,int nBaud): + m_nErr(0), + m_pHandle(0), + m_nDataBits(8), + m_nStopBits(ONE_STOP_BIT), + m_bParity(false), + m_nTotalReadTimeout(10*1000), + m_nTotalWriteTimeout(10*1000), + m_nInterCharReadTimeout(500), + m_nInterCharWriteTimeout(500), + m_bBlockingReads(true) +{ + Open(pszPort,nBaud); +} + +bool CeCosSerial::SetBlockingReads(bool b,bool bApplySettingsNow/*=true*/) +{ + m_bBlockingReads=b; + return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); +} + +bool CeCosSerial:: SetBaud(unsigned int nBaud,bool bApplySettingsNow/*=true*/) +{ + m_nBaud=nBaud; + return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); +} + +bool CeCosSerial:: SetParity(bool bParityOn,bool bApplySettingsNow/*=true*/) +{ + m_bParity=bParityOn; + return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); +} + +bool CeCosSerial:: SetDataBits(int n,bool bApplySettingsNow/*=true*/) +{ + m_nDataBits=n; + return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); +} + +bool CeCosSerial:: SetStopBits(StopBitsType n,bool bApplySettingsNow/*=true*/) +{ + m_nStopBits=n; + return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); +} + +bool CeCosSerial:: SetReadTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow/*=true*/) // mSec +{ + m_nTotalReadTimeout=nTotal; + m_nInterCharReadTimeout=nBetweenChars; + + return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); +} + +bool CeCosSerial:: SetWriteTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow/*=true*/) // mSec +{ + m_nTotalWriteTimeout=nTotal; + m_nInterCharWriteTimeout=nBetweenChars; + return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); +} + +#ifdef _WIN32 +bool CeCosSerial::Open(LPCTSTR pszPort,int nBaud) +{ + bool rc=false; + m_nBaud=nBaud, + m_strPort=pszPort; + HANDLE hCom=::CreateFile(pszPort,GENERIC_READ|GENERIC_WRITE, 0,NULL,OPEN_EXISTING,0,NULL); + SaveError(); + if (INVALID_HANDLE_VALUE==hCom) { + ERROR(_T("Failed to open port %s - %s\n"),pszPort,(LPCTSTR)ErrString()); + } else { + m_pHandle=(void *)hCom; + if(ApplySettings()){ + Flush(); + rc=true; + } else { + Close(); + } + } + return rc; +} + +bool CeCosSerial::Close() +{ + bool rc=false; + if(m_pHandle){ + try { + rc=(TRUE==CloseHandle((HANDLE)m_pHandle)); + } + catch(...) { + TRACE(_T("!!! Exception caught closing serial handle %08x\n"),m_pHandle); + } + m_pHandle=0; + } else { + rc=true; + } + return rc; +} + +bool CeCosSerial::ApplySettings() +{ + bool rc=false; + try { + DCB dcb; + + ZeroMemory(&dcb,sizeof dcb); + dcb.DCBlength=sizeof dcb; + dcb.BaudRate=m_nBaud; + dcb.fBinary=true; + dcb.fParity=true; + dcb.Parity=(BYTE) ((m_bParity) ? EVENPARITY : NOPARITY); + dcb.StopBits=(BYTE)m_nStopBits; + dcb.ByteSize=(BYTE)m_nDataBits; + LPCTSTR arpszStopbits[3]={_T("1"),_T("1.5"),_T("2")}; + TRACE(_T("Applysettings baud=%d Parity=%d stopbits=%s databits=%d\n"), + dcb.BaudRate, + dcb.Parity, + arpszStopbits[dcb.StopBits], + dcb.ByteSize); + + // No control over the following yet + dcb.fDtrControl=DTR_CONTROL_ENABLE; + dcb.fTXContinueOnXoff=1; + dcb.fRtsControl=RTS_CONTROL_ENABLE; + dcb.fAbortOnError=1; + dcb.XonLim=2048; + dcb.XoffLim=512; + dcb.XonChar=17; + dcb.XoffChar=19; + + HANDLE hCom=(HANDLE)m_pHandle; + if (!SetCommState(hCom, &dcb)) { + SaveError(); + ERROR(_T("Failed to set comm state - port %s handle=%d err=%d\n"),(LPCTSTR)m_strPort,hCom,GetLastError()); + } else { + COMMTIMEOUTS commtimeouts; + if(m_bBlockingReads){ + commtimeouts.ReadIntervalTimeout=m_nInterCharReadTimeout; + commtimeouts.ReadTotalTimeoutMultiplier=0; + commtimeouts.ReadTotalTimeoutConstant=m_nTotalReadTimeout; + } else { + commtimeouts.ReadIntervalTimeout=MAXDWORD; + commtimeouts.ReadTotalTimeoutMultiplier=0; + commtimeouts.ReadTotalTimeoutConstant=0; + } + commtimeouts.WriteTotalTimeoutMultiplier=m_nTotalWriteTimeout; + commtimeouts.WriteTotalTimeoutConstant=m_nInterCharWriteTimeout; + + if (SetCommTimeouts(hCom, &commtimeouts)) { + rc=true; + } else { + SaveError(); + ERROR(_T("Failed to set comm timeouts - port %s\n"),(LPCTSTR)m_strPort); + } + } + } + catch(...) + { + TRACE(_T("!!! Exception caught in CeCosSerial::ApplySettings!!!\n")); + } + return rc; +} + +bool CeCosSerial::Read (void *pBuf,unsigned int nSize,unsigned int &nRead) +{ + bool rc=(TRUE==ReadFile((HANDLE)m_pHandle,pBuf,nSize,(LPDWORD)&nRead,0)); + SaveError(); + return rc; +} + +bool CeCosSerial::Write(void *pBuf,unsigned int nSize,unsigned int &nWritten) +{ + bool rc=(TRUE==WriteFile((HANDLE)m_pHandle,pBuf,nSize,(LPDWORD)&nWritten,0)); + SaveError(); + return rc; +} + +bool CeCosSerial::ClearError() +{ + DWORD dwErrors; + bool rc=(TRUE==ClearCommError(HANDLE(m_pHandle),&dwErrors,0)); + if(dwErrors&CE_BREAK)TRACE(_T("The hardware detected a break condition.\n")); + if(dwErrors&CE_DNS)TRACE(_T("Windows 95 and Windows 98: A parallel device is not selected.\n")); + if(dwErrors&CE_FRAME)TRACE(_T("The hardware detected a framing error.\n")); + if(dwErrors&CE_IOE)TRACE(_T("An I/O error occurred during communications with the device.\n")); + if(dwErrors&CE_MODE)TRACE(_T("The requested mode is not supported, or the hFile parameter is invalid. If this value is specified, it is the only valid error.\n")); + if(dwErrors&CE_OOP)TRACE(_T("Windows 95 and Windows 98: A parallel device signaled that it is out of paper.\n")); + if(dwErrors&CE_OVERRUN)TRACE(_T("A character-buffer overrun has occurred. The next character is lost.\n")); + if(dwErrors&CE_PTO)TRACE(_T("Windows 95 and Windows 98: A time-out occurred on a parallel device.\n")); + if(dwErrors&CE_RXOVER)TRACE(_T("An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.\n")); + if(dwErrors&CE_RXPARITY)TRACE(_T("The hardware detected a parity error.\n")); + if(dwErrors&CE_TXFULL)TRACE(_T("The application tried to transmit a character, but the output buffer was full.\n")); + return rc; +} + +bool CeCosSerial::Flush (void) +{ + bool rc=(TRUE==PurgeComm ((HANDLE)m_pHandle,PURGE_TXCLEAR|PURGE_RXCLEAR)); + SaveError(); + return rc; +} + +String CeCosSerial::ErrString() const +{ + String str; + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + m_nErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + str=(LPCTSTR)lpMsgBuf; + // Free the buffer. + LocalFree( lpMsgBuf ); + return str; +} + +#else // UNIX + +String CeCosSerial::ErrString() const +{ + return strerror(errno); +} + +bool CeCosSerial::Close() +{ + bool rc=m_pHandle && (-1!=close((int)m_pHandle)); + m_pHandle=0; + return rc; +} + +bool CeCosSerial::Open(LPCTSTR pszPort,int nBaud) +{ + bool rc=false; + m_nBaud=nBaud, + m_strPort=pszPort; + int fd = open(pszPort,O_RDWR|O_NONBLOCK); + if (-1==fd) { + ERROR(_T("Failed to open port %s\n"),pszPort); + return false; + } else { + m_pHandle=(void *)fd; + if(ApplySettings()){ + rc=true; + } else { + Close(); + ERROR(_T("Failed to apply settings.\n")); + return false; + } + } + return rc; +} + +bool CeCosSerial::ApplySettings() +{ + struct termios buf, buf_verify; + int rate; + + // Clear the two structures so we can make a binary comparison later on. + memset(&buf, 0, sizeof(buf)); + memset(&buf_verify, 0, sizeof(buf_verify)); + + LPCTSTR arpszStopbits[3]={_T("1"),_T("1.5"),_T("2")}; + TRACE(_T("Applysettings baud=%d bParity=%d stopbits=%s databits=%d\n"), + m_nBaud, + m_bParity, + arpszStopbits[m_nStopBits], + m_nDataBits); + + switch(m_nBaud) { + case 110: + rate = B110; + break; + case 150: + rate = B150; + break; + case 300: + rate = B300; + break; + case 600: + rate = B600; + break; + case 1200: + rate = B1200; + break; + case 2400: + rate = B2400; + break; + case 4800: + rate = B4800; + break; + case 9600: + rate = B9600; + break; + case 19200: + rate = B19200; + break; + case 38400: + rate = B38400; + break; + case 57600: + rate = B57600; + break; + case 115200: + rate = B115200; + break; + default: + return false; + }; + + TRACE(_T("Changing configuration...\n")); + + // Get current settings. + if (tcgetattr((int) m_pHandle, &buf)) { + fprintf(stderr, _T("Error: tcgetattr\n")); + return false; + } + + // Reset to raw. + buf.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + buf.c_oflag &= ~OPOST; + buf.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + buf.c_cflag &= ~(CSIZE|PARENB); + buf.c_cflag |= CS8; + + // Set baud rate. + cfsetispeed(&buf, rate); + cfsetospeed(&buf, rate); + + // Set data bits. + { + int data_bits[9] = {0, 0, 0, 0, 0, CS5, CS6, CS7, CS8}; + + buf.c_cflag &= ~CSIZE; + buf.c_cflag |= data_bits[m_nDataBits]; + } + + // Set stop bits. + { + buf.c_cflag &= ~CSTOPB; + if (ONE_STOP_BIT != m_nStopBits) + buf.c_cflag |= CSTOPB; + } + + // Set parity. + { + buf.c_cflag &= ~(PARENB | PARODD); // no parity. + if (m_bParity) // even parity. + buf.c_cflag |= PARENB; + } + + // Set the new settings + if (tcsetattr((int) m_pHandle, TCSADRAIN, &buf)) { + fprintf(stderr, _T("Error: tcsetattr\n")); + return false; + } + + // Now read back the settings. On SunOS tcsetattr only returns + // error if _all_ settings fail. If just a few settings are not + // supported, the call returns true while the hardware is set to a + // combination of old and new settings. + if (tcgetattr((int) m_pHandle, &buf_verify)) { + fprintf(stderr, _T("Error: tcgetattr\n")); + return false; + } + if (memcmp(&buf, &buf_verify, sizeof(buf))) { + fprintf(stderr, _T("Error: termios verify failed\n")); + return false; + } + + // A slight delay to allow things to settle. + CeCosThreadUtils::Sleep(10); + + TRACE(_T("Done.\n")); + + return true; +} + +bool CeCosSerial::Flush (void) +{ + return 0==tcflush((int) m_pHandle, TCIOFLUSH); +} + +bool CeCosSerial::Read (void *pBuf,unsigned int nSize,unsigned int &nRead) +{ + + if (!m_bBlockingReads) { + nRead = 0; + int n = read((int)m_pHandle, pBuf, nSize); + if (-1 == n) { + if (EAGAIN == errno) + return true; + ERROR(_T("Read failed: %d\n"), errno); + return false; + } + nRead = n; + return true; + } + + // Blocking reads: emulate the Windows semantics: + // If m_nTotalReadTimeout elapses before we see the first TCHAR, + // return. + // If m_nInterCharReadTimeout elapses after reading any + // subsequent TCHAR, return. + + fd_set rfds; + FD_ZERO(&rfds); + FD_SET((int)m_pHandle, &rfds); + + // Start with total timeout. + struct timeval tv; + tv.tv_sec = m_nTotalReadTimeout / 1000; + tv.tv_usec = (m_nTotalReadTimeout % 1000) * 1000; + + unsigned char* pData = (unsigned char*) pBuf; + nRead = 0; + while (nSize) { + switch(select((int)m_pHandle + 1, &rfds, NULL, NULL, &tv)) { + case 1: + { + int n = read((int)m_pHandle, pData, nSize); + if (-1 == n && EAGAIN != errno) { + ERROR(_T("Read failed: %d\n"), errno); + return false; // FAILED + } + nRead += n; + pData += n; + nSize -= n; + + // Now use inter-char timeout. + tv.tv_sec = m_nInterCharReadTimeout / 1000; + tv.tv_usec = (m_nInterCharReadTimeout % 1000) * 1000; + } + break; + case 0: + return true; // Timeout + case -1: + ERROR(_T("Select failed: %d\n"), errno); + return false; + } + } + + return true; +} + +bool CeCosSerial::Write(void *pBuf,unsigned int nSize,unsigned int &nWritten) +{ + bool rc; + int n=write((int)m_pHandle,pBuf,nSize); + if(-1==n){ + nWritten=0; + if (errno == EAGAIN) + rc = true; + else + rc=false; + } else { + nWritten=n; + rc=true; + } + return rc; +} + +bool CeCosSerial::ClearError() +{ + return false; +} + +#endif diff --git a/host/tools/Utils/common/eCosSerial.h b/host/tools/Utils/common/eCosSerial.h new file mode 100644 --- /dev/null +++ b/host/tools/Utils/common/eCosSerial.h @@ -0,0 +1,133 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//================================================================= +// +// eCosSerial.h +// +// Serial test class +// +//================================================================= +//================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contributors: sdf +// Date: 1999-04-01 +// Description: This class abstracts the serial port +// Usage: +// +// +//####DESCRIPTIONEND#### + +#ifndef _CECOSSERIAL_H +#define _CECOSSERIAL_H +#include "eCosStd.h" +#include "eCosSocket.h" +#include "Collections.h" +//================================================================= +// This class is a host-independent interface to a serial port +//================================================================= +class CeCosSerial { + friend CeCosSocket::SSReadResult CeCosSocket::SSRead (CeCosSerial &serial,CeCosSocket &socket,void *pBuf,unsigned int nSize,unsigned int &nRead,bool *pbStop); + +public: + enum StopBitsType { ONE_STOP_BIT, ONE_POINT_FIVE_STOP_BITS, TWO_STOP_BITS }; + CeCosSerial(LPCTSTR pszPort,int nBaud); // ctor and open all in one go + CeCosSerial(); // Call Open() later + virtual ~CeCosSerial(); + + // Open the port with given baud rate. Result indicates how successful we've been + bool Open(LPCTSTR pszPort,int nBaud); + + // Set various line characteristics. This can be done with the line open or closed. + // In each case the "bApplySettingsNow" argument indicates whether to perform the action now, + // or to hold off until a call of ApplySettings(). + + bool SetBaud(unsigned int nBaud,bool bApplySettingsNow=true); + bool SetParity(bool bParityOn,bool bApplySettingsNow=true); + bool SetDataBits(int n,bool bApplySettingsNow=true); + bool SetStopBits(StopBitsType n,bool bApplySettingsNow=true); + bool SetReadTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow=true); // Times are in mSec + bool SetWriteTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow=true); // Times are in mSec + + bool ApplySettings(); + + // Query the settings: + int GetParity() const { return m_bParity; } + int GetDataBits() const { return m_nDataBits; } + StopBitsType GetStopBits() const { return m_nStopBits; } + unsigned int GetBaud() const { return m_nBaud; } + bool GetReadTimeOuts(int &nTotal,int &nBetweenChars) const {nTotal=m_nTotalReadTimeout; nBetweenChars=m_nInterCharReadTimeout; return true; }// mSec + bool GetWriteTimeOuts(int &nTotal,int &nBetweenChars) const {nTotal=m_nTotalWriteTimeout; nBetweenChars=m_nInterCharWriteTimeout; return true; }// mSec + bool GetBlockingReads() const { return m_bBlockingReads; } + bool Close(); + + // Clear the serial buffer: + bool Flush (void); + + // Use to test success after opening with the ctor: + bool Ok() const { return 0!=m_pHandle; } + + // Will read up to the length provided: + bool Read (void *pBuf,unsigned int nSize,unsigned int &nRead); + bool Write(void *pBuf,unsigned int nSize,unsigned int &nWritten); + + // Use in the event of an error that needs to be cleared before the next operation: + bool ClearError(); + + // Set blocking/non-blocking + bool SetBlockingReads(bool b,bool bApplySettingsNow=true); + + // Return last error + int Error() const { return m_nErr; } + + // Return last error, translated to a string + String ErrString() const; + +protected: + // The last error: + int m_nErr + ; + // Remember the error + void SaveError() { + #ifdef _WIN32 + m_nErr=WSAGetLastError(); + #else // UNIX + m_nErr=errno; + #endif + } + + // Line characteristics: + void *m_pHandle; + int m_nDataBits; + StopBitsType m_nStopBits; + bool m_bParity; + unsigned int m_nBaud; + int m_nTotalReadTimeout,m_nTotalWriteTimeout; + int m_nInterCharReadTimeout,m_nInterCharWriteTimeout; + bool m_bBlockingReads; + String m_strPort; +}; +#endif diff --git a/host/tools/Utils/common/eCosSocket.cpp b/host/tools/Utils/common/eCosSocket.cpp new file mode 100644 --- /dev/null +++ b/host/tools/Utils/common/eCosSocket.cpp @@ -0,0 +1,820 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//================================================================= +// +// eCosSocket.cpp +// +// Socket test class +// +//================================================================= +//================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contributors: sdf +// Date: 1999-04-01 +// Description: This class abstracts tcp/ip sockets for use in the testing infrastructure +// Usage: +// +//####DESCRIPTIONEND#### + +#include "eCosStd.h" +#include "eCosSocket.h" +#include "eCosSerial.h" +#include "eCosThreadUtils.h" +#include "eCosTrace.h" +#include + +enum {ERR_TIMEOUT=20000, ERR_READ_AFTER_CLOSE=20001}; + +// Blocking read on one or other of the data sources: +// Result: -1 - socket error occurred +// 1 - data read from socket +// -2 - serial error occurred +// 2 - data read from serial + +CeCosSocket::SSReadResult CeCosSocket::SSRead (CeCosSerial &serial,CeCosSocket &socket,void *pBuf,unsigned int nSize,unsigned int &nRead,bool *pbStop) +{ + SSReadResult rc=SS_STOPPED; + bool bBlocking=serial.GetBlockingReads(); + bool bBlockingModified=false; + while(0==pbStop || !(*pbStop)){ + if(!socket.Peek(nRead)){ + rc=SS_SOCKET_ERROR; + break; + } else if(nRead){ + nRead=MIN(nRead,nSize); + rc=socket.recv(pBuf,nRead)?SS_SOCKET_READ:SS_SOCKET_ERROR; + break; + } else { + if(bBlocking){ + serial.SetBlockingReads(false); + bBlockingModified=true; + bBlocking=false; + } + if(serial.Read(pBuf,nSize,nRead)){ + if(nRead>0){ + rc=SS_SERIAL_READ; + break; + } + } else { + rc=SS_SERIAL_ERROR; + break; + } + } + CeCosThreadUtils::Sleep(10); + } + if(bBlockingModified){ + serial.SetBlockingReads(true); + } + return rc; +} + +// ctors and dtors + +CeCosSocket::CeCosSocket (): +m_nDefaultTimeout(10*1000), +m_nSock(-1), +m_nClient(0) +{ + VTRACE(_T("Create socket instance %08x\n"),(unsigned int)this); +} + +CeCosSocket::CeCosSocket (int sock /*result of previous call of Listen*/, bool *pbStop): +m_nDefaultTimeout(10*1000), +m_nSock(-1), +m_nClient(0) +{ + VTRACE(_T("Create socket instance %08x\n"),(unsigned int)this); + Accept(sock,pbStop); +} + +CeCosSocket::CeCosSocket (LPCTSTR pszHostPort,Duration dTimeout): +m_nDefaultTimeout(10*1000), +m_nSock(-1), +m_nClient(0) +{ + VTRACE(_T("Create socket instance %08x\n"),(unsigned int)this); + Connect(pszHostPort,dTimeout); +} + +bool CeCosSocket::Accept(int sock /*result of previous call of Listen*/, bool *pbStop) +{ + m_nSock=-1; + while(0==pbStop||!*pbStop){ + struct sockaddr cli_addr; +#ifndef _WIN32 + unsigned +#endif + int clilen=sizeof(struct sockaddr); + m_nSock=::accept(sock, (struct sockaddr *) &cli_addr, &clilen); + SaveError(); + if(-1==m_nSock){ + if(WOULDBLOCK==SocketError()){ + CeCosThreadUtils::Sleep(100); + continue; + } + } else { + memcpy(&m_nClient,cli_addr.sa_data+2,4); + TRACE(_T("Connection accepted from %s - socket %d\n"),(LPCTSTR )ClientName(m_nClient),m_nSock); + SetSocketOptions(); + break; + } + } + return -1!=m_nSock; +} + +int CeCosSocket::Listen(int nTcpPort) +{ + // Create socket + int sock=::socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + ERROR(_T("Couldn't create socket\n")); + } else { + VTRACE(_T("Created socket %d listening on port %d\n"),sock,nTcpPort); + // Bind socket to address + struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof serv_addr); + + serv_addr.sin_family = AF_INET; + serv_addr.sin_port=htons((short)nTcpPort); + serv_addr.sin_addr.s_addr = INADDR_ANY; + + if (::bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) { + TRACE(_T("Couldn't bind socket on port %d\n"),nTcpPort); + CloseSocket(sock); + } else if (-1==::listen(sock, SOMAXCONN)){ + CloseSocket(sock); + TRACE(_T("socket error on listen - port %d\n"),nTcpPort); + } else { +#ifdef _WIN32 + int nTrue=1; + bool rc=(0==::ioctlsocket(sock, FIONBIO, (unsigned long *)&nTrue)); +#else //UNIX + int flags=::fcntl(sock,F_GETFL); + flags|=O_NONBLOCK; + bool rc=(0==::fcntl (sock, F_SETFL, flags)); +#endif + if(!rc){ + TRACE(_T("Failed to set socket options on socket %d\n"),sock); + } + } + } + return sock; +} + +bool CeCosSocket::Connect(LPCTSTR pszHostPort,Duration dTimeout) +{ + dTimeout=TimeoutDuration(dTimeout); + struct sockaddr_in serv_addr; + + VTRACE(_T("Connect: %s timeout=%d\n"),pszHostPort,dTimeout); + + // Get the target host address + String strHost; + int nPort; + CeCosSocket::ParseHostPort(pszHostPort,strHost,nPort); + String strErr; + + char *ip=GetHostByName(strHost).GetCString(); + memset(&serv_addr, 0, sizeof serv_addr); + // Create socket + m_nSock = ::socket(AF_INET, SOCK_STREAM, 0); + if (-1 == m_nSock) { + TRACE(_T("Could not create socket [%s]\n"),pszHostPort); + } else { +#ifdef _WIN32 + SetSocketOptions(); +#endif + VTRACE(_T("Created socket %d connected to %s\n"),m_nSock,pszHostPort); + // Bind socket to address + serv_addr.sin_family = AF_INET; + serv_addr.sin_port=htons((short)nPort); + SaveError(); + serv_addr.sin_addr.s_addr = inet_addr(ip); + + // Connect to server + VTRACE(_T("Connect() : connecting to server\n")); + int cc=::connect(m_nSock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); + SaveError(); + String strMsg; + if(-1==cc){ + if( +#ifdef _WIN32 + WOULDBLOCK==SocketError() +#else // UNIX + EINPROGRESS==SocketError() +#endif + ){ + // Allow dTimeout milliseconds for connect to complete + fd_set set; + FD_ZERO(&set); +#ifdef _WIN32 +#pragma warning( push ) +#pragma warning( disable : 4127 ) // conditional expression is constant +#endif + FD_SET((unsigned)m_nSock, &set); +#ifdef _WIN32 +#pragma warning( pop ) +#endif + struct timeval tv; + tv.tv_sec = dTimeout/1000; + tv.tv_usec = 1000*(dTimeout % 1000); + switch(::select(m_nSock, NULL, &set , NULL, &tv)){ + case 0: + m_nErr=ERR_TIMEOUT; + strMsg.Format(_T("attempt timed out after %d seconds"),dTimeout/1000); + break; + case -1: + SaveError(); + strMsg=SocketErrString(); + break; + default: + cc=0; + } + } else { + strMsg=SocketErrString(); + } + } + + if(-1==cc){ + TRACE(_T("Could not connect to %s - %s\n"),pszHostPort,(LPCTSTR)strMsg); + CloseSocket(m_nSock); + } else { +#ifndef _WIN32 + SetSocketOptions(); +#endif + } + } + delete [] ip; + return -1!=m_nSock; +} + +bool CeCosSocket::sendrecv(bool bSend,const void *pData,unsigned int nLength, + LPCTSTR pszMsg,Duration dTimeout,CeCosSocket::StopFunc pFnStop,void *pParam) +{ + + dTimeout=TimeoutDuration(dTimeout); + + LPCTSTR pszSR=(bSend?_T("sending"):_T("receiving")); + LPTSTR c=(LPTSTR )pData; + Time ft0=Now(); + int nTodo=nLength; + while((nTodo>0) && ((0==pFnStop) || (!pFnStop(pParam)))){ + int s=bSend?::send(m_nSock, (const char *)c, nTodo, 0): ::recv(m_nSock, (char *)c, nTodo, 0); + if(0==s && !bSend){ + m_nErr=ERR_READ_AFTER_CLOSE; + } else { + SaveError(); + } + if(-1==s && WOULDBLOCK==SocketError()){ + Duration d=Duration(Now()-ft0); + if(d>dTimeout){ + TRACE(_T("%d/%d mSec timeout on socket %d %s %s - processed %d/%d bytes\n") , + d,dTimeout,m_nSock,pszSR,pszMsg, + nLength-nTodo,nLength); + m_nErr=ERR_TIMEOUT; + break; + } + CeCosThreadUtils::Sleep(100); + } else if (s>0) { + c+=s; + nTodo-=s; + ft0=Now(); + } else { + TRACE(_T("Error on socket %d %s %s - %s\n") ,m_nSock, pszSR, pszMsg, (LPCTSTR )SocketErrString()); + break; + } + } + return 0==nTodo; +} + +// Graceful socket closedown +CeCosSocket::~CeCosSocket() +{ + Close(); + VTRACE(_T("Delete socket instance %08x\n"),(unsigned int)this); +} + +bool CeCosSocket::CloseSocket(int &sock) +{ + bool rc=false; + if(-1!=sock){ + VTRACE(_T("Closing socket %d\n"),sock); + try{ + shutdown(sock,0);// SD_BOTH +#ifdef _WIN32 + rc=(0==closesocket(sock)); +#else // UNIX + rc=(0==close(sock)); +#endif + } + catch(...) { + TRACE(_T("!!! Exception caught in CeCosSocket::CloseSocket!!!\n")); + } + sock=-1; + } + return rc; +} + +bool CeCosSocket::SetSocketOptions() +{ + bool rc; +#ifdef _WIN32 + int nTrue=1; + rc=(0==::ioctlsocket(m_nSock, FIONBIO, (unsigned long *)&nTrue)); + SaveError(); +#else // UNIX + int flags=::fcntl(m_nSock,F_GETFL); + SaveError(); + flags|=O_NONBLOCK; + rc=(0==::fcntl (m_nSock, F_SETFL, flags)); + SaveError(); +#endif + int bLinger=0; + setsockopt(m_nSock,SOL_SOCKET,SO_LINGER,(const char *)&bLinger, sizeof(bLinger)); + if(!rc){ + TRACE(_T("Failed to set socket options socket %d - %s\n"),m_nSock,(LPCTSTR )SocketErrString()); + } + return rc; +} + +String CeCosSocket::SocketErrString(int nErr) +{ + String str; +#ifdef _WIN32 + switch(nErr){ + case ERR_TIMEOUT: str=_T("Read operation timed out");break; + case ERR_READ_AFTER_CLOSE: str=_T("Read operation after socket closed");break; + + case WSAEACCES: str=_T("Permission denied");break; + case WSAEADDRINUSE: str=_T("Address already in use");break; + case WSAEADDRNOTAVAIL: str=_T("Cannot assign requested address");break; + case WSAEAFNOSUPPORT: str=_T("Address family not supported by protocol family");break; + case WSAEALREADY: str=_T("Operation already in progress");break; + case WSAECONNABORTED: str=_T("Software caused connection abort");break; + case WSAECONNREFUSED: str=_T("Connection refused");break; + case WSAECONNRESET: str=_T("Connection reset by peer");break; + case WSAEDESTADDRREQ: str=_T("Destination address required");break; + case WSAEFAULT: str=_T("Bad address");break; + case WSAEHOSTDOWN: str=_T("Host is down");break; + case WSAEHOSTUNREACH: str=_T("No route to host");break; + case WSAEINPROGRESS: str=_T("Operation now in progress");break; + case WSAEINTR: str=_T("Interrupted function call");break; + case WSAEINVAL: str=_T("Invalid argument");break; + case WSAEISCONN: str=_T("Socket is already connected");break; + case WSAEMFILE: str=_T("Too many open files");break; + case WSAEMSGSIZE: str=_T("Message too long");break; + case WSAENETDOWN: str=_T("Network is down");break; + case WSAENETRESET: str=_T("Network dropped connection on reset");break; + case WSAENETUNREACH: str=_T("Network is unreachable");break; + case WSAENOBUFS: str=_T("No buffer space available");break; + case WSAENOPROTOOPT: str=_T("Bad protocol option");break; + case WSAENOTCONN: str=_T("Socket is not connected");break; + case WSAENOTSOCK: str=_T("Socket operation on non-socket");break; + case WSAEOPNOTSUPP: str=_T("Operation not supported");break; + case WSAEPFNOSUPPORT: str=_T("Protocol family not supported");break; + case WSAEPROCLIM: str=_T("Too many processes");break; + case WSAEPROTONOSUPPORT: str=_T("Protocol not supported");break; + case WSAEPROTOTYPE: str=_T("Protocol wrong type for socket");break; + case WSAESHUTDOWN: str=_T("Cannot send after socket shutdown");break; + case WSAESOCKTNOSUPPORT: str=_T("Socket type not supported");break; + case WSAETIMEDOUT: str=_T("Connection timed out");break; + case WSATYPE_NOT_FOUND: str=_T("Class type not found");break; + case WSAEWOULDBLOCK: str=_T("Resource temporarily unavailable");break; + case WSAHOST_NOT_FOUND: str=_T("Host not found");break; + case WSA_INVALID_HANDLE: str=_T("Specified event object handle is invalid");break; + case WSA_INVALID_PARAMETER: str=_T("One or more parameters are invalid");break; + //case WSAINVALIDPROCTABLE: str=_T("Invalid procedure table from service provider");break; + //case WSAINVALIDPROVIDER: str=_T("Invalid service provider version number");break; + case WSA_IO_INCOMPLETE: str=_T("Overlapped I/O event object not in signaled state");break; + case WSA_IO_PENDING: str=_T("Overlapped operations will complete later");break; + case WSA_NOT_ENOUGH_MEMORY: str=_T("Insufficient memory available");break; + case WSANOTINITIALISED: str=_T("Successful case WSAStartup not yet:performed");break; + case WSANO_DATA: str=_T("Valid name, no data record of requested type");break; + case WSANO_RECOVERY: str=_T("This is a non-recoverable error");break; + //case WSAPROVIDERFAILEDINIT: str=_T("Unable to initialize a service provider");break; + case WSASYSCALLFAILURE: str=_T("System call failure");break; + case WSASYSNOTREADY: str=_T("Network subsystem is unavailable");break; + case WSATRY_AGAIN: str=_T("Non-authoritative host not found");break; + case WSAVERNOTSUPPORTED: str=_T("WINSOCK.DLL version out of range");break; + case WSAEDISCON: str=_T("Graceful shutdown in progress");break; + case WSA_OPERATION_ABORTED: str=_T("Overlapped operation aborted");break; + default: + str.Format(_T("Unknown error %d (0x%08x)"),nErr,nErr); + } +#else // UNIX + switch(nErr){ + case ERR_TIMEOUT: str=_T("Read operation timed out");break; + case ERR_READ_AFTER_CLOSE: str=_T("Read operation after socket closed");break; + default: + str=strerror(errno); + } +#endif + return str; +} + +bool CeCosSocket::sendInteger(int n,LPCTSTR pszMsg,Duration dTimeout) +{ + // This has to support cross-architectural endianness + unsigned char c[sizeof(int)]; + for(unsigned int i=0;i>=8; + } + return send (c, sizeof(int),pszMsg,dTimeout); +} + +bool CeCosSocket::recvInteger(int & n,LPCTSTR pszMsg,Duration dTimeout) +{ + // This has to support cross-architectural endianness + unsigned char c[sizeof(int)]; + bool rc=recv (c, sizeof(int),pszMsg,dTimeout); + n=0; + if(rc){ + for(int i=sizeof(int)-1;i>=0;--i){ + n<<=8; + n|=c[i]; + } + } + return rc; +} + +// Socket communications for strings are always non-UNICODE: +bool CeCosSocket::recvString (String &str,LPCTSTR pszMsg,Duration dTimeout) +{ + int nLength; + bool rc=false; + if(recvInteger(nLength,pszMsg,dTimeout)){ + if(0==nLength){ + rc=true; + } else { + Buffer b(1+nLength); + char *c=(char *)b.Data(); + if(c){ + rc=recv(c,nLength,pszMsg,dTimeout); + c[nLength]='\0'; + str=String::CStrToUnicodeStr(c); + } + } + } + return rc; +} + +// Socket communications for strings are always non-UNICODE: +bool CeCosSocket::sendString (const String &str,LPCTSTR pszMsg,Duration dTimeout) +{ + char *psz=str.GetCString(); + int nLength=strlen(psz); + bool rc=sendInteger(nLength,pszMsg,dTimeout) && (0==nLength || send(psz,nLength,pszMsg,dTimeout)); + delete [] psz; + return rc; +} + + +// Give indication of bytes available to be read (but don't read them) +bool CeCosSocket::Peek (unsigned int &nAvail) +{ + char buf[8192]; + int n=::recv(m_nSock, buf, sizeof buf, MSG_PEEK); + nAvail=0; + bool rc=false; + switch(n) { + case -1: + SaveError(); + if(WOULDBLOCK==SocketError()){ + rc=true; // nAvail stays==0 + } else { + ERROR(_T("Peek: err=%d %s\n"),SocketError(),(LPCTSTR)SocketErrString()); + } + break; + case 0: + m_nErr=ERR_READ_AFTER_CLOSE; + break; + default: + rc=true; + nAvail=n; + } + return rc; +} + +// Connect tcp/ip port and serial port together. +// Traffic is passed through pFunc, passed parameter pParam. +// The pFunc function: +// may reallocate pBuf (using malloc/realloc etc...) +// must leave pBuf allocated on exit +// should not close either serial or socket +// should leave writing to its caller +// should return false if it wishes to terminate the connection (after caller has written output) +bool CeCosSocket::ConnectSocketToSerial (CeCosSocket &socket,CeCosSerial &serial,FilterFunc *pSerialToSocketFilterFunc/*=0*/,void *pSerialParam/*=0*/,FilterFunc *pSocketToSerialFilterFunc/*=0*/,void *pSocketParam/*=0*/,bool *pbStop/*=0*/) +{ + serial.ClearError(); + enum {BUFSIZE=8192}; + void *pBuf=malloc(BUFSIZE); + TRACE(_T("ConnectSocketToSerial: connected\n")); + bool rc=true; + try { + /* + { //hack + unsigned int nWritten;//hack + serial.Write(_T("+"),1,nWritten);//hack + }//hack + */ + while(rc && (0==pbStop || !(*pbStop))){ + unsigned int nRead=0; + switch(SSRead (serial,socket,pBuf,BUFSIZE,nRead,pbStop)){ + case SS_SERIAL_READ: + VTRACE(_T("Serial:%d\n"),nRead); + if(pSerialToSocketFilterFunc){ + rc=pSerialToSocketFilterFunc(pBuf,nRead,serial,socket,pSerialParam); + } + if(nRead && !socket.send(pBuf,nRead)){ + TRACE(_T("Failed to write to socket\n")); + rc=false; + } + break; + case SS_SOCKET_READ: + unsigned int nWritten; + VTRACE(_T("Socket:%d\n"),nRead); + if(pSocketToSerialFilterFunc){ + rc=pSocketToSerialFilterFunc(pBuf,nRead,serial,socket,pSocketParam); + } + { + LPTSTR c=(LPTSTR )pBuf; + int nToWrite=nRead; + while(nToWrite>0){ + if(!serial.Write(pBuf,nRead,nWritten)){ + TRACE(_T("Failed to write to serial\n")); + rc=false; + break; + } + nToWrite-=nWritten; + c+=nWritten; + } + } + break; + // Error conditions: + case SS_SERIAL_ERROR: + TRACE(_T("SSRead serial error - %s\n"),(LPCTSTR)serial.ErrString()); + rc=false; + break; + case SS_SOCKET_ERROR: + TRACE(_T("SSRead socket error - %s\n"),(LPCTSTR)socket.SocketErrString()); + rc=false; + break; + case SS_STOPPED: + TRACE(_T("SSRead stopped\n")); + rc=false; + break; + } + } + } + catch (...){ + ERROR(_T("!!! ConnectSocketToSerial exception caught!!!\n")); + free(pBuf); + throw; + } + free(pBuf); + return rc; +} + +// Connect two tcp/ip ports together. +// Traffic is passed through pFunc, passed parameter pParam. +// The pFunc function: +// may reallocate pBuf (using malloc/realloc etc...) +// must leave pBuf allocated on exit +// should not close either serial or socket +// should leave writing to its caller +// should return false if it wishes to terminate the connection (after caller has written output) +bool CeCosSocket::ConnectSocketToSocket (CeCosSocket &o,FilterFunc *pSocketToSocketFilterFunc1,FilterFunc *pSocketToSocketFilterFunc2,void *pParam,bool *pbStop) +{ + enum {BUFSIZE=8192}; + void *pBuf=malloc(BUFSIZE); + TRACE(_T("ConnectSocketToSocket: connected\n")); + bool rc=true; + try { + while(rc && (0==pbStop || !(*pbStop))){ + fd_set set; + FD_ZERO(&set); + FD_SET((unsigned)m_nSock, &set); + FD_SET((unsigned)o.m_nSock, &set); + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + switch(::select(m_nSock,&set,0,0,&tv)){ + case -1: + rc=false; + break; + case 1: + case 2: + { + unsigned int nAvail=0; + if(FD_ISSET((unsigned)m_nSock, &set) && Peek(nAvail) && recv(pBuf,nAvail)){ + //rc=pSocketToSocketFilterFunc1(pBuf,nAvail,socket,this,o); + o.send(pBuf,nAvail); + } + if(FD_ISSET((unsigned)o.m_nSock, &set) && o.Peek(nAvail) && o.recv(pBuf,nAvail)){ + //rc=pSocketToSocketFilterFunc2(pBuf,nAvail,socket,o,this); + send(pBuf,nAvail); + } + } + case 0: + break; + } + } + } + catch (...){ + TRACE(_T("!!! ConnectSocketToSocket exception caught!!!\n")); + rc=false; + } + free(pBuf); + return rc; +} + +bool CeCosSocket::ConnectSocketToSerial ( + int nListenSock,LPCTSTR pszPort, int nBaud, + FilterFunc *pSerialToSocketFilterFunc/*=0*/,void *pSerialParam/*=0*/,FilterFunc *pSocketToSerialFilterFunc/*=0*/,void *pSocketParam/*=0*/, + bool *pbStop) +{ + bool rc=false; + try{ + TRACE(_T("ConnectSocketToSerial : socket %d <--> %s\n"),nListenSock,pszPort); + + CeCosSerial serial; + serial.SetBlockingReads(false); + // Open serial device. + if (!serial.Open(pszPort,nBaud)){ + ERROR(_T("Couldn't open port %s\n"),pszPort); + } else { + // Flush the serial buffer. + serial.Flush(); + + TRACE(_T("ConnectSocketToSerial: waiting for connection...\n")); + CeCosSocket socket; + if(!socket.Accept(nListenSock,pbStop)){ + ERROR(_T("ConnectSocketToSerial - couldn't accept\n")); + } else { + rc=ConnectSocketToSerial (socket,serial,pSerialToSocketFilterFunc,pSerialParam,pSocketToSerialFilterFunc,pSocketParam,pbStop); + } + } + TRACE(_T("ConnectSocketToSerial : done\n")); + } + catch(...){ + TRACE(_T("ConnectSocketToSerial !!!exception handled!!!\n")); + } + return rc; +} + +String CeCosSocket::ClientName(int nClient) +{ + char ip[4]; + memcpy(ip,&nClient,4); + struct hostent *he=::gethostbyaddr((const char *)ip,4,AF_INET); + String str; + if(he){ + str=String::CStrToUnicodeStr(he->h_name); + } else { + str.Format(_T("%u.%u.%u.%u"),ip[0],ip[1],ip[2],ip[3]); + } + return str; +} + +String CeCosSocket::HostPort(LPCTSTR pszHost,int nPort) +{ + String str; + str.Format(_T("%s:%d"),pszHost,nPort); + return str; +} + +// Split the string into host:port parts. Result tells us whether it was successful. +bool CeCosSocket::ParseHostPort (LPCTSTR pszHostPort, String &strHost, int &nPort) +{ + int n=_stscanf(pszHostPort,_T("%[^:]:%d"),strHost.GetBuffer(_tcslen(pszHostPort)),&nPort); + strHost.ReleaseBuffer(); + return 2==n && nPort>0 && nPort<=0xffff; +} + +// Is the string in the form host:port? +bool CeCosSocket::IsLegalHostPort (LPCTSTR pszHostPort) +{ + int nPort=0; + String strHost; + return ParseHostPort(pszHostPort,strHost,nPort); +} + +// Translate a timeout that may be one of the special values DEFAULTTIMEOUT or NOTIMEOUT to a value in milliseconds. +Duration CeCosSocket::TimeoutDuration(Duration dTimeout) +{ + switch(dTimeout){ + case DEFAULTTIMEOUT: + dTimeout=m_nDefaultTimeout; + break; + case NOTIMEOUT: + dTimeout=0x7fffffff; + break; + default: + break; + } + return dTimeout; +} + +String CeCosSocket::SocketErrString() { + return SocketErrString(m_nErr); +} + + +bool CeCosSocket::SameHost(LPCTSTR host1, LPCTSTR host2) +{ + return 0==_tcscmp(host1,host2) || (GetHostByName(host1)==GetHostByName(host2)); +} + +bool CeCosSocket::Init() +{ +#ifdef _WIN32 + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD( 2, 0 ); + WSAStartup( wVersionRequested, &wsaData ); +#endif + return true; +} + +void CeCosSocket::Term() +{ +#ifdef _WIN32 + WSACleanup(); +#endif +} + +LPCTSTR CeCosSocket::MyHostName() +{ + static String str; + if(str.empty()){ + char szMyname[256]; + if(0==gethostname(szMyname,sizeof szMyname)){ + str=String::CStrToUnicodeStr(szMyname); + } + } + return str; +} + +LPCTSTR CeCosSocket::MySimpleHostName() +{ + static String str; + if(str.empty()){ + str=MyHostName(); + // Remove all after a '.' + LPCTSTR c=_tcschr(str,_TCHAR('.')); + if(c){ + str.resize(c-(LPCTSTR)str); + } + } + return str; +} + +const String CeCosSocket::GetHostByName(LPCTSTR pszHost) +{ + typedef std::map MapStringToString; + static MapStringToString hostmap; + MapStringToString::iterator it=hostmap.find(pszHost); + if(hostmap.end()==it){ + char *h=0; // avoid erroneous gcc warning message + h=String(pszHost).GetCString(); + char ip[16]; + struct hostent* host_dat; + if (0!=(host_dat=::gethostbyname(h))){ + char *c=inet_ntoa( *( (struct in_addr *)host_dat->h_addr_list[0] ) ); + if(c){ + strcpy(ip,c); + hostmap[pszHost]=String::CStrToUnicodeStr(ip); + } + } + delete [] h; + return String::CStrToUnicodeStr(ip); + } else { + return it->second; + } +} + + \ No newline at end of file diff --git a/host/tools/Utils/common/eCosSocket.h b/host/tools/Utils/common/eCosSocket.h new file mode 100644 --- /dev/null +++ b/host/tools/Utils/common/eCosSocket.h @@ -0,0 +1,195 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//================================================================= +// +// eCosSocket.h +// +// Socket test class +// +//================================================================= +//================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contributors: sdf +// Date: 1999-04-01 +// Description: This class abstracts tcp/ip sockets for use in the testing infrastructure +// Usage: +// +//####DESCRIPTIONEND#### +//================================================================= +// This class is a host-independent interface to a TCP/IP socket +// There are two flavours of socket - server and client. +// Server sockets listen (accept) on a socket number. Client sockets connect to a host:port. +// The class can be used thus: +// Server: +// CeCosSocket sock; // no-argument ctor +// if(-1!=sock.Listen(6000)){ +// ... +// } +// Client: +// CeCosSocket sock; +// if(sock.Connect(_T("ginga"),5000)){ +// ... +// } +// In each of the above cases the socket is closed automatically by the dtor. +// +// Alternatively, the ctor can be used directly: +// Server: +// CeCosSocket sock(6000)); +// ... +// Client: +// CeCosSocket sock(_T("ginga"),5000)); +// ... +// +//================================================================= +#include "eCosStd.h" +#include "Collections.h" + +#ifndef _SOCKETUTILS_H +#define _SOCKETUTILS_H + +class CeCosSerial; + +class CeCosSocket { +public: + static const String GetHostByName(LPCTSTR pszHost); + + // These functions must be called before any other operation is carried out: + static bool Init(); + static void Term(); + + typedef bool (CALLBACK FilterFunc)(void *&,unsigned int &,CeCosSerial&,CeCosSocket &,void *); + + // A function that causes an operation to stop - i.e. it when it returns true the operation is aborted. + typedef bool (CALLBACK StopFunc)(void *); + + enum {NOTIMEOUT=0x7fffffff-1,DEFAULTTIMEOUT=-2}; // No explicit timeout specified + + // Listen and this form of constructor used to act as server + static int Listen(int nTcpPort); + CeCosSocket (); // Caller promises to call Accept() or Connect() later + + // Accept-like ctor (act as server) + CeCosSocket (int sock /*result of previous call of Listen*/, bool *pbStop=0); + // Connect-like ctor (act as client) + CeCosSocket (LPCTSTR pszHostPort,Duration dTimeout=NOTIMEOUT); + + bool Accept(int sock /*result of previous call of Listen*/, bool *pbStop=0); + // This form of constructor used to act as client + bool Connect(LPCTSTR pszHostPort,Duration dTimeout=NOTIMEOUT); + ~CeCosSocket(); + + int Client() const { return m_nClient; } + static String ClientName(int nClient); + + int Sock() const { return m_nSock; } + + // Set the default timeout for all operations + void SetTimeout (Duration dTimeout) { m_nDefaultTimeout=dTimeout; } + + // Use to test success after opening with the ctor: + bool Ok() { return -1!=m_nSock; } + + // Close the given socket + bool Close () { return CloseSocket(m_nSock); } + + // Return last error on this socket + int SocketError() { return m_nErr; } + + // Return last socket error, translated to a string + String SocketErrString(); + static String SocketErrString(int nErr); + + // Read and write functions + + // Untyped: these versions allow the operation to be aborted either by timeout or by the "stop func" returning true. + bool send(const void *pData,unsigned int nLength,LPCTSTR pszMsg=_T(""),int dTimeout=DEFAULTTIMEOUT,StopFunc *pFunc=0,void *pParam=0){ + return sendrecv(true,pData,nLength,pszMsg,dTimeout,pFunc,pParam); + } + bool recv(const void *pData,unsigned int nLength,LPCTSTR pszMsg=_T(""),int dTimeout=DEFAULTTIMEOUT,StopFunc *pFunc=0,void *pParam=0){ + return sendrecv(false,pData,nLength,pszMsg,dTimeout,pFunc,pParam); + } + + // Read/write an integer (this can be used between machines of different endianness) + bool recvInteger (int &n,LPCTSTR pszMsg=_T(""),Duration dTimeout=DEFAULTTIMEOUT); + bool sendInteger (int n,LPCTSTR pszMsg=_T(""),Duration dTimeout=DEFAULTTIMEOUT); + + // Read/write a string + bool recvString (String &str,LPCTSTR pszMsg=_T(""),Duration dTimeout=DEFAULTTIMEOUT); + bool sendString (const String &str,LPCTSTR pszMsg=_T(""),Duration dTimeout=DEFAULTTIMEOUT); + + static bool CloseSocket (int &sock); + bool Peek (unsigned int &nAvail); + + // Miscellaneous helper functions: + + // Combine string and integer to the form host:port: + static String HostPort(LPCTSTR pszHost,int nPort); + // Decompose (opposite of the above): + static bool ParseHostPort (LPCTSTR pszHostPort, String &pszHost, int &nPort); + // Just check for legality: + static bool IsLegalHostPort (LPCTSTR pszHostPort); + // Are these two hosts really the same? + static bool SameHost (LPCTSTR host1,LPCTSTR host2); + // Set up a connection between a serial port and a socket. Traffic is simply passed between them. + static bool ConnectSocketToSerial (int nListenSock,LPCTSTR pszPort, int nBaud,FilterFunc *pSerialToSocketFilterFunc=0,void *pSerialParam=0,FilterFunc *pSocketToSerialFilterFunc=0,void *pSocketParam=0,bool *pbStop=0); + static bool ConnectSocketToSerial (CeCosSocket &socket,CeCosSerial &serial,FilterFunc *pSerialToSocketFilterFunc=0,void *pSerialParam=0, FilterFunc *pSocketToSerialFilterFunc=0,void *pSocketParam=0,bool *pbStop=0); + + static LPCTSTR MyHostName(); + static LPCTSTR MySimpleHostName(); + + // Set up a connection between two sockets. Traffic is simply passed between them. + bool ConnectSocketToSocket (CeCosSocket &o,FilterFunc *pSocketToSocketFilterFunc1,FilterFunc *pSocketToSocketFilterFunc2,void *pParam,bool *pbStop); + +protected: + + // Blocking read on one or other of the data sources: + // Result: -1 - socket error occurred + // 1 - data read from socket + // -2 - serial error occurred + // 2 - data read from serial + + enum SSReadResult {SS_SOCKET_ERROR=-1,SS_SOCKET_READ=1,SS_SERIAL_ERROR=-2,SS_SERIAL_READ=2,SS_STOPPED=0}; + static SSReadResult SSRead (CeCosSerial &serial,CeCosSocket &socket,void *pBuf,unsigned int nSize,unsigned int &nRead,bool *pbStop); + + Duration m_nDefaultTimeout; + Duration TimeoutDuration (Duration dTimeout); + // Set appropriate socket options (most importantly, non-blocking mode) + bool SetSocketOptions (); + int m_nSock; + int m_nClient; + int m_nErr; + void SaveError() { +#ifdef _WIN32 + m_nErr=WSAGetLastError(); +#else // UNIX + m_nErr=errno; +#endif + } + bool sendrecv(bool bSend,const void *pData,unsigned int nLength,LPCTSTR pszMsg=_T(""),int dTimeout=DEFAULTTIMEOUT,StopFunc *pFunc=0,void *pParam=0); + +}; +#endif diff --git a/host/tools/Utils/common/eCosStd.h b/host/tools/Utils/common/eCosStd.h --- a/host/tools/Utils/common/eCosStd.h +++ b/host/tools/Utils/common/eCosStd.h @@ -27,22 +27,24 @@ // Author(s): sdf // Contributors: sdf // Date: 1999-04-01 -// Description: Standard include file for test infra +// Description: Standard include file - include file // Usage: // //####DESCRIPTIONEND#### +// ---------------------------------------------------------------------------- +// This header sets us up with what is generally needed, both for WIN32 and UNIX +// Apart from header includes it defines the time-related quantities: +// Time - type to measure an absolute time +// Duration - type to measure the difference between two times, or a delay +// Now() - the time now. +// MIN and MAX +// LogFunc - a function to which output can be sent +// ---------------------------------------------------------------------------- + #if !defined(AFX_STDAFX_H__F20BA9C4_CFD5_11D2_BF75_00A0C949ADAC__INCLUDED_) #define AFX_STDAFX_H__F20BA9C4_CFD5_11D2_BF75_00A0C949ADAC__INCLUDED_ -#ifndef CYG_UNUSED_PARAM - #ifdef _WIN32 - #define CYG_UNUSED_PARAM( _name_ ) _name_ - #else // UNIX - #define CYG_UNUSED_PARAM( _name_ ) { void * __tmp1 = &(_name_); __tmp1 = 0; } - #endif -#endif - #ifdef _WIN32 #ifdef _UNICODE #ifndef UNICODE @@ -63,61 +65,47 @@ #ifndef _WINDOWS_ #include #endif - #include - #include #include #define cPathsep _TCHAR('\\') #include #include - #include - #define POPEN _tpopen - #define PCLOSE _pclose #include // _heapchk - //#define CHECKHEAP CeCosTestUtils::EnterCriticalSection();assert(_HEAPOK==_heapchk());CeCosTestUtils::LeaveCriticalSection() - #define CHECKHEAP assert(_HEAPOK==_heapchk()) - #define CLOSESOCKET(s) if(-1!=s)closesocket(s);s=-1 #define CALLBACK __stdcall // Calling conventions for a callback #define WOULDBLOCK WSAEWOULDBLOCK // "Would blocking" error #define errno (*_errno()) #define vsnprintf _vsnprintf - #define Sleep(mSec) ::Sleep(mSec) #pragma warning (disable:4710) // Not inlined warning typedef __int64 Time; + #define MODE_TEXT _T("t") #else // UNIX #include #include - #include #include #include - #include #include - #include #include // socket etc... #include // inet_addr #include // inet_addr #include // gethostbyname - #include #include #include - #include #define cPathsep '/' + #include // malloc #include // atoi #include - #define POPEN popen - #define PCLOSE pclose - #define CHECKHEAP - #define CLOSESOCKET(s) if(-1!=s)close(s);s=-1 #define WOULDBLOCK EWOULDBLOCK #define CALLBACK #include "wcharunix.h" + #include #define _stat stat - #define Sleep(nMsec) usleep((int)nMsec * 1000); + typedef long long Time; + #define MODE_TEXT #endif #define ECOS_VERSION "1.3.2" @@ -137,11 +125,9 @@ extern int MAX(int a, int b); #include #include #include -#include #include #include #include -#include #include #include // vsnprintf diff --git a/host/tools/Utils/common/eCosThreadUtils.cpp b/host/tools/Utils/common/eCosThreadUtils.cpp --- a/host/tools/Utils/common/eCosThreadUtils.cpp +++ b/host/tools/Utils/common/eCosThreadUtils.cpp @@ -90,7 +90,6 @@ bool CeCosThreadUtils::RunThread(Callbac DWORD dwID; HANDLE hThread=CreateThread(NULL,0,SThreadFunc, pInfo, 0, &dwID); if(hThread){ - TRACE(_T("RunThread: - new thread=%x\n"),dwID); ::CloseHandle(hThread); rc=true; } else { @@ -100,16 +99,13 @@ bool CeCosThreadUtils::RunThread(Callbac #ifdef NO_THREADS assert(false); #else - VTRACE(_T("RunThread():Calling pthread_create()\n")); pthread_t hThread; int n=pthread_create(&hThread, NULL, SThreadFunc, pInfo); TRACE( _T("RunThread: - non-blocking call (new thread=%x)\n"),hThread); - VTRACE(_T("RunThread(): pthread_create() returned <%d>\n"), n); if (n != 0) { ERROR(_T("RunThread(): pthread_create failed - %s\n"),strerror(errno)); } else { - VTRACE(_T("RunThread(): Calling pthread_detach\n")); int n = pthread_detach(hThread); if (0==n) { @@ -119,7 +115,6 @@ bool CeCosThreadUtils::RunThread(Callbac hThread=0; } } - VTRACE(_T("RunThread(): returned from pthread calls - exiting RunThread()\n")); #endif #endif if(!rc){ @@ -149,8 +144,9 @@ int CALLBACK CeCosThreadUtils::FilterFun CeCosThreadUtils::THREADFUNC CALLBACK CeCosThreadUtils::SThreadFunc (void *pParam) { - VTRACE(_T("SThreadFunc()\n")); + THREAD_ID id=GetThreadId(); ThreadInfo *pInfo=(ThreadInfo*)pParam; + TRACE(_T("Thread %x [%s] created\n"),id,(LPCTSTR)pInfo->strName); #ifdef _WIN32 __try { // Call what we are instructed to (e.g. LocalThreadFunc): @@ -171,7 +167,6 @@ CeCosThreadUtils::THREADFUNC CALLBACK Ce #endif // Call the Callback: - TRACE(_T("SThreadFunc - invoking callback\n")); if(pInfo->pCompletionFunc){ pInfo->pCompletionFunc (pInfo->pCompletionParam); } else if (pInfo->pCompletionParam) { @@ -179,13 +174,17 @@ CeCosThreadUtils::THREADFUNC CALLBACK Ce *(bool *)pInfo->pCompletionParam=true; } // No more references to pInfo->pTest from now on... - VTRACE(_T("SThreadFunc(): deleting (ThreadInfo)pInfo\n")); - delete pInfo; - TRACE(_T("SThreadFunc exiting\n")); + TRACE(_T("Thread %x [%s] terminated\n"),id,(LPCTSTR)pInfo->strName); + delete pInfo; return 0; } -int CeCosThreadUtils::CS::AtomicIncrement (int &n) +bool CeCosThreadUtils::CS::InCriticalSection() +{ + return GetThreadId()==nCSOwner; +} + +int CeCosThreadUtils::AtomicIncrement (int &n) { int rc; ENTERCRITICAL; @@ -194,7 +193,7 @@ int CeCosThreadUtils::CS::AtomicIncremen return rc; } -int CeCosThreadUtils::CS::AtomicDecrement (int &n) +int CeCosThreadUtils::AtomicDecrement (int &n) { int rc; ENTERCRITICAL; @@ -207,8 +206,7 @@ CeCosThreadUtils::CS::CS() { // Get mutex lock; block until available unless current // thread already owns the mutex. - if(GetThreadId()!=nCSOwner){ - VTRACE(_T("%x try CS\n"),GetThreadId()); + if(!InCriticalSection()){ #ifdef _WIN32 if(!bCSInitialized){ InitializeCriticalSection(&cs); @@ -220,19 +218,22 @@ CeCosThreadUtils::CS::CS() pthread_mutex_lock(&cs); #endif #endif + // As we now own the CS it is safe to perform the following assignment: nCSOwner=GetThreadId(); - VTRACE(_T("%x has CS count=%d\n"),GetThreadId(),m_nCriticalSectionLock);//sdf } + // As we now own the CS it is safe to perform the following increment: m_nCriticalSectionLock++; } CeCosThreadUtils::CS::~CS() { + assert(InCriticalSection()); + // As we own the CS we can safely manipulate variables: m_nCriticalSectionLock--; assert(m_nCriticalSectionLock>=0); if(0==m_nCriticalSectionLock){ + // Last lock is being released - let go of the mutex nCSOwner=(THREAD_ID)-1; - VTRACE(_T("%x leaves CS count=%d\n"),GetThreadId(),m_nCriticalSectionLock); // Release mutex lock. #ifdef _WIN32 @@ -245,3 +246,12 @@ CeCosThreadUtils::CS::~CS() } } +void CeCosThreadUtils::Sleep(int nMsec) +{ +#ifdef _WIN32 + ::Sleep(nMsec); +#else + sched_yield(); + usleep((int)nMsec * 1000); +#endif +} diff --git a/host/tools/Utils/common/eCosThreadUtils.h b/host/tools/Utils/common/eCosThreadUtils.h --- a/host/tools/Utils/common/eCosThreadUtils.h +++ b/host/tools/Utils/common/eCosThreadUtils.h @@ -43,8 +43,6 @@ #define _ECOSTHREADUTILS_H #include "eCosStd.h" #include "Collections.h" -#define ENTERCRITICAL {CeCosThreadUtils::CS c -#define LEAVECRITICAL } #ifndef _WIN32 // UNIX #ifndef NO_THREADS @@ -52,10 +50,15 @@ #endif #endif +//================================================================= +// This class handles threads in a host-independent manner. +// It also contains a few thread-related functions such as Sleep +//================================================================= + class CeCosThreadUtils { public: + #ifdef _WIN32 - static int CALLBACK FilterFunction(LPEXCEPTION_POINTERS p); typedef DWORD THREAD_ID; #else // UNIX #ifndef NO_THREADS @@ -64,38 +67,48 @@ public: typedef pthread_t THREAD_ID; #endif #endif - static THREAD_ID GetThreadId(); + + static THREAD_ID GetThreadId(); // Get my current thread ID, mostly for debugging + // CS supports a single system-wide critical sections (recursive mutexes). + // You are expected to use macros ENTERCRITICAL and LEAVECRITICAL to use this class - these macros define + // a block containing a CS object, which has the effect of creating a critical section. + // Exit from the block (by whatever means, including an exception) causes the CS dtor + // to be called so as to release the section. + class CS{ - // p and q routines (process-local recursive mutexes) + public: + static bool InCriticalSection(); // This thread owns the critical section + CS(); + virtual ~CS(); + protected: + static int m_nCriticalSectionLock; // The number of times the recursive mutex has been locked. Management of this allows us to avoid use of true recursive mutexes on UNIX. + static THREAD_ID nCSOwner; // The thread owning the resource. #ifdef _WIN32 - static CRITICAL_SECTION cs; + static CRITICAL_SECTION cs; // The one and only critical section static bool bCSInitialized; #else // UNIX #ifndef NO_THREADS - // Static recursive mutex for unix critical section - static pthread_mutex_t cs; + static pthread_mutex_t cs; // The one and only critical section #endif #endif - - public: - - static int m_nCriticalSectionLock; - static THREAD_ID nCSOwner; - - static int AtomicIncrement (int &n); // return old value - static int AtomicDecrement (int &n); // return old value - CS(); - virtual ~CS(); }; + + #define ENTERCRITICAL {CeCosThreadUtils::CS c + #define LEAVECRITICAL } + + static int AtomicIncrement (int &n); // return old value + static int AtomicDecrement (int &n); // return old value + // Wait for this boolean to become true, subject to the given timeout + // If the timeout happens first, the return code will be false - otherwise true static bool WaitFor (bool &b, int dTimeout=0x7fffffff); /////////////////////////////////////////////////////////////////////////// // Define the characteristics of a callback procedure: - // A callback procedure: + // A callback procedure, used both for thread entry points and thread completion callbacks typedef void (CALLBACK CallbackProc)(void *); // Run a thread: pThreadFunc is the entry point (passed pParam). No notification of completion. @@ -105,22 +118,21 @@ public: // Run a thread, calling the callback on completion static bool RunThread(CallbackProc *pThreadFunc, void *pParam, CallbackProc *pCompletionFunc, LPCTSTR pszName=_T("")) { return RunThread(pThreadFunc,pParam,pCompletionFunc,pParam,pszName); } + static void Sleep (int nMsec); + protected: - // If m_pProc is non-zero then it is called - // If m_pProc is 0 and m_pParam is non-0 then the callback sets the boolean whose address is held in m_pParam - // If m_pProc is 0 and m_pParam is 0 then the callback is "blocking" - //bool IsBlocking() const { return 0==m_pProc && 0==m_pParam; } - // Run a thread: arbitrary callbcak static bool RunThread(CallbackProc *pThreadFunc, void *pParam, CallbackProc *pCompletionFunc, void *pCompletionParam, LPCTSTR pszName); + // This is the information that is passed to the host-specific thread proc. It is simply enough to call the thread entry point and + // call the callback (or set the boolean) at the end. struct ThreadInfo { - CallbackProc *pThreadFunc; - void *pThreadParam; - CallbackProc *pCompletionFunc; // Call this function - void *pCompletionParam; // With this parameter - String strName; + CallbackProc *pThreadFunc; // The thread proc is this function + void *pThreadParam; // - called with this parameter + CallbackProc *pCompletionFunc; // At the end - call this function + void *pCompletionParam; // with this parameter + String strName; // For debugging ThreadInfo (CallbackProc *_pThreadFunc,void *_pThreadParam,CallbackProc *_pCompletionFunc,void *_pCompletionParam,LPCTSTR pszName) : pThreadFunc(_pThreadFunc), pThreadParam(_pThreadParam), @@ -129,9 +141,10 @@ protected: strName(pszName){} }; - // Result type of the thread function + // THREADFUNC is the result type of the thread function #ifdef _WIN32 typedef unsigned long THREADFUNC; + static int CALLBACK FilterFunction(LPEXCEPTION_POINTERS p); #else // UNIX typedef void * THREADFUNC; #endif diff --git a/host/tools/Utils/common/eCosTrace.cpp b/host/tools/Utils/common/eCosTrace.cpp --- a/host/tools/Utils/common/eCosTrace.cpp +++ b/host/tools/Utils/common/eCosTrace.cpp @@ -35,7 +35,7 @@ #include "eCosThreadUtils.h" #include "eCosTrace.h" -bool CeCosTrace::bVerbose=false; +CeCosTrace::TraceLevel CeCosTrace::nVerbosity=CeCosTrace::TRACE_LEVEL_ERRORS; bool CeCosTrace::bInteractive=false; LPCTSTR CeCosTrace::arpszDow[7]={_T("Su"),_T("M"),_T("Tu"),_T("W"),_T("Th"),_T("F"),_T("Sa")}; @@ -58,12 +58,12 @@ void CALLBACK CeCosTrace::StreamLogFunc( bool CeCosTrace::SetOutput(LPCTSTR pszFilename) { - FILE *f=_tfopen(pszFilename,_T("at")); + FILE *f=_tfopen(pszFilename,_T("a") MODE_TEXT); if(f){ - if(OutInfo.strFilename.GetLength()>0){ + if(!OutInfo.strFilename.empty()){ fclose(OutInfo.f); } - if(bVerbose){ + if(nVerbosity>=TRACE_LEVEL_TRACE){ _ftprintf(stderr,_T("Output -> %s (%08x)\n"),pszFilename,(unsigned int)f); } OutInfo.f=f; @@ -75,9 +75,9 @@ bool CeCosTrace::SetOutput(LPCTSTR pszFi bool CeCosTrace::SetError(LPCTSTR pszFilename) { - FILE *f=_tfopen(pszFilename,_T("at")); + FILE *f=_tfopen(pszFilename,_T("a") MODE_TEXT); if(f){ - if(ErrInfo.strFilename.GetLength()>0){ + if(!ErrInfo.strFilename.empty()){ fclose(ErrInfo.f); } ErrInfo.f=f; @@ -92,14 +92,14 @@ void CALLBACK CeCosTrace::StreamInfoFunc StreamInfo *pInfo=(StreamInfo *)pParam; ENTERCRITICAL; _fputts(psz,pInfo->f); - if(pInfo->strFilename.GetLength()>0 && Now()-pInfo->tLastReopen>20*1000){ + if(!pInfo->strFilename.empty() && Now()-pInfo->tLastReopen>20*1000){ // SAMBA clients will not honor fflush(), so we do this: fclose(pInfo->f); do { - pInfo->f=_tfopen(pInfo->strFilename,_T("at")); + pInfo->f=_tfopen(pInfo->strFilename,_T("a") MODE_TEXT); if(NULL==pInfo->f){ _ftprintf(stderr,_T("Failed to reopen %s\n"),(LPCTSTR)pInfo->strFilename); - Sleep(1000); + CeCosThreadUtils::Sleep(1000); } } while (NULL==pInfo->f); pInfo->tLastReopen=Now(); @@ -109,19 +109,7 @@ void CALLBACK CeCosTrace::StreamInfoFunc LEAVECRITICAL; } -void CeCosTrace::Trace(LPCTSTR pszFormat, ...) -{ - if(bVerbose){ - va_list marker; - va_start (marker, pszFormat); - String str; - str.vFormat(pszFormat,marker); - va_end (marker); - Error(_T("%s"),(LPCTSTR)str); - } -} - -void CeCosTrace::Error(LPCTSTR pszFormat, ...) +void CeCosTrace::TimeStampedErr(LPCTSTR pszFormat,...) { va_list marker; va_start (marker, pszFormat); @@ -129,18 +117,19 @@ void CeCosTrace::Error(LPCTSTR pszFormat str.vFormat(pszFormat,marker); va_end (marker); + Err(String::SFormat(_T("%s %s"),(LPCTSTR)Timestamp(),(LPCTSTR)str)); +} + +const String CeCosTrace::Timestamp() +{ time_t ltime; time(<ime); struct tm *now=localtime( <ime ); - String s; - CeCosThreadUtils::THREAD_ID id=CeCosThreadUtils::GetThreadId(); - s.Format(_T("[%x %s %02d:%02d:%02d%s] %s"),id, - arpszDow[now->tm_wday],now->tm_hour,now->tm_min,now->tm_sec,CeCosThreadUtils::CS::nCSOwner==id?_T("*"):_T(""),(LPCTSTR)str); - if(_TCHAR('\n')!=s[s.GetLength()-1]){ - s+=_TCHAR('\n'); - } - Err(s); + bool bInCriticalSection=CeCosThreadUtils::CS::InCriticalSection(); + TCHAR c1=bInCriticalSection?_TCHAR('<'):_TCHAR('['); + TCHAR c2=bInCriticalSection?_TCHAR('>'):_TCHAR(']'); + return String::SFormat(_T("%c%3x %s %02d:%02d:%02d%c"),c1,CeCosThreadUtils::GetThreadId(), + arpszDow[now->tm_wday],now->tm_hour,now->tm_min,now->tm_sec,c2); + } - - diff --git a/host/tools/Utils/common/eCosTrace.h b/host/tools/Utils/common/eCosTrace.h --- a/host/tools/Utils/common/eCosTrace.h +++ b/host/tools/Utils/common/eCosTrace.h @@ -32,6 +32,14 @@ // //####DESCRIPTIONEND#### +//================================================================= +// This class handles output of errors, debugging trace and so on. All its members are static, so it's really a namespace :-). +// It handles two output streams - error and output - and allows these to be redirected independently to files etc... +// Part of the justification for this (which might be carried out on the command line) involves shortcomings of +// SAMBA client, which deals badly with the flushing of file buffers. +// The definition of LogFunc, which defines a function (void *,LPCTSTR) to which output is sent, is in eCosStd. +//================================================================= + #ifndef _ECOSTRACE_H #define _ECOSTRACE_H #include "eCosStd.h" @@ -39,40 +47,47 @@ class CeCosTrace { public: + static const String Timestamp(); // Diagnostic output static void Out(LPCTSTR psz) { pfnOut(pOutParam,psz); } - static void Err(LPCTSTR psz) { pfnError(pErrorParam,psz); } - - static void Trace (LPCTSTR pszFormat,...); - static void Error (LPCTSTR pszFormat,...); + static void Err(LPCTSTR psz) { pfnError(pErrorParam,psz); } // Send to "stderr" + static void TimeStampedErr(LPCTSTR pszFormat,...); - static void EnableTracing(bool b) { bVerbose=b; } - static bool IsTracingEnabled () { return bVerbose; } + enum TraceLevel {TRACE_LEVEL_ERRORS, TRACE_LEVEL_TRACE, TRACE_LEVEL_VTRACE}; // These are the levels of trace + + // Here's how to set and get the current trace value: + static void EnableTracing(TraceLevel n) { nVerbosity=n; } + static TraceLevel TracingEnabled() { return nVerbosity; } - static void SetInteractive(bool b) { bInteractive=b; } + static void SetInteractive(bool b) { bInteractive=b; } // Declare this program to be "interactive" (usually means command-line) static bool IsInteractive() { return bInteractive; } - static void SetOutput (LogFunc *pFn,void *pParam) { pfnOut=pFn; pOutParam=pParam; } - static void SetError (LogFunc *pFn,void *pParam) { pfnError=pFn; pErrorParam=pParam; } - - static bool SetOutput (LPCTSTR pszFilename); - static bool SetError (LPCTSTR pszFilename); + static void SetOutput (LogFunc *pFn,void *pParam) { pfnOut=pFn; pOutParam=pParam; } // Make stdout go to this callback + static void SetError (LogFunc *pFn,void *pParam) { pfnError=pFn; pErrorParam=pParam; } // Make stderr go to this callback - #ifndef TRACE - #define TRACE CeCosTrace::Trace - #endif - #undef ERROR - #define ERROR CeCosTrace::Error + static bool SetOutput (LPCTSTR pszFilename); // Make stdout go to this file + static bool SetError (LPCTSTR pszFilename); // Make stderr go to this file - #ifdef VERBOSE - #define VTRACE CeCosTrace::Trace - #else - #define VTRACE if(0) CeCosTrace::Trace + // Some macros... + #ifndef TRACE // because if running under a debugger we might have a better definition (via OutputDebugString) already + // Use this to generate output that will only appear if trace level is at least TRACE_LEVEL_TRACE (turned on by -v) + #define TRACE if(CeCosTrace::TracingEnabled()>=CeCosTrace::TRACE_LEVEL_TRACE) CeCosTrace::TimeStampedErr #endif + #undef ERROR + + #define ERROR CeCosTrace::TimeStampedErr + // Use this to generate output that will only appear if trace level is at least TRACE_LEVEL_VTRACE (turned on by -V) + #define VTRACE if(CeCosTrace::TracingEnabled()>=CeCosTrace::TRACE_LEVEL_VTRACE) CeCosTrace::TimeStampedErr + + // Use this to generate output that will only appear if mode is interactive (see above) + #define INTERACTIVE if(CeCosTrace::IsInteractive()||CeCosTrace::TracingEnabled()>=CeCosTrace::TRACE_LEVEL_TRACE) CeCosTrace::TimeStampedErr + + // Thus log function can be used to direct output to a FILE* (e.g. stdout) passed as the first argument: static void CALLBACK StreamLogFunc (void *, LPCTSTR psz); protected: + // Information we need to know for a stream (error or output) struct StreamInfo { Time tLastReopen; String strFilename; @@ -81,13 +96,14 @@ protected: ~StreamInfo() { fclose(f); } }; + // Here are the two streams static StreamInfo OutInfo,ErrInfo; - static void CALLBACK StreamInfoFunc (void *, LPCTSTR psz); + static void CALLBACK StreamInfoFunc (void *, LPCTSTR psz); static LPCTSTR arpszDow[7]; - static bool bVerbose; + static TraceLevel nVerbosity; static bool bInteractive; static LogFunc *pfnOut; static void *pOutParam; static LogFunc *pfnError; static void *pErrorParam; diff --git a/host/tools/Utils/common/wcharunix.h b/host/tools/Utils/common/wcharunix.h --- a/host/tools/Utils/common/wcharunix.h +++ b/host/tools/Utils/common/wcharunix.h @@ -22,6 +22,11 @@ // ---------------------------------------------------------------------------- // //####COPYRIGHTEND#### + +// ---------------------------------------------------------------------------- +// This file defines the generic-text routine mappings found in TCHAR.H on windows +// ---------------------------------------------------------------------------- + #define _TEOF EOF #define __T(x) x diff --git a/host/tools/Utils/win32/CTUtils.cpp b/host/tools/Utils/win32/CTUtils.cpp --- a/host/tools/Utils/win32/CTUtils.cpp +++ b/host/tools/Utils/win32/CTUtils.cpp @@ -163,16 +163,16 @@ BOOL CUtils::StrToItemIntegerType(const const CString CUtils::IntToStr(__int64 d,bool bHex) { - CString str; - str.Format(bHex?_T("0x%08x"):_T("%d"),d); - return str; + CString s; + s.Format(bHex?_T("0x%08x"):_T("%d"),d); + return s; } const CString CUtils::DoubleToStr (double dValue) { - CString strValue; - strValue.Format (_T("%.*e"), DBL_DIG, dValue); - return strValue; + CString s; + s.Format (_T("%.*e"), DBL_DIG, dValue); + return s; } BOOL CUtils::StrToDouble (const CString & strValue, double &dValue) diff --git a/host/tools/Utils/win32/SubProcess.cpp b/host/tools/Utils/win32/SubProcess.cpp deleted file mode 100644 --- a/host/tools/Utils/win32/SubProcess.cpp +++ /dev/null @@ -1,542 +0,0 @@ -//####COPYRIGHTBEGIN#### -// -// ---------------------------------------------------------------------------- -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// -// This program is part of the eCos host tools. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// ---------------------------------------------------------------------------- -// -//####COPYRIGHTEND#### -//=========================================================================== -//=========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): sdf -// Contact(s): sdf -// Date: 1998/08/11 -// Version: 0.01 -// Purpose: -// Description: This is the implementation of the class which allows for spawning subprocesses -// -// Requires: -// Provides: -// See also: -// Known bugs: -// Usage: -// -//####DESCRIPTIONEND#### -// -//=========================================================================== -#include "subprocess.h" - -const UINT CSubprocess::PROCESS_KILL_EXIT_CODE=0xCCFFCCFF; - -CSubprocess::CSubprocess(bool bVerbose): - m_dwParentThreadId(0), - m_pstrOutput(0), - m_idProcess(0), - m_bThreadRunning(false), - m_bVerbose(bVerbose), - m_dwExitCode(0xffffffff), - m_bAutoDelete(false), - m_hThread(0), - m_pfnLogfunc(0), - m_pLogparam(0), - m_hwndParent(0) -{ -} - -// Run (non-blocking and discarding output) -/* static */ unsigned int CSubprocess::Run(LPCTSTR pszCmd,LPCTSTR pszDir) -{ - CSubprocess *psp=new CSubprocess(false); - psp->m_bAutoDelete=true; - String strOutput; - return psp->Run(strOutput,pszCmd,pszDir); -} - -unsigned int CSubprocess::Run(LogFunc *pfnLog,void * pLogparam, LPCTSTR pszCmd,LPCTSTR pszDir) -{ - unsigned int rc; - if(m_bThreadRunning){ - rc=0; - } else { - m_pfnLogfunc=pfnLog; - m_pLogparam=pLogparam; - m_strCmd=pszCmd; - m_strDir=pszDir; - rc=CreateProcess(); - if(rc){ - ThreadFunc(); - } - } - return rc; -} - -#ifdef _WIN32 -// Non-blocking: WM_SUBPROCESS messages are posted to HWND supplied as argument -unsigned int CSubprocess::Run(HWND hwndParent,LPCTSTR pszCmd,LPCTSTR pszDir) -{ - unsigned int rc; - if(m_bThreadRunning){ - rc=0; - } else { - m_hwndParent=hwndParent; - m_strCmd=pszCmd; - m_strDir=pszDir; - rc=CreateProcess(); - if(rc){ - DWORD dwID; - m_bThreadRunning=true; - m_hThread=::CreateThread(NULL,0,ThreadFunc,this,0,&dwID); - } - } - return rc; -} - -// Non-blocking: WM_SUBPROCESS messages are posted to thread supplied as argument -unsigned int CSubprocess::Run(DWORD dwParentThreadId,LPCTSTR pszCmd,LPCTSTR pszDir) -{ - unsigned int rc; - if(m_bThreadRunning){ - rc=0; - } else { - m_dwParentThreadId=dwParentThreadId; - m_strCmd=pszCmd; - m_strDir=pszDir; - rc=CreateProcess(); - if(rc){ - DWORD dwID; - m_bThreadRunning=true; - m_hThread=::CreateThread(NULL,0,ThreadFunc,this,0,&dwID); - } - } - return rc; -} -#endif - -// Blocking: output is placed in string supplied as argument -unsigned int CSubprocess::Run(String &strOutput,LPCTSTR pszCmd,LPCTSTR pszDir) -{ - strOutput=_T(""); - m_strCmd=pszCmd; - m_strDir=pszDir; - m_pstrOutput=&strOutput; - unsigned int rc=CreateProcess(); - if(rc){ - ThreadFunc(); - } - return rc; -} - -CSubprocess::~CSubprocess() -{ - Kill(); - - if(m_hThread){ // running non-blocking and thread started (but possibly already finished) - if(WAIT_TIMEOUT==WaitForSingleObject(m_hThread,1000)){ - // In general this is bad news, but we can't allow the thread to live on if - // the class object is about to be deleted. - if(m_bVerbose){ - Output(_T("*** CSubprocess: Forcibly terminating thread\n")); - } - ::TerminateThread(m_hThread,0); - } - ::CloseHandle(m_hThread); - } -} - -#ifdef _WIN32 -unsigned int CSubprocess::CreateProcess() -{ - - STARTUPINFO si; // For CreateProcess call - HANDLE hrPipe,hwPipe,hwPipe2; - // Create the anonymous pipe - - SECURITY_ATTRIBUTES saPipe; // Security for anonymous pipe - saPipe.nLength = sizeof(SECURITY_ATTRIBUTES); - saPipe.lpSecurityDescriptor = NULL; - saPipe.bInheritHandle = true; - - ::CreatePipe(&m_hrPipe,&hwPipe,&saPipe,80); - - // In most cases you can get away with using the same anonymous - // pipe write handle for both the child's standard output and - // standard error, but this may cause problems if the child app - // explicitly closes one of its standard output or error handles. If - // that happens, the anonymous pipe will close, since the child's - // standard output and error handles are really the same handle. The - // child won't be able to write to the other write handle since the - // pipe is now gone, and parent reads from the pipe will return - // ERROR_BROKEN_PIPE and child output will be lost. To solve this - // problem, simply duplicate the write end of the pipe to create - // another distinct, separate handle to the write end of the pipe. - // One pipe write handle will serve as standard out, the other as - // standard error. Now *both* write handles must be closed before the - // write end of the pipe actually closes. - - ::DuplicateHandle(::GetCurrentProcess(), // Source process - hwPipe, // Handle to duplicate - ::GetCurrentProcess(), // Destination process - &hwPipe2, // New handle, used as stderr by child - 0, // New access flags - ignored since DUPLICATE_SAME_ACCESS - true, // It's inheritable - DUPLICATE_SAME_ACCESS); - - ::CreatePipe(&hrPipe,&m_hwPipe,&saPipe,80); - - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - - si.hStdOutput = hwPipe; - si.hStdError = hwPipe2; - si.hStdInput = hrPipe; - si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - si.wShowWindow = SW_SHOW; - - LPCTSTR pszDir=0; - if(m_strDir.GetLength()){ - pszDir=m_strDir; // NULL = start in current - } - - PROCESS_INFORMATION pi; - unsigned int rc=(::CreateProcess(NULL, // Application name - m_strCmd.GetBuffer(m_strCmd.GetLength()), // Full command line for child - NULL, // Process security descriptor - NULL, // Thread security descriptor - true, // Inherit handles? Also use if STARTF_USESTDHANDLES - // Creation flags of - // CREATE_NEW_PROCESS_GROUP so we can use - // GenerateConsoleCtrlEvent to - // terminate the child - DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP, - NULL, // Inherited environment address - pszDir,&si,&pi) ? pi.dwProcessId : 0); - - m_strCmd.ReleaseBuffer(); - String strMsg; - - if(rc){ - m_idProcess=pi.dwProcessId; - m_hProcess=pi.hProcess; - strMsg.Format(_T("*** Process %d created \"%s\"\n"),m_idProcess,(LPCTSTR)m_strCmd); - m_dwExitCode=STILL_ACTIVE; - } else { - strMsg.Format(_T("*** Failed to create process \"%s\"\n"),(LPCTSTR)m_strCmd); - m_dwExitCode=GetLastError(); - } - - if(m_bVerbose){ - Output(strMsg); - } - - ::CloseHandle(hrPipe); - ::CloseHandle(hwPipe); - ::CloseHandle(hwPipe2); - ::CloseHandle(pi.hThread); - - return rc; - -} -#else // UNIX -unsigned int CSubprocess::CreateProcess() -{ - int pipe_ends_w[2]; - if (pipe(pipe_ends_w) < 0 ) { - Log(_T("Failed to create pipe_ends_w - %s\n"),strerror(errno)); - } else { - int pipe_ends_r[2]; - if (pipe(pipe_ends_r) < 0 ) { - Log(_T("Failed to create pipe_ends_r - %s\n"),strerror(errno)); - } else { - int pid=fork(); - - switch (pid) { - // Fork failed - case -1: - Log(_T("Failed to create gdb process - %s\n"),strerror(errno)); - pid=0; - break; - case 0: - // Process is created (we're the child) - // No point in outputting except via output streams - - // Input to child process - if (dup2(pipe_ends_w[0], 0) < 0) { - _ftprintf(stderr,(_T("dup2 error\n")); - exit(1); - } - - // Output from process - if (dup2(pipe_ends_r[1], 2) < 0) { - _ftprintf(stderr,(_T("dup2 error\n")); - exit(2); - } - if (dup2(pipe_ends_r[1], 1) < 0) { - _ftprintf(stderr,(_T("dup2 error\n")); - exit(3); - } - setvbuf(stdout,0,_IONBF,0); - setvbuf(stderr,0,_IONBF,0); - if(m_bVerbose){ - strMsg.Format(_T("*** Process %d created \"%s\"\n"),pid,(LPCTSTR)m_strCmd); - } - - StringArray ar; - int argc=m_strCmd.Chop(ar,_TCHAR(' '),true); - TCHAR **argv=new TCHAR *[1+argc]; - int i; - for(i=0;i\n"), pszCmdline, pid); - if (fcntl(pipe_ends_r[0], F_SETFL, O_NONBLOCK) <0) { - Log(_T("Couldn't set pipe non-blocking - %s\n"),strerror(errno)); - } else { - m_rPipeHandle=(void *)pipe_ends_r[0]; - m_wPipeHandle=(void *)pipe_ends_w[1]; - } - break; - } - close (pipe_ends_r[0]); - close (pipe_ends_r[1]); - } - close (pipe_ends_w[0]); - close (pipe_ends_w[1]); - } - return pid; -} -#endif - -DWORD CSubprocess::ThreadFunc() - -{ - - DWORD dwAvail; - - while (::PeekNamedPipe(m_hrPipe, NULL, 0, 0, &dwAvail, NULL)){ - if(dwAvail){ - DWORD dwRead; - char *buf=new char[dwAvail+1]; - if(!::ReadFile(m_hrPipe, buf, dwAvail, &dwRead, NULL)){ - delete [] buf; - break; - } - buf[dwRead]='\0'; - Output(String::CStrToUnicodeStr(buf)); - delete [] buf; - } else { - DWORD dw; - ::GetExitCodeProcess(m_hProcess, &dw); - - if(STILL_ACTIVE!=dw){ - break; - } - - Sleep(250); - } - } - - ::GetExitCodeProcess(m_hProcess, &m_dwExitCode); - String strMsg; - if(m_bVerbose){ - if(PROCESS_KILL_EXIT_CODE==m_dwExitCode){ - strMsg.Format(_T("\n*** Process %d killed\n"),m_idProcess); - } else { - strMsg.Format(_T("\n*** Process %d terminated (rc=%d)\n"),m_idProcess,m_dwExitCode); - } - Output(strMsg); - } - - if(m_dwParentThreadId || m_hwndParent){ - Post(0); - } - m_idProcess=0; - - ::CloseHandle(m_hrPipe); - ::CloseHandle(m_hwPipe); - ::CloseHandle(m_hProcess); - m_bThreadRunning=false; - DWORD rc=m_dwExitCode; // protect against auto-delete - - if(m_bAutoDelete){ - delete this; - } - - return rc; - -} - -bool CSubprocess::Kill() -{ - if(0!=m_idProcess){ - //TRACE(_T("*** Killing process %d(ctrl/c)\n"),m_idProcess); - //::GenerateConsoleCtrlEvent( CTRL_C_EVENT, m_idProcess); - //if(WAIT_TIMEOUT==WaitForSingleObject(m_hThread,1000)){ - //TRACE(_T("*** Killing process %d(ctrl/break)\n"),m_idProcess); - //::GenerateConsoleCtrlEvent( CTRL_BREAK_EVENT, m_idProcess); - //if(WAIT_TIMEOUT==WaitForSingleObject(m_hThread,1000)){ - if(m_bVerbose){ - String strMsg; - strMsg.Format(_T("*** Killing process %d (TerminateProcess)\n"),m_idProcess); - Output(strMsg); - } - ::TerminateProcess(m_hProcess,PROCESS_KILL_EXIT_CODE); - //} - //} - } - return 0==m_idProcess; -} - -void CSubprocess::Output (LPCTSTR psz) -{ - if(m_dwParentThreadId || m_hwndParent){ - TCHAR *pszCopy=new TCHAR[1+_tcslen(psz)]; - _tcscpy(pszCopy,psz); - Post((LPARAM)pszCopy); - } else if (m_pfnLogfunc) { - m_pfnLogfunc(m_pLogparam,psz); - } else { - assert(NULL!=m_pstrOutput); - (*m_pstrOutput)+=psz; - } -} - - -void CSubprocess::Post(LPARAM lParam) -{ - if(m_hwndParent){ - ::PostMessage(m_hwndParent,WM_SUBPROCESS,(WPARAM)this,lParam); - } else { - assert(m_dwParentThreadId); - ::PostThreadMessage(m_dwParentThreadId,WM_SUBPROCESS,(WPARAM)m_idProcess,lParam); - } -} - -void CSubprocess::CygKill() -{ - - // Map win32 pids to cygwin format - PtrArray map; - - int nKillCount; - int nGid=-1; - do { - nKillCount=0; - // Execute a "ps -l" to find out what's out there in Cygwin land - CSubprocess sp; - String strOutput; - sp.Run(strOutput,_T("ps -l")); - if(0==strOutput.GetLength()){ - if(m_bVerbose){ - Output(_T("*** Warning: could not run ps to effect a Cygkill()\n")); - } - } else { - // Walk through the lines by line and extract what we need - for(LPCTSTR psz=-1+(LPCTSTR)strOutput;psz;psz=_tcschr(psz,_TCHAR('\n'))){ - psz++; // move over the '\n' - CygProcessInfo cpi; - if(0==_tcsstr(psz,_T("ps.exe")) && 4==_stscanf(2+psz,_T("%d %d %d %d"),&cpi.nPid,&cpi.nPpid,&cpi.nPgid,&cpi.nWinpid) && cpi.nWinpid){ - for(unsigned int i=0;inWinpid==cpi.nWinpid){ - break; - } - } - - if(i==map.size()){ - // No existing match - add: - map.push_back(new CygProcessInfo(cpi)); - if((int)m_idProcess==cpi.nWinpid){ - nGid=cpi.nPgid; - } - } - } - } - - // Kill everything in the same group as our process - if(-1!=nGid){ - for (unsigned int i=0;inPgid==nGid){ - // Check that the process exists - HANDLE hProcess=OpenProcess(PROCESS_TERMINATE,false,pcpi->nWinpid); - if(hProcess){ - CloseHandle(hProcess); - String strCmd,strOut; - strCmd.Format(_T("kill %d"),pcpi->nPid); - pcpi->nPgid=-pcpi->nPgid; // prevent this being done more than once - CSubprocess::Run(strCmd); - nKillCount++; - } - } - } - } - - } - } while (nKillCount>0); - - // Now we've sent a kill to every process. Go back and check they are really dead (use windows API this time) - for(unsigned int i=0;inPgid)==nGid){ - HANDLE hProcess=OpenProcess(PROCESS_TERMINATE,false,pcpi->nWinpid); - if(hProcess){ - ::TerminateProcess(hProcess,0x7fffffff); - CloseHandle(hProcess); - } - } - } - - for(i=0;iThreadFunc(); } - DWORD ThreadFunc(); -}; - -#endif diff --git a/host/tools/configtool/ChangeLog b/host/tools/configtool/ChangeLog --- a/host/tools/configtool/ChangeLog +++ b/host/tools/configtool/ChangeLog @@ -1,3 +1,12 @@ +2000-04-11 John Dallaway + + * common/win32/CTCommonDoc.cpp: + + Modify OpenRepository() to pass error and warning + handlers to CdlPackagesDatabaseBody::make(). This + allows use of the config tool with repositories + having missing packages. + 2000-03-31 John Dallaway * standalone/win32/MainFrm.cpp: diff --git a/host/tools/configtool/common/win32/CTCommonDoc.cpp b/host/tools/configtool/common/win32/CTCommonDoc.cpp --- a/host/tools/configtool/common/win32/CTCommonDoc.cpp +++ b/host/tools/configtool/common/win32/CTCommonDoc.cpp @@ -1193,7 +1193,7 @@ bool CConfigToolDoc::OpenRepository (con // create a CDL repository, interpreter and configuration try {// create a new package database, interpreter and configuration - NewCdlPkgData = CdlPackagesDatabaseBody::make (CUtils::UnicodeToStdStr(strNewPackagesDir)); + NewCdlPkgData = CdlPackagesDatabaseBody::make (CUtils::UnicodeToStdStr(strNewPackagesDir), &CdlParseErrorHandler, &CdlParseWarningHandler); NewCdlInterp = CdlInterpreterBody::make (); NewCdlConfig = CdlConfigurationBody::make ("eCos", NewCdlPkgData, NewCdlInterp); } diff --git a/host/tools/configtool/standalone/common/ChangeLog b/host/tools/configtool/standalone/common/ChangeLog --- a/host/tools/configtool/standalone/common/ChangeLog +++ b/host/tools/configtool/standalone/common/ChangeLog @@ -1,3 +1,8 @@ +2000-04-10 Bart Veer + + * cdl_exec.cxx: + Add diagnostic callbacks to database initialization. + 2000-03-08 Bart Veer * configure.in (cyg_ac_infra_libdir): diff --git a/host/tools/configtool/standalone/common/cdl_exec.cxx b/host/tools/configtool/standalone/common/cdl_exec.cxx --- a/host/tools/configtool/standalone/common/cdl_exec.cxx +++ b/host/tools/configtool/standalone/common/cdl_exec.cxx @@ -65,7 +65,7 @@ cdl_exec::cdl_exec (const std::string re bool cdl_exec::cmd_new (const std::string cdl_hardware, const std::string cdl_template /* = "default" */, const std::string cdl_version /* = "" */) { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::make ("eCos", pkgdata, interp); config->set_hardware (resolve_hardware_alias (cdl_hardware), &diagnostic_handler, &diagnostic_handler); @@ -91,7 +91,7 @@ bool cdl_exec::cmd_new (const std::strin bool cdl_exec::cmd_target (const std::string cdl_target) { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); config->set_hardware (resolve_hardware_alias (cdl_target), &diagnostic_handler, &diagnostic_handler); @@ -110,7 +110,7 @@ bool cdl_exec::cmd_target (const std::st bool cdl_exec::cmd_template (const std::string cdl_template, const std::string cdl_version /* = "" */) { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); if (pkgdata->is_known_template (cdl_template) && ! cdl_version.empty ()) { @@ -135,7 +135,7 @@ bool cdl_exec::cmd_template (const std:: bool cdl_exec::cmd_export (const std::string cdl_savefile) { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); config->save (cdl_savefile, /* minimal = */ true); @@ -153,7 +153,7 @@ bool cdl_exec::cmd_export (const std::st bool cdl_exec::cmd_import (const std::string cdl_savefile) { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); config->add (cdl_savefile, &diagnostic_handler, &diagnostic_handler); @@ -172,7 +172,7 @@ bool cdl_exec::cmd_import (const std::st bool cdl_exec::cmd_add (const std::vector cdl_packages) { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); for (unsigned int n = 0; n < cdl_packages.size (); n++) { @@ -194,7 +194,7 @@ bool cdl_exec::cmd_remove (const std::ve unsigned int n; bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); for (n = 0; n < cdl_packages.size (); n++) { @@ -220,7 +220,7 @@ bool cdl_exec::cmd_remove (const std::ve bool cdl_exec::cmd_version (const std::string cdl_version, const std::vector cdl_packages) { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); for (unsigned int n = 0; n < cdl_packages.size (); n++) { @@ -241,7 +241,7 @@ bool cdl_exec::cmd_version (const std::s bool cdl_exec::cmd_tree () { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); char * cwd = getcwd (NULL, 0); @@ -268,14 +268,13 @@ bool cdl_exec::cmd_tree () { bool cdl_exec::cmd_list () { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); // list the installed packages std::vector packages = pkgdata->get_packages (); std::sort (packages.begin (), packages.end ()); for (unsigned int package = 0; package < packages.size (); package++) { const std::vector & aliases = pkgdata->get_package_aliases (packages [package]); - printf ("Package %s (%s):\n aliases:", packages [package].c_str (), aliases [0].c_str ()); for (unsigned int alias = 1; alias < aliases.size (); alias++) { printf (" %s", aliases [alias].c_str ()); } @@ -328,7 +327,7 @@ bool cdl_exec::cmd_check () { try { CdlTransactionBody::disable_automatic_inference (); - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); config->save (savefile); // tidy up any manual edits @@ -415,7 +414,7 @@ bool cdl_exec::cmd_resolve () { bool status = false; try { - pkgdata = CdlPackagesDatabaseBody::make (repository); + pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); interp = CdlInterpreterBody::make (); config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); config->resolve_all_conflicts (); diff --git a/host/tools/configtool/standalone/win32/ConfigToolDoc.cpp b/host/tools/configtool/standalone/win32/ConfigToolDoc.cpp --- a/host/tools/configtool/standalone/win32/ConfigToolDoc.cpp +++ b/host/tools/configtool/standalone/win32/ConfigToolDoc.cpp @@ -534,7 +534,7 @@ void CConfigToolDoc::RunTests() const CString strTarget(CurrentTestingIdentifier()); TRACE (_T("OnRunSim(): test target ID = '%s'\n"), strTarget); - if (!CeCosTest::IsValid (strTarget)) { + if (NULL==CeCosTestPlatform::Get(strTarget)) { if(IDNO==CUtils::MessageBoxFT(MB_YESNO,_T("%s is not a recognized platform - do you wish to add it?"),strTarget)){ return; } @@ -545,8 +545,8 @@ void CConfigToolDoc::RunTests() if(IDCANCEL==dlg.DoModal()){ return; } - CeCosTest::AddPlatform(CeCosTest::TargetInfo(dlg.m_strPlatform,dlg.m_strPrefix,dlg.m_nType,dlg.m_strGDB)); - CeCosTest::SaveTargetInfo(); + CeCosTestPlatform::Add(CeCosTestPlatform(dlg.m_strPlatform,dlg.m_strPrefix,dlg.m_strPrompt,dlg.m_strGDB,dlg.m_bServerSideGdb,dlg.m_strInferior)); + CeCosTestPlatform::Save(); } CFileNameArray ar; diff --git a/host/tools/configtool/standalone/win32/Configtool.cpp b/host/tools/configtool/standalone/win32/Configtool.cpp --- a/host/tools/configtool/standalone/win32/Configtool.cpp +++ b/host/tools/configtool/standalone/win32/Configtool.cpp @@ -53,6 +53,7 @@ #include "CTUtils.h" #include "eCosDialog.h" #include "eCosTest.h" +#include "eCosSocket.h" #include "FileName.h" #include "MainFrm.h" #include "OutputView.h" @@ -104,7 +105,8 @@ CConfigToolApp theApp; BOOL CConfigToolApp::InitInstance() { - CeCosTest::Init(); + CeCosSocket::Init(); + CeCosTestPlatform::Load(); CFileName strCSHFile; ::GetModuleFileName(::GetModuleHandle(NULL),strCSHFile.GetBuffer(1+MAX_PATH),MAX_PATH); strCSHFile.ReleaseBuffer(); @@ -288,7 +290,8 @@ int CConfigToolApp::ExitInstance() WriteProfileString(CUtils::LoadString(IDS_KEY_TOOLS_DIR),strPrefix,strBinDir); } ::DeleteFile(CConfigToolDoc::HTMLHelpLinkFileName()); - CeCosTest::Term(); + CeCosSocket::Term(); + CeCosTestPlatform::RemoveAllPlatforms(); return CWinApp::ExitInstance(); } diff --git a/host/tools/configtool/standalone/win32/Configtool.dsp b/host/tools/configtool/standalone/win32/Configtool.dsp --- a/host/tools/configtool/standalone/win32/Configtool.dsp +++ b/host/tools/configtool/standalone/win32/Configtool.dsp @@ -298,6 +298,16 @@ SOURCE=..\..\..\Utils\win32\eCosProperty # End Source File # Begin Source File +SOURCE=..\..\..\Utils\common\eCosSerial.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosSocket.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + SOURCE=..\..\..\Utils\common\eCosStd.cpp # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -313,7 +323,7 @@ SOURCE=..\..\..\ecostest\common\eCosTest # End Source File # Begin Source File -SOURCE=..\..\..\ecostest\common\eCosTestSerial.cpp +SOURCE=..\..\..\ecostest\common\eCosTestPlatform.cpp # SUBTRACT CPP /YX /Yc /Yu # End Source File # Begin Source File @@ -323,11 +333,6 @@ SOURCE=..\..\..\ecostest\common\eCosTest # End Source File # Begin Source File -SOURCE=..\..\..\ecostest\common\eCosTestSocket.cpp -# SUBTRACT CPP /YX /Yc /Yu -# End Source File -# Begin Source File - SOURCE=..\..\..\ecostest\common\eCosTestUtils.cpp # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -529,7 +534,7 @@ SOURCE=..\..\..\Utils\win32\StringEdit.c # End Source File # Begin Source File -SOURCE=..\..\..\Utils\win32\SubProcess.cpp +SOURCE=..\..\..\Utils\common\Subprocess.cpp # SUBTRACT CPP /YX /Yc /Yu # End Source File # Begin Source File @@ -696,6 +701,14 @@ SOURCE=..\..\..\Utils\win32\eCosProperty # End Source File # Begin Source File +SOURCE=..\..\..\Utils\common\eCosSerial.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Utils\common\eCosSocket.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Utils\common\eCosStd.h # End Source File # Begin Source File @@ -708,7 +721,7 @@ SOURCE=..\..\..\ecostest\common\eCosTest # End Source File # Begin Source File -SOURCE=..\..\..\ecostest\common\eCosTestSerial.h +SOURCE=..\..\..\ecostest\common\eCosTestPlatform.h # End Source File # Begin Source File @@ -716,10 +729,6 @@ SOURCE=..\..\..\ecostest\common\eCosTest # End Source File # Begin Source File -SOURCE=..\..\..\ecostest\common\eCosTestSocket.h -# End Source File -# Begin Source File - SOURCE=..\..\..\ecostest\common\eCosTestUtils.h # End Source File # Begin Source File @@ -916,7 +925,7 @@ SOURCE=..\..\..\Utils\win32\StringEdit.h # End Source File # Begin Source File -SOURCE=..\..\..\Utils\win32\SubProcess.h +SOURCE=..\..\..\Utils\common\Subprocess.h # End Source File # Begin Source File diff --git a/host/tools/configtool/standalone/win32/MainFrm.cpp b/host/tools/configtool/standalone/win32/MainFrm.cpp --- a/host/tools/configtool/standalone/win32/MainFrm.cpp +++ b/host/tools/configtool/standalone/win32/MainFrm.cpp @@ -45,6 +45,8 @@ #include "stdafx.h" +#define WM_SUBPROCESS (WM_USER+42) + #include "BinDirDialog.h" #include "BuildOptionsDialog.h" #include "CTOptionsDialog.h" @@ -155,10 +157,10 @@ BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_MESSAGE(WM_SUBPROCESS,OnSubprocess) ON_UPDATE_COMMAND_UI(ID_TOOLS_ADMINISTRATION, OnUpdateToolsAdministration) ON_WM_HELPINFO() + ON_COMMAND(ID_EDIT_PLATFORMS, OnEditPlatforms) ON_WM_MENUCHAR() - ON_WM_TIMER() ON_COMMAND(ID_HELP, OnHelp) - ON_COMMAND(ID_EDIT_PLATFORMS, OnEditPlatforms) + ON_WM_TIMER() //}}AFX_MSG_MAP ON_NOTIFY(HHN_NAVCOMPLETE, ID_HHNOTIFICATION, OnNavComplete) ON_NOTIFY(HHN_TRACK, ID_HHNOTIFICATION, OnNavComplete) @@ -183,8 +185,7 @@ CMainFrame::CMainFrame(): m_strIdleMessage(), m_nThermometerMax(0), m_bFindInProgress(false), - m_bStatusBarCreated(false), - m_psp(NULL) + m_bStatusBarCreated(false) { } @@ -443,17 +444,17 @@ void CMainFrame::OnUpdateViewOutput(CCmd void CMainFrame::OnUpdateBuildConfigure(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::OnBuildStop() { - m_psp->CygKill(); // leave the rest to OnSubprocessComplete() + m_sp.Kill(); // leave the rest to OnSubprocessComplete() } void CMainFrame::OnUpdateBuildStop(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL!=m_psp); + pCmdUI->Enable(m_sp.ProcessAlive()); } void CMainFrame::OnConfigurationBuild() @@ -467,46 +468,19 @@ DWORD CMainFrame::ThreadFunc(LPVOID para CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); CString strCmd(_T("make -n ")); strCmd+=pMain->m_strBuildTarget; - CSubprocess sp(true);; - sp.Run(GetCurrentThreadId(),strCmd, pDoc->BuildTree()); - CString strBuf; - for(;;){ - MSG msg; - switch(::GetMessage(&msg,NULL,WM_SUBPROCESS,WM_SUBPROCESS+1)){ - case 0: - return 0; //WM_QUIT - case -1: - return 1; // error - case 1: - if(WM_SUBPROCESS==msg.message){ - if(msg.lParam){ - LPTSTR pszMsg=(LPTSTR)msg.lParam; - strBuf+=pszMsg; - deleteZA(pszMsg); - } else { -#ifdef _DEBUG - CStdioFile file; - CFileName strFile(CFileName::GetTempPath()+_T("__ctbuffer.tmp")); - if(file.Open(strFile,CFile::modeCreate|CFile::modeWrite|CFile::typeText)){ - file.WriteString(strBuf); - file.Close(); - } -#endif + SetCurrentDirectory(pDoc->BuildTree()); + String strOut; + CSubprocess sp; + sp.Run(strOut,strCmd); // Don't attempt to change the thermometer itself - not safe from a separate thread - pMain->m_nThermometerMax=pDoc->GetCompilationCount(strBuf); - } - } else { - sp.CygKill(); - } - } - } + pMain->m_nThermometerMax=pDoc->GetCompilationCount(strOut); return 0; } void CMainFrame::Build(const CString &strWhat/*=_T("")*/) { - ASSERT(NULL==m_psp); + ASSERT(!m_sp.ProcessAlive()); CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); if(!arView[Output].bVisible){ @@ -538,15 +512,17 @@ void CMainFrame::Build(const CString &st strMsg.Format(_T("Building %s"),strWhat); SetIdleMessage(strMsg); - m_psp=new CSubprocess(true); - if(!m_psp->Run(m_hWnd, strCmd, pDoc->BuildTree())){ - deleteZ(m_psp); - } + SetTimer(42,1000,0); // This timer checks for process completion + SetCurrentDirectory(pDoc->BuildTree()); + m_sp.Run(SubprocessOutputFunc, this, strCmd, false); SetIdleMessage(); } } } + + + CConfigToolApp * CMainFrame::GetApp() { return (CConfigToolApp *)AfxGetApp(); @@ -619,8 +595,8 @@ void CMainFrame::OnDestroy() } } - if(NULL!=m_psp){ - m_psp->CygKill(); + if(m_sp.ProcessAlive()){ + m_sp.Kill(); } for(i=0;iEnable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::OnUpdateFileSave(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::OnUpdateFileSaveAs(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::OnUpdateFileOpen(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::OnUpdateFileNew(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::OnUpdateAppExit(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam) @@ -674,7 +650,7 @@ void CMainFrame::OnSysCommand(UINT nID, void CMainFrame::OnUpdateConfigurationRefresh(CCmdUI* pCmdUI) { CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); - pCmdUI->Enable(NULL==m_psp && !pDoc->BuildTree().IsEmpty()); + pCmdUI->Enable(!m_sp.ProcessAlive() && !pDoc->BuildTree().IsEmpty()); } void CMainFrame::OnConfigurationRefresh() @@ -712,7 +688,7 @@ void CMainFrame::OnSize(UINT nType, int void CMainFrame::OnUpdateConfigurationRepository(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::OnWindowNext() @@ -791,7 +767,7 @@ void CMainFrame::OnBuildClean() void CMainFrame::OnUpdateBuildClean(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::OnToolsShell() @@ -880,11 +856,11 @@ bool CMainFrame::PrepareEnvironment(bool void CMainFrame::OnClose() { - if(NULL!=m_psp){ + if(m_sp.ProcessAlive()){ if(IDNO==CUtils::MessageBoxFT(MB_YESNO|MB_DEFBUTTON2,_T("A build is in progress: exit anyway?"))){ return; } - m_psp->CygKill(); + m_sp.Kill(); } SaveBarState(_T("DockState")); CFrameWnd::OnClose(); @@ -1073,7 +1049,7 @@ CFont &CMainFrame::GetPaneFont(PaneType void CMainFrame::OnUpdateRunSim(CCmdUI* pCmdUI) { - pCmdUI->Enable(!CConfigTool::GetConfigToolDoc()->InstallTree().IsEmpty() && NULL==m_psp); + pCmdUI->Enable(!CConfigTool::GetConfigToolDoc()->InstallTree().IsEmpty() && !m_sp.ProcessAlive()); } void CMainFrame::SetFailRulePane(int nCount) @@ -1199,34 +1175,28 @@ void CMainFrame::OnInitMenuPopup(CMenu* } } -LRESULT CMainFrame::OnSubprocess(WPARAM, LPARAM lParam) +void CALLBACK CMainFrame::SubprocessOutputFunc(void *pParam,LPCTSTR psz) { - if(lParam){ - LPTSTR psz=(LPTSTR)lParam; + LPTSTR pszCopy=new TCHAR[1+_tcslen(psz)]; + _tcscpy(pszCopy,psz); + // Post a message to the mainframe because it wouldn't be safe to manipulate controls from a different thread + ((CMainFrame *)pParam)->PostMessage(WM_SUBPROCESS,(WPARAM)pszCopy); +} + +LRESULT CMainFrame::OnSubprocess(WPARAM wParam, LPARAM) +{ + LPTSTR psz=(LPTSTR)wParam; CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); m_nLogicalLines+=pDoc->GetCompilationCount(psz); UpdateThermometer (m_nLogicalLines); CConfigTool::GetOutputView()->AddText(psz); deleteZA(psz); - } else { - ::PostThreadMessage(m_dwThreadId,WM_SUBPROCESS+1,0,0); - - TRACE(_T("m_nThermometerMax=%d m_nLogicalLines=%d\n"),m_nThermometerMax,m_nLogicalLines); - if(0==m_psp->GetExitCode){ - UpdateThermometer(m_nThermometerMax); - Sleep(250); // Allow user to see it - } - UpdateThermometer(0); - SetThermometerMax(0); - deleteZ(m_psp); - return 0; - } return 0; } void CMainFrame::OnUpdateToolsAdministration(CCmdUI* pCmdUI) { - pCmdUI->Enable(NULL==m_psp); + pCmdUI->Enable(!m_sp.ProcessAlive()); } void CMainFrame::CygMount(TCHAR c) @@ -1270,10 +1240,26 @@ void CMainFrame::OnEditPlatforms() { CPlatformsDialog dlg; if(IDOK==dlg.DoModal()){ - CeCosTest::RemoveAllPlatforms(); + CeCosTestPlatform::RemoveAllPlatforms(); for(unsigned int i=0;i + + * unix/Makefile: add randfile + +2000-04-13 Jesper Skov + + * common/eCosTestDownloadFilter.cpp: Cast Write arguments to void*. + +2000-04-13 Simon FitzMaurice + * common\ResetAttributes.cpp + common\eCosTest.cpp + common\eCosTestClient.cpp + + Ensure socket timeout matches on_off/off_on delay for reset + Correct parsing of eCosTestClient delay args. + Use remote resource to determine baud rate for default download timeout. + +2000-04-13 Simon FitzMaurice + * common\ResetAttributes.cpp + common\eCosTest.cpp + common\eCosTest.h + common\eCosTestClient.cpp + common\eCosTestServer.cpp + common\eCosTestUtils.cpp + common\rgdb.cpp + common\summlog.cpp + common\x10reset.cpp + win32\eCosTest.dsp + + Tidy up reset output. + Police use of -f and -r switches more accurately. + Set default timeout in all cases. + +2000-04-11 Simon FitzMaurice + * common\ResetAttributes.cpp + common\ResetAttributes.h + common\ResourceServer.cpp + common\TestResource.cpp + common\TestResource.h + common\X10.h + common\X10d.cpp + common\eCosTest.cpp + common\eCosTest.h + common\eCosTestClient.cpp + common\eCosTestDownloadFilter.cpp + common\eCosTestDownloadFilter.h + common\eCosTestMonitorFilter.cpp + common\eCosTestMonitorFilter.h + common\eCosTestSerialFilter.cpp + common\eCosTestSerialFilter.h + common\eCosTestServer.cpp + common\eCosTestUtils.cpp + common\eCosTestUtils.h + common\resetall.cpp + common\rgdb.cpp + common\ser_filter.cpp + common\stat.cpp + common\summlog.cpp + common\x10reset.cpp + unix\Makefile + win32\eCosTest.dsp + win32\Amplicon\AmpliconD.cpp + + General tidy-up. + +2000-04-10 Bart Veer + + * common/permtest.cxx (main): + Add diagnostics callbacks to database initialization. + 2000-03-20 John Dallaway * win32/eCosTest.dsp: diff --git a/host/tools/ecostest/common/ResetAttributes.cpp b/host/tools/ecostest/common/ResetAttributes.cpp --- a/host/tools/ecostest/common/ResetAttributes.cpp +++ b/host/tools/ecostest/common/ResetAttributes.cpp @@ -38,6 +38,22 @@ const CResetAttributes CResetAttributes::NoReset; +CResetAttributes::CResetAttributes(LPCTSTR psz) : + // Default values: + m_nDelay(1000), + m_nReadTimeout(10*1000), + m_nBaud(38400) +{ + // Remove spaces + while(*psz){ + if(!_istspace(*psz)){ + m_str+=*psz; + } + psz++; + } +} + +/* LPCTSTR CResetAttributes::Image(int nErr) { switch(nErr){ @@ -61,102 +77,99 @@ LPCTSTR CResetAttributes::Image(int nErr break; } } - +*/ void CResetAttributes::SuckThreadFunc() { - m_strResetOutput.SetLength(0); + m_strResetOutput=_T(""); // Board has apparently been powered on. Suck initial output. - String strMsg; - strMsg.Format(_T(">>> Reading board startup output from %s with timeout of %d seconds...\n"),(LPCTSTR)m_strAuxPort,m_nReadTimeout/1000); - ResetLog(strMsg); + ResetLog(String::SFormat(_T("Reading board startup output from %s with timeout of %d seconds..."),(LPCTSTR)m_strAuxPort,m_nReadTimeout/1000)); enum {BUFSIZE=512}; - TCHAR *buf=new TCHAR[BUFSIZE]; + TCHAR buf[1+BUFSIZE]; memset(buf,0,BUFSIZE); // safety for string functions in IsValidReset - TCHAR *c=buf; do { unsigned int dwRead=0; // We are working in non-blocking mode if(m_Socket.Ok()){ - if(!m_Socket.Peek(dwRead)||!m_Socket.recv(c,MIN(dwRead,(unsigned)BUFSIZE-(c-buf)))){ + if(!m_Socket.Peek(dwRead)||!m_Socket.recv(buf,MIN(dwRead,BUFSIZE))){ break; } - } else if (!m_Serial.Read(c,BUFSIZE-(c-buf),dwRead)){ + } else if (!m_Serial.Read(buf,BUFSIZE,dwRead)){ m_Serial.ClearError(); - c=buf; + continue; } if(dwRead>0){ - c[dwRead]=_TCHAR('\0'); - { - String str; - for(const TCHAR *t=c;*t;t++){ - if(_istprint(*t)){ - str+=*t; - } - } - ResetLog(str); - } + buf[dwRead]=_TCHAR('\0'); - for(int i=dwRead-1;i>=0;--i){ - if(c[i]<0x20 || c[i]>=0x7f){ - // Control character - assume nothing up to this is of interest - i++; - dwRead-=i; - memmove(c,c+i,dwRead); - break; + // Remove unprintable characters + String str; + for(const TCHAR *t=buf;*t;t++){ + if(_istprint(*t)){ + str+=*t; } } - c+=dwRead; - if(IsValidReset((void *)buf)){ - ResetLog(_T("\n>>> Valid reset determined\n")); + + if(m_pfnReset){ + ENTERCRITICAL; + m_pfnReset(m_pfnResetparam,str); + LEAVECRITICAL; + } + + ResetLog(str); + m_strResetOutput+=str; + + if(IsValidReset()){ break; } - } else { // Nothing read - Sleep(500); +// } else { // Nothing read +// CeCosThreadUtils::Sleep(50); } } while (0==m_tResetOccurred || Now()-m_tResetOccurred>> No response from board\n")); + + if(0==m_strResetOutput.size()){ + ResetLog(_T("No response from board")); + } else { + if(m_pfnReset){ + ENTERCRITICAL; + m_pfnReset(m_pfnResetparam,_T("\n")); + LEAVECRITICAL; + } + TRACE(_T("%s"),(LPCTSTR)m_strResetOutput); } } bool CResetAttributes::Reset(Action action,bool bCheckOutput) { + m_tResetOccurred=0; m_strResetOutput=_T(""); bool rc=false; - CeCosTestSocket sock; - time_t ltime; - time(<ime); - struct tm *now=localtime( <ime ); + CeCosSocket sock; String strStatus; - + strStatus.Format(_T("Reset target using %s %s port=%s(%d) read timeout=%d delay=%d"), + (LPCTSTR)m_strHostPort,(LPCTSTR)m_strControl, + (LPCTSTR)m_strAuxPort, m_nBaud, m_nReadTimeout, m_nDelay); if(bCheckOutput){ - strStatus.Format(_T(">>> Reset target using %s %s port=%s(%d) read timeout=%d delay=%d [%02d:%02d:%02d]\n"), - (LPCTSTR)m_strHostPort,(LPCTSTR)m_strControl, (LPCTSTR)m_strAuxPort, m_nBaud, m_nReadTimeout, m_nDelay, - now->tm_hour,now->tm_min,now->tm_sec); - } else { - strStatus.Format(_T(">>> Reset target using %s %s delay=%d [%02d:%02d:%02d]\n"), - (LPCTSTR)m_strHostPort,(LPCTSTR)m_strControl, m_nDelay, - now->tm_hour,now->tm_min,now->tm_sec); + strStatus+=_T(" expect("); + for(unsigned int i=0;i0){ + strStatus+=_TCHAR(','); + } + strStatus+=m_arValidResetStrings[i]; + } + strStatus+=_T(")"); } ResetLog(strStatus); // Open up communication to port whence we read the board startup bool bThreadDone=false; - bCheckOutput&=(m_strAuxPort.GetLength()>0); + bCheckOutput&=(m_strAuxPort.size()>0); if(bCheckOutput){ TRACE(_T("Opening %s\n"),(LPCTSTR)m_strAuxPort); - String strHost; - int nPort; - if(CeCosTestSocket::ParseHostPort(m_strAuxPort,strHost,nPort)){ + if(CeCosSocket::IsLegalHostPort(m_strAuxPort)){ // tcp/ip port - if(!m_Socket.Connect(strHost,nPort,m_nReadTimeout)){ - String str; - str.Format(_T("Failed to open %s - %s\n"),(LPCTSTR)m_strAuxPort,(LPCTSTR)m_Socket.SocketErrString()); - ResetLog(str); + if(!m_Socket.Connect(m_strAuxPort,m_nReadTimeout)){ + ResetLog(String::SFormat(_T("Failed to open %s - %s"),(LPCTSTR)m_strAuxPort,(LPCTSTR)m_Socket.SocketErrString())); return false; } } else { @@ -165,49 +178,35 @@ bool CResetAttributes::Reset(Action acti if(m_Serial.Open(m_strAuxPort,m_nBaud)){ m_Serial.Flush(); } else { - String str; - str.Format(_T("Failed to open comms port %s - %s\n"),(LPCTSTR)m_strAuxPort,(LPCTSTR)m_Serial.ErrString()); - ResetLog(str); + ResetLog(String::SFormat(_T("Failed to open comms port %s - %s"),(LPCTSTR)m_strAuxPort,(LPCTSTR)m_Serial.ErrString())); return false; } } CeCosThreadUtils::RunThread(SSuckThreadFunc,this,&bThreadDone,_T("SSuckThreadFunc")); } else { - ResetLog(_T(">>> [not checking output]\n")); + ResetLog(_T("[not checking output]")); } - String strHost; - int nPort; // This will be true if we need to talk to a reset server, false to talk down a local port - bool bRemote=CeCosTestSocket::ParseHostPort(m_strHostPort,strHost,nPort); + bool bRemote=CeCosSocket::IsLegalHostPort(m_strHostPort); if(bRemote){ - if(sock.Connect(strHost,nPort,10*1000)){ - m_tResetOccurred=0; + if(sock.Connect(m_strHostPort,10*1000)){ // Write the message to the socket - String strCmd; int nDelay=(action==ON_OFF || action==OFF_ON)?m_nDelay:0; - strCmd.Format(_T("-Control=%s -Action=%d -Delay=%d"),(LPCTSTR)m_strControl,action,nDelay); - TRACE(_T("-Control=%s -Action=%d -Delay=%d"),(LPCTSTR)m_strControl,action,0); - if(sock.sendString(strCmd,_T("Reset control codes"), 10*1000)){ + TRACE(_T("-Control=%s -Action=%d -Delay=%d"),(LPCTSTR)m_strControl,action,nDelay); + if(sock.sendString(String::SFormat(_T("-Control=%s -Action=%d -Delay=%d"),(LPCTSTR)m_strControl,action,nDelay),_T("Reset control codes"), 10*1000)){ // Wait for an acknowledgement String strResponse; - if(sock.recvString(strResponse, _T("Response"), 20*1000)){ - rc=(0==strResponse.GetLength()); + if(sock.recvString(strResponse, _T("Response"), nDelay+20*1000)){ + rc=(0==strResponse.size()); if(!rc && m_pfnReset){ - String strMsg; - strMsg.Format(_T("Reset server reports error '%s'\n"),(LPCTSTR)strResponse); - ResetLog(strMsg); + ResetLog(String::SFormat(_T("Reset server reports error '%s'"),(LPCTSTR)strResponse)); } } else { - String str; - str.Format(_T(">>> Failed to read response from reset server %s - %s\n"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString()); - ResetLog(str); + ResetLog(String::SFormat(_T("Failed to read response from reset server %s - %s"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString())); } } else { - String str; - str.Format(_T(">>> Failed to contact reset server %s - %s\n"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString()); - ResetLog(str); - ResetLog(_T(">>> Failed to contact reset server\n")); + ResetLog(String::SFormat(_T("Failed to contact reset server %s - %s"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString())); } m_tResetOccurred=Now(); if(bCheckOutput){ @@ -216,14 +215,11 @@ bool CResetAttributes::Reset(Action acti m_tResetOccurred=Now()-m_nReadTimeout; } CeCosThreadUtils::WaitFor(bThreadDone); // do not apply a timeout - the thread has one - rc=IsValidReset((void *)(LPCTSTR)m_strResetOutput); - ResetLog(rc?_T(">>> Reset output valid\n"):_T("!!! Reset output invalid\n")); + rc=IsValidReset(); + ResetLog(rc?_T("Reset output valid"):_T("Reset output INVALID")); } } else { - String str; - str.Format(_T(">>> Failed to contact reset server %s - %s\n"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString()); - ResetLog(str); - ResetLog(_T(">>> Failed to contact reset server\n")); + ResetLog(String::SFormat(_T("Failed to contact reset server %s - %s"),(LPCTSTR)m_strHostPort,(LPCTSTR)sock.SocketErrString())); } } else { // Sending something locally @@ -232,8 +228,8 @@ bool CResetAttributes::Reset(Action acti m_Serial.Write((void *)(LPCTSTR)m_strControl,1,nWritten); if(bCheckOutput){ CeCosThreadUtils::WaitFor(bThreadDone); // do not apply a timeout - the thread has one - rc=IsValidReset((void *)(LPCTSTR)m_strResetOutput); - ResetLog(rc?_T(">>> Reset output valid\n"):_T("!!! Reset output invalid\n")); + rc=IsValidReset(); + ResetLog(rc?_T("Reset output valid"):_T("Reset output INVALID")); } } @@ -245,6 +241,8 @@ bool CResetAttributes::Reset(Action acti return rc && bCheckOutput; } +// We expect to be passed a string that starts with "xxx(yyy)" +// and the task is to extract xxx into strID and yyy into strArg const TCHAR *CResetAttributes::GetIdAndArg (LPCTSTR psz,String &strID,String &strArg) { const TCHAR *cEnd=_tcschr(psz,_TCHAR('(')); @@ -267,45 +265,18 @@ const TCHAR *CResetAttributes::GetIdAndA return 0; } -int CResetAttributes::GetArgs(LPCTSTR psz,StringArray &ar) -{ - ar.clear(); - if(0==*psz){ - return 0; - } else { - String str; - for(const TCHAR *c=psz;*c;c++){ - if(_TCHAR(',')==*c){ - ar.push_back(str); - str=_T(""); - } else { - str+=*c; - } - } - ar.push_back(str); - return ar.size(); - } -} - -// m_str will hold something like -// 3(off(ginga:5000,a1) delay(2000) on(,..com2,38400)) +// Do the reset CResetAttributes::ResetResult CResetAttributes::Reset (LogFunc *pfnLog, void *pfnLogparam,bool bCheckOnly) { m_pfnReset=pfnLog; m_pfnResetparam=pfnLogparam; - const TCHAR *c; - String str; - // Remove spaces - for(c=m_str;*c;c++){ - if(!_istspace(*c)){ - str+=*c; - } - } + // First we clean up the reset string so as to make subsequent parsing less complicated. + // Spaces have already been removed in the ctor // Check paren matching: int nNest=0; - for(c=str;*c;c++){ + for(const TCHAR *c=m_str;*c;c++){ if(_TCHAR('(')==*c){ nNest++; } else if(_TCHAR(')')==*c){ @@ -321,16 +292,16 @@ CResetAttributes::ResetResult CResetAttr return INVALID_STRING; } - m_nReadTimeout=10*1000; - m_nBaud=38400; - m_nDelay=1000; - - return Parse(str,bCheckOnly); + return Parse(m_str,bCheckOnly); } -// 3(off(ginga:5000,a1) delay(2000) on(,..com2,38400)) +// This function parses the reset string, whose form is something like: +// expect($T05) 3(off(ginga:5000,a1) delay(2000) on(ginga:5000,a1,com1,38400,10000)) +// It is recursive (which is another reason elementary syntax checking was carried out above) +// and calls itself to perform repeats [e.g. 3(...)] CResetAttributes::ResetResult CResetAttributes::Parse (LPCTSTR psz,bool bCheckOnly) { + enum {ARGSEP=_TCHAR(',')}; bool bCheck=false; for(const TCHAR *c=psz;*c;){ String strID,strArg; @@ -341,6 +312,7 @@ CResetAttributes::ResetResult CResetAttr } if(isdigit(*(LPCTSTR)strID)){ + // Process a repeat-until-reset. Syntax is n(resetstring) int nRepeat=_ttoi(strID); if(0==nRepeat){ ResetLog(_T("Invalid reset string")); @@ -356,23 +328,30 @@ CResetAttributes::ResetResult CResetAttr } } } + } else if (_T("expect")==strID) { + // Expected string(s). e.g. expect(str1,str2,...). + strArg.Chop(m_arValidResetStrings,ARGSEP,true); } else if (_T("port")==strID) { + // Port information. e.g. port(com1,38400,1000) + // This information will apply to all subsequent actions until overwritten. + // Specifically args are: // 0. Port // 1. Baud - // 2. Timeout + // 2. Read timeout StringArray ar; - int nArgs=GetArgs(strArg,ar); - if(nArgs>0 && ar[0].GetLength()){ + int nArgs=strArg.Chop(ar,ARGSEP,true); + if(nArgs>0 && ar[0].size()){ m_strAuxPort=ar[0]; } - if(nArgs>1 && ar[1].GetLength()){ + if(nArgs>1 && ar[1].size()){ m_nBaud=_ttoi(ar[1]); } - if(nArgs>2 && ar[2].GetLength()){ + if(nArgs>2 && ar[2].size()){ m_nReadTimeout=_ttoi(ar[2]); } } else if (_T("off")==strID || _T("on")==strID || _T("on_off")==strID || _T("off_on")==strID) { - // args are: + // Action information. e.g. off(ginga:500,A4,com1,38400,10000,1000) + // Specifically args are: // 0. Reset host:port // 1. Control string // 2. Port @@ -380,27 +359,27 @@ CResetAttributes::ResetResult CResetAttr // 4. Read timeout // 5. Delay StringArray ar; - int nArgs=GetArgs(strArg,ar); - if(nArgs>0 && ar[0].GetLength()){ - m_strHostPort=ar[0]; + int nArgs=strArg.Chop(ar,ARGSEP,true); + if(nArgs>0 && ar[0].size()){ + m_strHostPort=ar[0]; } - if(nArgs>1 && ar[1].GetLength()){ + if(nArgs>1 && ar[1].size()){ m_strControl=ar[1]; } - if(nArgs>2 && ar[2].GetLength()){ + if(nArgs>2 && ar[2].size()){ m_strAuxPort=ar[2]; } - if(nArgs>3 && ar[3].GetLength()){ + if(nArgs>3 && ar[3].size()){ m_nBaud=_ttoi(ar[3]); } - if(nArgs>4 && ar[4].GetLength()){ + if(nArgs>4 && ar[4].size()){ m_nReadTimeout=_ttoi(ar[4]); } - if(nArgs>5 && ar[5].GetLength()){ + if(nArgs>5 && ar[5].size()){ m_nDelay=_ttoi(ar[5]); } - if(0==m_strHostPort.GetLength()){ + if(0==m_strHostPort.size()){ ResetLog(_T("Failed to specify reset host:port")); return INVALID_STRING; } @@ -421,61 +400,42 @@ CResetAttributes::ResetResult CResetAttr } bCheck ^= 1; } else if (_T("delay")==strID) { - TRACE(_T("Sleep %d\n"),_ttoi(strArg)); + // Delay for a given time right now. e.g. delay(1000) + // Specifically args are: + // 0. msec to delay + TRACE(_T("CeCosThreadUtils::Sleep %d\n"),_ttoi(strArg)); if(!bCheckOnly){ - Sleep(_ttoi(strArg)); + CeCosThreadUtils::Sleep(_ttoi(strArg)); } } else { - ResetLog(_T("Unrecognized command")); + ResetLog(String::SFormat(_T("Unrecognized command '%s'"),(LPCTSTR)strID)); return INVALID_STRING; } } - ResetLog(_T("!!! Target reset not verified\n")); + ResetLog(_T("Target reset not verified")); return NOT_RESET; } +// Log some output to the reset log function. void CResetAttributes::ResetLog(LPCTSTR psz) { if(m_pfnReset){ ENTERCRITICAL; - m_pfnReset(m_pfnResetparam,psz); + m_pfnReset(m_pfnResetparam,String::SFormat(_T("%s >>> %s\n"),(LPCTSTR)CeCosTrace::Timestamp(),psz)); TRACE(_T("%s"),psz); LEAVECRITICAL; } } -// This function determines whether the board startup has all that is required -// It is a hack because it has hardwired knowledge of what boards say at startup time -bool CALLBACK CResetAttributes::IsValidReset (void *pParam) +bool CResetAttributes::IsValidReset() { - bool rc=false; - LPCTSTR pszBuf=(LPCTSTR)pParam; - - // Look for $T or $S - LPCTSTR pcTpkt=_tcsstr(pszBuf,_T("$T")); - if(0==pcTpkt){ - pcTpkt=_tcsstr(pszBuf,_T("$S")); + unsigned int n=0; + ENTERCRITICAL; + for(int i=m_arValidResetStrings.size()-1;i>=0;--i){ + if(_tcsstr(m_strResetOutput,m_arValidResetStrings[i])){ + n++; + } } - - if(pcTpkt){ - // T packet ends with #hh - LPCTSTR d=_tcschr(pcTpkt,_TCHAR('#')); - if(d && d[1] && d[2]){ - rc=true; - } - } else if (_tcsstr(pszBuf,_T("cygmon> "))) { - rc=true; - } else { - LPCTSTR pBootp=_tcsstr(pszBuf,_T("BOOTP got ")); - if(pBootp){ - int i1,i2,i3,i4; - rc=(4==_stscanf(pBootp+10,_T("%d.%d.%d.%d"),&i1,&i2,&i3,&i4)); - } - } - return rc; + LEAVECRITICAL; + return n==m_arValidResetStrings.size(); } - -bool CResetAttributes::IsValid() -{ - return INVALID_STRING!=Reset (0,0,true); -} diff --git a/host/tools/ecostest/common/ResetAttributes.h b/host/tools/ecostest/common/ResetAttributes.h --- a/host/tools/ecostest/common/ResetAttributes.h +++ b/host/tools/ecostest/common/ResetAttributes.h @@ -36,41 +36,90 @@ #ifndef _RESETATTRIBUTES_H #define _RESETATTRIBUTES_H +#include "Collections.h" #include "eCosStd.h" -#include "eCosTestSerial.h" -#include "eCosTestSocket.h" +#include "eCosSerial.h" +#include "eCosSocket.h" #include "Properties.h" -class CTestResource; +//================================================================= +// This class deals with resetting a target. +// The ctor accepts the "reset string" this is something like +// expect($T05,#) 3(off(ginga:5000,a1) delay(2000) on(,..com2,38400)) +// and is parsed to generate the commands to reset the target. +// The syntax is: +// resetstring :== [directive | (resetstring)] * +// directive :== id(arg[,arg]*) +// directive :== port | action | delay | expect +// +// The (string) syntax repeats argument its until reset is achieved. +// Each directive is given by example below: +// expect: +// Expected string(s). e.g. expect(str1,str2,...). +// Arguments: +// The string(s) expected to be output by a target after reset. +// *all* supplied strings must be present *in order* in the reset string for a reset to be recognized as valid. +// port: +// Provide port information to apply to all subsequent off|on|on_off|off_on actions until overwritten. +// e.g. port(com1,38400,1000) +// Arguments: +// 0. Port +// 1. Baud +// 2. Read timeout +// These have the meanings described under off|on|on_off|off_on. +// off|on|on_off|off_on: +// Request a reset host to perform a "power cycle" (or its logical equivalent - +// the meanings of "off" and "on" may depend on the reset host) +// e.g. off_on(ginga:500,A4,com1,38400,10000,1000) +// Arguments: +// 0. Reset host:port +// 1. Control string (meaning known to the reset host) +// 2. Port (from which to read startup output) +// 3. Baud for the above +// 4. Read timeout +// 5. Delay (between off and on or vice versa) +// delay: +// Delay for a given time right now. +// e.g. delay(1000) +// Arguments: +// 0. msec to delay +//================================================================= class CResetAttributes { public: - bool IsValid(); - CResetAttributes(LPCTSTR psz=_T("")) : m_str(psz) {} + CResetAttributes(LPCTSTR psz=_T("")); + + //bool IsValid(); + const LPCTSTR Image() const { return m_str; } - static bool IsError(int n) { return n>=RESET_ILLEGAL_DEVICE_CODE && n<=RESET_UNKNOWN_ERROR; } - static LPCTSTR Image(int nErr); - bool IsNull() const { return 0==m_str.GetLength(); } + + bool IsNull() const { return m_str.empty(); } static const CResetAttributes NoReset; - // Perform reset enum ResetResult {INVALID_STRING=-1,RESET_OK=0,NOT_RESET=1, RESET_ILLEGAL_DEVICE_CODE=30000,RESET_NO_REPLY, RESET_BAD_CHECKSUM, RESET_BAD_ACK, RESET_UNKNOWN_ERROR}; - enum Action {OFF=0,ON=1,OFF_ON=2,ON_OFF=3}; + // Perform the reset, sending the output to the log function supplied as parameter. + ResetResult Reset (LogFunc *pfnLog=0, void *pfnLogparam=0,bool bCheckOnly=false); - ResetResult Reset (LogFunc *pfnLog=0, void *pfnLogparam=0,bool bCheckOnly=false); - static bool CALLBACK IsValidReset (void *); + enum Action {OFF=0,ON=1,OFF_ON=2,ON_OFF=3}; protected: + // This function determines whether the board startup has output all that is required + // All the strings of m_arValidResetStrings [arguments of expect() in the reset string] must be present + bool IsValidReset(); + Time m_tResetOccurred; - void ResetLog(LPCTSTR psz); + + // The log function. LogFunc *m_pfnReset; void *m_pfnResetparam; + // Log some output to the reset log function. + void ResetLog(LPCTSTR psz); - CeCosTestSerial m_Serial; - CeCosTestSocket m_Socket; + CeCosSerial m_Serial; + CeCosSocket m_Socket; const TCHAR *GetIdAndArg (LPCTSTR psz,String &strID,String &strArg); ResetResult Parse (LPCTSTR psz,bool bCheckOnly=false); @@ -78,18 +127,20 @@ protected: void SuckThreadFunc (); static void CALLBACK SSuckThreadFunc (void *pParam) { ((CResetAttributes*)pParam)->SuckThreadFunc(); } - int GetArgs(LPCTSTR psz,StringArray &ar); - String m_str; // Could be const, but avoid the assignment operator warnings + String m_str; // Here is the reset string. Could be const, but avoid the assignment operator warnings + + // These members hold the information we extract by parsing the string: - String m_strHostPort; // host we talk to - String m_strControl; // Control string - int m_nDelay; // Delay between power off and power on - String m_strAuxPort; // Auxiliary port (serial port to listen on if primary port is TCP/IP) - int m_nReadTimeout; // mSec to wait for board to say something - int m_nBaud; + StringArray m_arValidResetStrings; + String m_strHostPort; // host we talk to + String m_strControl; // Control string + int m_nDelay; // Delay between power off and power on + String m_strAuxPort; // Auxiliary port (serial port to listen on if primary port is TCP/IP) + int m_nReadTimeout; // mSec to wait for board to say something + int m_nBaud; // Baud rate - String m_strResetOutput; + String m_strResetOutput; // The output we get }; #endif diff --git a/host/tools/ecostest/common/TestResource.cpp b/host/tools/ecostest/common/TestResource.cpp --- a/host/tools/ecostest/common/TestResource.cpp +++ b/host/tools/ecostest/common/TestResource.cpp @@ -42,35 +42,32 @@ #include "eCosStd.h" #include "eCosTestUtils.h" #include "eCosTrace.h" -#ifdef _WIN32 - #include "Subprocess.h" -#endif +#include "Subprocess.h" + #include "TestResource.h" CTestResource *CTestResource::pFirstInstance=0; unsigned int CTestResource::nCount=0; -String CTestResource::strResourceHost; -int CTestResource::nResourcePort; +String CTestResource::strResourceHostPort; -CTestResource::CTestResource(LPCTSTR target, LPCTSTR pszDownloadPort, int nBaud, LPCTSTR pszResetString): +CTestResource::CTestResource(LPCTSTR pszHostPort, LPCTSTR target, LPCTSTR pszDownloadPort, int nBaud, LPCTSTR pszResetString): m_strReset(pszResetString), m_bInUse(false), m_nBaud(nBaud), m_strPort(pszDownloadPort), m_bLocked(false), - m_Target(target), - m_strHost(CeCosTestUtils::HostName()), - m_nPort(0) + m_Target(target) { - VTRACE(_T("@@@ Created resource %08x %s\n"),(unsigned int)this,(LPCTSTR)Output()); + CeCosSocket::ParseHostPort(pszHostPort,m_strHost,m_nPort); + VTRACE(_T("@@@ Created resource %08x %s\n"),(unsigned int)this,(LPCTSTR)Image()); Chain(); } CTestResource::~CTestResource() { ENTERCRITICAL; - VTRACE(_T("@@@ Destroy resource %08x %s\n"),this,(LPCTSTR)Output()); + VTRACE(_T("@@@ Destroy resource %08x %s\n"),this,(LPCTSTR)Image()); if(m_pPrevInstance || m_pNextInstance){ nCount--; } @@ -88,13 +85,17 @@ CTestResource::~CTestResource() // Find the resource matching the given host:port specification // Returns 0 if no such host:port found -CTestResource * CTestResource::Lookup(LPCTSTR pszHost, int nPort) +CTestResource * CTestResource::Lookup(LPCTSTR pszHostPort) { - CTestResource *pResource; + CTestResource *pResource=NULL; ENTERCRITICAL; - for(pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ - if(nPort==pResource->TcpipPort() && 0==_tcsicmp(pszHost,pResource->Host())){ - break; + String strHost; + int nPort; + if(CeCosSocket::ParseHostPort(pszHostPort,strHost,nPort)){ + for(pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ + if(nPort==pResource->TcpIPPort() && CeCosSocket::SameHost(strHost,pResource->Host())){ + break; + } } } LEAVECRITICAL; @@ -118,12 +119,12 @@ bool CTestResource::GetMatches (const Ce { bool rc=false; arstr.clear(); - if(LoadSocket()){ + if(Load()){ ENTERCRITICAL; for(CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ - if(pResource->Matches(e,bIgnoreLocking)){ - arstr.push_back(CeCosTestSocket::HostPort(pResource->Host(),pResource->TcpipPort())); - } + if(pResource->Matches(e,bIgnoreLocking)){ + arstr.push_back(pResource->HostPort()); + } } LEAVECRITICAL; rc=true; @@ -140,140 +141,141 @@ void CTestResource::DeleteAllInstances() LEAVECRITICAL; } -bool CTestResource::LoadFile (LPCTSTR psz,void *key) +bool CTestResource::LoadFromDirectory (LPCTSTR psz) { bool rc=true; ENTERCRITICAL; DeleteAllInstances(); -#ifdef _WIN32 - if(key){ - // Find all the keys under "psz" and load from each of them - HKEY hKey; - if(ERROR_SUCCESS==RegOpenKeyEx ((HKEY)key, psz, 0L, KEY_ENUMERATE_SUB_KEYS, &hKey)){ - TCHAR szName[256]; - DWORD dwSizeName=sizeof szName; - FILETIME ftLastWriteTime; - for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime); dwIndex++){ - CTestResource *pResource=new CTestResource(_T("")); - String strKey; - strKey.Format(_T("%s\\%s"),psz,szName); - CTestResourceProperties prop1(pResource,strKey,key); - prop1.SetDefaults(); - prop1.Load(); - dwSizeName=sizeof szName; - } - RegCloseKey(hKey); + // Find all the files in directory "psz" and load from each of them + TCHAR szOrigDir[256]; + _tgetcwd(szOrigDir,sizeof szOrigDir-1); + if(0==_tchdir(psz)){ + String strFile; + void *pHandle; + for(bool b=CeCosTestUtils::StartSearch(pHandle,strFile);b;b=CeCosTestUtils::NextFile(pHandle,strFile)){ + if(CeCosTestUtils::IsFile(strFile)){ + CTestResource *pResource=new CTestResource(_T(""),_T("")); + CTestResourceProperties prop(pResource); + prop.LoadFromFile(strFile); + } } - } else -#endif + CeCosTestUtils::EndSearch(pHandle); + } else { + TRACE(_T("Failed to change to %s from %s\n"),psz,szOrigDir); + } + _tchdir(szOrigDir); + LEAVECRITICAL; + + return rc; +} + +bool CTestResource::SaveToDirectory (LPCTSTR pszDir) +{ + bool rc=false; + ENTERCRITICAL; { - // Find all the files in directory "psz" and load from each of them + // Delete all the files under directory "pszDir" void *pHandle; TCHAR szOrigDir[256]; _tgetcwd(szOrigDir,sizeof szOrigDir-1); - if(0==_tchdir(psz)){ + if(0==_tchdir(pszDir)){ String strFile; for(bool b=CeCosTestUtils::StartSearch(pHandle,strFile);b;b=CeCosTestUtils::NextFile(pHandle,strFile)){ - struct _stat buf; - if(0==_tstat(strFile,&buf) && 0==(S_IFDIR&buf.st_mode)){ - CTestResource *pResource=new CTestResource(_T("")); - CTestResourceProperties prop1(pResource,strFile); - prop1.SetDefaults(); - prop1.Load(); + if(CeCosTestUtils::IsFile(strFile)){ + _tunlink(strFile); } } CeCosTestUtils::EndSearch(pHandle); + rc=true; + for(CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ + CTestResourceProperties prop(pResource); + rc&=prop.SaveToFile(pResource->FileName()); + } } else { - TRACE(_T("Failed to change to %s from %s\n"),psz,szOrigDir); + fprintf(stderr,"Failed to change to %s from %s\n",pszDir,szOrigDir); } _tchdir(szOrigDir); } + LEAVECRITICAL; return rc; } -bool CTestResource::SaveFile (LPCTSTR psz,void *key) +#ifdef _WIN32 +bool CTestResource::LoadFromRegistry(HKEY key,LPCTSTR psz) +{ + // Find all the keys under "psz" and load from each of them + bool rc=false; + ENTERCRITICAL; + HKEY hKey; + if(ERROR_SUCCESS==RegOpenKeyEx ((HKEY)key, psz, 0L, KEY_ENUMERATE_SUB_KEYS, &hKey)){ + TCHAR szName[256]; + DWORD dwSizeName=sizeof szName; + FILETIME ftLastWriteTime; + for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime); dwIndex++){ + CTestResource *pResource=new CTestResource(_T(""),_T("")); + String strKey; + strKey.Format(_T("%s\\%s"),psz,szName); + CTestResourceProperties prop1(pResource); + prop1.LoadFromRegistry(key,strKey); + dwSizeName=sizeof szName; + } + RegCloseKey(hKey); + } + LEAVECRITICAL; + return rc; +} + +bool CTestResource::SaveToRegistry(HKEY key,LPCTSTR psz) { bool rc=false; ENTERCRITICAL; -#ifdef _WIN32 - if(key){ - // Delete all the keys under "psz" - HKEY hKey; - if(ERROR_SUCCESS==RegOpenKeyEx ((HKEY)key, psz, 0L, KEY_ENUMERATE_SUB_KEYS, &hKey)){ - TCHAR szName[256]; - DWORD dwSizeName=sizeof szName; - FILETIME ftLastWriteTime; - DWORD dwIndex; - if(ERROR_SUCCESS==RegQueryInfoKey(hKey,0,0,0,&dwIndex,0,0,0,0,0,0,0)){ - while((signed)--dwIndex>=0){ - if(ERROR_SUCCESS!=RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime) || - ERROR_SUCCESS!=RegDeleteKey(hKey,szName)){ - rc=false; - } - dwSizeName=sizeof szName; - } + // Delete all the keys under "psz" + HKEY hKey; + if(ERROR_SUCCESS==RegOpenKeyEx ((HKEY)key, psz, 0L, KEY_ENUMERATE_SUB_KEYS, &hKey)){ + TCHAR szName[256]; + DWORD dwSizeName=sizeof szName; + FILETIME ftLastWriteTime; + DWORD dwIndex; + if(ERROR_SUCCESS==RegQueryInfoKey(hKey,0,0,0,&dwIndex,0,0,0,0,0,0,0)){ + while((signed)--dwIndex>=0){ + if(ERROR_SUCCESS!=RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime) || + ERROR_SUCCESS!=RegDeleteKey(hKey,szName)){ + rc=false; } - RegCloseKey(hKey); + dwSizeName=sizeof szName; + } } - } else -#endif - { - // Delete all the files under directory "psz" - void *pHandle; - TCHAR szOrigDir[256]; - _tgetcwd(szOrigDir,sizeof szOrigDir-1); - if(0==_tchdir(psz)){ - String strFile; - for(bool b=CeCosTestUtils::StartSearch(pHandle,strFile);b;b=CeCosTestUtils::NextFile(pHandle,strFile)){ - struct _stat buf; - if(0==_tstat(strFile,&buf) && 0==(S_IFDIR&buf.st_mode)){ - _tunlink(strFile); - } - } - CeCosTestUtils::EndSearch(pHandle); - } else { - fprintf(stderr,"Failed to change to %s from %s\n",psz,szOrigDir); - } - _tchdir(szOrigDir); + RegCloseKey(hKey); } - rc=true; for(CTestResource *pResource=pFirstInstance;pResource;pResource=pResource->m_pNextInstance){ - String strName; - if(key){ - strName.Format(_T("%s\\%s-%d"),psz,(LPCTSTR)pResource->m_strHost,pResource->m_nPort); - CTestResourceProperties prop1(pResource,strName,key); - rc&=prop1.Save(); - } else { - strName.Format(_T("%s%c%s-%d"),psz,cPathsep,(LPCTSTR)pResource->m_strHost,pResource->m_nPort); - CTestResourceProperties prop1(pResource,strName,key); - rc&=prop1.Save(); - } - + CTestResourceProperties prop1(pResource); + rc&=prop1.SaveToRegistry(key,pResource->FileName()); } + LEAVECRITICAL; - return rc; } -CTestResource::CTestResourceProperties::CTestResourceProperties(CTestResource *pResource,LPCTSTR psz,void *key): - CProperties(psz,key) +#endif + +CTestResource::CTestResourceProperties::CTestResourceProperties(CTestResource *pResource) { - CProperties::Add(_T("Baud"), pResource->m_nBaud,0); - Add(_T("BoardId"), pResource->m_strBoardID); - Add(_T("Date"), pResource->m_strDate); - Add(_T("Email"), pResource->m_strEmail); - Add(_T("Host"), pResource->m_strHost); - CProperties::Add(_T("Locked"), pResource->m_bLocked,0); - Add(_T("Originator"), pResource->m_strUser); - CProperties::Add(_T("Port"), pResource->m_nPort); - Add(_T("Reason"), pResource->m_strReason); - Add(_T("Reset"), pResource->m_strReset); - Add(_T("Serial"), pResource->m_strPort); - Add(_T("Target"), pResource->m_Target); - Add(_T("User"), pResource->m_strUser); + Add(_T("Baud"), pResource->m_nBaud); + Add(_T("BoardId"), pResource->m_strBoardID); + Add(_T("Date"), pResource->m_strDate); + Add(_T("Email"), pResource->m_strEmail); + Add(_T("Host"), pResource->m_strHost); + Add(_T("Port"), pResource->m_nPort); + Add(_T("Locked"), pResource->m_bLocked); + Add(_T("Originator"), pResource->m_strUser); + Add(_T("Reason"), pResource->m_strReason); + Add(_T("Reset"), pResource->m_strReset); + Add(_T("Serial"), pResource->m_strPort); + Add(_T("Target"), pResource->m_Target); + Add(_T("User"), pResource->m_strUser); } bool CTestResource::Lock() @@ -296,7 +298,7 @@ bool CTestResource::Unlock() } } -bool CTestResource::LoadSocket(LPCTSTR pszResourceHost,int nResourcePort,Duration dTimeout/*=10*1000*/) +bool CTestResource::LoadSocket(LPCTSTR pszResourceHostPort,Duration dTimeout/*=10*1000*/) { bool rc=false; ENTERCRITICAL; @@ -305,8 +307,8 @@ bool CTestResource::LoadSocket(LPCTSTR p for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){ pResource->m_bFlag=false; } - CeCosTestSocket sock; - if(sock.Connect(pszResourceHost,nResourcePort,dTimeout)){ + CeCosSocket sock; + if(sock.Connect(pszResourceHostPort,dTimeout)){ // Write the message to the socket int nRequest=0; // read if(!sock.sendInteger(nRequest)){ @@ -321,9 +323,9 @@ bool CTestResource::LoadSocket(LPCTSTR p VTRACE(_T("Recv \"%s\"\n"),(LPCTSTR)strImage); CTestResource tmp; tmp.FromStr(strImage); - CTestResource *pResource=Lookup(tmp.Host(),tmp.TcpipPort()); + CTestResource *pResource=Lookup(tmp.HostPort()); if(0==pResource){ - pResource=new CTestResource(_T("")); + pResource=new CTestResource(_T(""),_T("")); } pResource->FromStr(strImage); pResource->m_bFlag=true; @@ -348,12 +350,53 @@ bool CTestResource::LoadSocket(LPCTSTR p return rc; } +bool CTestResource::SaveSocket(LPCTSTR pszResourceHostPort,Duration dTimeout) +{ + bool rc=true; + ENTERCRITICAL; + CeCosSocket sock(pszResourceHostPort, dTimeout); + if(sock.Ok()){ + // Write the message to the socket + int nRequest=1; //write + if(!sock.sendInteger(nRequest, _T(""),dTimeout)){ + ERROR(_T("Failed to write to socket\n")); + rc=false; + } else { + int nResources=0; + CTestResource *pResource; + for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){ + nResources++; + } + if(sock.sendInteger(nResources,_T("resource count"),dTimeout)){ + for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){ + String strImage; + CTestResourceProperties prop(pResource); + strImage=prop.MakeCommandString(); + TRACE(_T("Send \"%s\"\n"),(LPCTSTR)strImage); + if(!sock.sendString (strImage, _T("reply"),dTimeout)){ + rc=false; + break; + } + } + } else { + rc=false; + } + } + } else { + rc=false; + } + LEAVECRITICAL; + return rc; +} + +/* void CTestResource::Image(String &str) { CTestResourceProperties prop(this); str=prop.MakeCommandString(); VTRACE(_T("Make command string %s\n"),(LPCTSTR)str); } +*/ bool CTestResource::FromStr(LPCTSTR pszImage) { @@ -378,52 +421,14 @@ void CTestResource::Chain() bool CTestResource::Matches (const CeCosTest::ExecutionParameters &e,bool bIgnoreLocking) const { - return (bIgnoreLocking||(!m_bLocked)) && (0==_tcsicmp(e.Target(),m_Target)); + return (bIgnoreLocking||(!m_bLocked)) && (0==_tcsicmp(e.PlatformName(),m_Target)); }; -bool CTestResource::SaveSocket(LPCTSTR pszResourceServer,int nResourcePort,Duration dTimeout) -{ - bool rc=true; - ENTERCRITICAL; - CeCosTestSocket sock(pszResourceServer,nResourcePort, dTimeout); - if(sock.Ok()){ - // Write the message to the socket - int nRequest=1; //write - if(!sock.sendInteger(nRequest, _T(""),dTimeout)){ - ERROR(_T("Failed to write to socket\n")); - rc=false; - } else { - int nResources=0; - CTestResource *pResource; - for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){ - nResources++; - } - if(sock.sendInteger(nResources,_T("resource count"),dTimeout)){ - for(pResource=CTestResource::First();pResource;pResource=pResource->Next()){ - String strImage; - pResource->Image(strImage); - TRACE(_T("Send \"%s\"\n"),(LPCTSTR)strImage); - if(!sock.sendString (strImage, _T("reply"),dTimeout)){ - rc=false; - break; - } - } - } else { - rc=false; - } - } - } else { - rc=false; - } - LEAVECRITICAL; - return rc; -} - CeCosTest::ServerStatus CTestResource::Query() { CeCosTest::ExecutionParameters e(CeCosTest::ExecutionParameters::QUERY,m_Target); - CeCosTestSocket *pSock=0; - CeCosTest::ServerStatus s=CeCosTest::Connect(m_strHost,m_nPort,pSock,e,m_strInfo); + CeCosSocket *pSock=0; + CeCosTest::ServerStatus s=CeCosTest::Connect(HostPort(),pSock,e,m_strInfo); delete pSock; return s; } @@ -472,31 +477,22 @@ CTestResource *CTestResource::GetResourc return p; } -String CTestResource::Output() const +const String CTestResource::Image() const { String str; - str.Format( - _T("%10s:%d %20s %8s"), - Host(), - TcpipPort(), - Target(), - Serial()); - if(HasReset()){ - str+=_T(" Reset:"); - str+=m_strReset; - } + str.Format(_T("%10s %20s %8s"),(LPCTSTR)HostPort(),(LPCTSTR)Target(),(LPCTSTR)Serial()); if(IsLocked()){ str+=_T(" [RL]"); } return str; } -bool CTestResource::Matches(LPCTSTR pszHost, int nPort, const CeCosTest::ExecutionParameters &e) +bool CTestResource::Matches(LPCTSTR pszHostPort, const CeCosTest::ExecutionParameters &e) { bool rc=false; ENTERCRITICAL; - if(LoadSocket()){ - CTestResource *pResource=Lookup(pszHost,nPort); + if(Load()){ + CTestResource *pResource=Lookup(pszHostPort); if(pResource){ rc=pResource->Matches(e); } @@ -525,28 +521,23 @@ void CALLBACK CTestResource::StringLogFu CResetAttributes::ResetResult CTestResource::RemoteReset(LogFunc *pfnLog, void *pfnLogparam) { + String strHost; + int nPort; + CeCosSocket::ParseHostPort(HostPort(),strHost,nPort); String strCmd; - strCmd.Format(_T("rsh %s x10reset %s\n"),Host(),ResetString()); + strCmd.Format(_T("rsh %s x10reset %s\n"),(LPCTSTR)strHost,ResetString()); pfnLog(pfnLogparam,strCmd); -#ifdef _WIN32 - // because this can be used from GUI tools CSubprocess sp; sp.Run(pfnLog,pfnLogparam,strCmd); -#else // UNIX - FILE *f=POPEN(strCmd,"rt"); - if(f){ - char buf[80]; - while(fgets(buf,sizeof buf,f)){ - pfnLog(pfnLogparam,buf); - } - PCLOSE(f); - } else { - String strMsg; - strMsg.Format(_T("Failed to execute '%s'\n"),(LPCTSTR)strCmd); - pfnLog(pfnLogparam,strMsg); - } -#endif return CResetAttributes::RESET_OK; // FIXME } +String CTestResource::FileName() const +{ + String strHost; + int nPort; + CeCosSocket::ParseHostPort(HostPort(),strHost,nPort); + return String::SFormat(_T("%s-%d"),(LPCTSTR)strHost,nPort); +} + diff --git a/host/tools/ecostest/common/TestResource.h b/host/tools/ecostest/common/TestResource.h --- a/host/tools/ecostest/common/TestResource.h +++ b/host/tools/ecostest/common/TestResource.h @@ -42,76 +42,83 @@ #ifndef _TESTRESOURCE_H #define _TESTRESOURCE_H + +#include "Collections.h" #include "eCosStd.h" #include "eCosTest.h" -#include "eCosTestSerial.h" +#include "eCosSerial.h" #include "Properties.h" #include "ResetAttributes.h" // This class is used to manipulate test resources. A test resource is the means to execute -// a test (a test agent running on a tcp/ip port) +// a test (usually an eCosTestServer running on a tcp/ip port) class CTestResource { public: - class CTestResourceProperties : public CProperties { - public: - CTestResourceProperties(CTestResource *pResource,LPCTSTR psz=0,void *key=0); - virtual ~CTestResourceProperties(){} - void Add(LPCTSTR pszName,String &str,LPCTSTR pszDefault=_T("")) {CProperties::Add(pszName,(void *)&str,GetFn,PutFn,pszDefault);} - protected: - static LPCTSTR CALLBACK GetFn (void *pObj) { return (LPCTSTR)*(String *)pObj; } - static void CALLBACK PutFn (void *pObj,LPCTSTR psz) { *(String *)pObj=psz; } - }; - friend class CTestResourceProperties; - // ctors/dtors CTestResource( + LPCTSTR pszHostPort, // Where the resource "lives" - i.e. the host and TCP/IP port for the server LPCTSTR target, // Physical port characteristics. If pszPort is null, simulator run is meant (in which case nBaud is ignored) LPCTSTR pszPort=0, int nBaud=0, // Associated reset characteristics: pszPort may be a remote server (host:port) or a local port LPCTSTR pszResetString=_T("") ); + // Not chained or fully initialized + CTestResource():m_nBaud(0),m_bLocked(false),m_pNextInstance(0),m_pPrevInstance(0){} virtual ~CTestResource(); - bool Use(); - + bool Use(); // Mark this resource as "in use" + + // This causes the reset to be performed (via rsh, on the machine CResetAttributes::ResetResult RemoteReset(LogFunc *pfnLog, void *pfnLogparam=0); - String Output() const; + const String Image() const; - static void UnlockResources(LPCTSTR pszFile,int nLine); - static void LockResources (LPCTSTR pszFile,int nLine); - void Image (String &str); - static bool SaveSocket (Duration dTimeout=10*1000) { return SaveSocket(strResourceHost,nResourcePort,dTimeout); } - static bool LoadSocket (Duration dTimeout=10*1000) { return LoadSocket(strResourceHost,nResourcePort,dTimeout); } + // Receive details from the socket + static bool Load(Duration dTimeout=10*1000) { return LoadSocket(strResourceHostPort,dTimeout); } + static bool Save(Duration dTimeout=10*1000) { return SaveSocket(strResourceHostPort,dTimeout); } CeCosTest::ServerStatus Query(); + + // [Resource] locking: bool Unlock(); bool Lock (); + bool IsLocked() const { return m_bLocked; } + static CTestResource *First() { return pFirstInstance; } CTestResource *Next() const { return m_pNextInstance; } - static CTestResource * Lookup(LPCTSTR pszHost, int nPort); + static CTestResource * Lookup(LPCTSTR pszHostPort); static unsigned int ResourceCount() { return nCount; } static void DeleteAllInstances(); - bool IsLocked() const { return m_bLocked; } - static bool LoadFile (LPCTSTR psz,void *key=0); // Load information from the registry or a file - static bool SaveFile (LPCTSTR psz,void *key=0); // Save information to the registry or a file + static bool LoadFromDirectory (LPCTSTR psz); // Load information from a set of files in given directory + static bool SaveToDirectory (LPCTSTR psz); // Save information, likewise +#ifdef _WIN32 + static bool SaveToRegistry(HKEY key,LPCTSTR pszKey); // Save information to the registry + static bool LoadFromRegistry(HKEY key,LPCTSTR pszKey);// Load information from the registry +#endif + void SetInfo (LPCTSTR pszInfo) { m_strInfo=pszInfo; } LPCTSTR Info() const { return m_strInfo; } - // Attributes - LPCTSTR Host() const { return m_strHost; } - int TcpipPort() const { return m_nPort; } + // Host and TCP/IP port: + String HostPort() const { return CeCosSocket::HostPort(m_strHost,m_nPort); } + // Same information, but separately: + String Host() const { return m_strHost; } + int TcpIPPort() const { return m_nPort; } + + // Serial (comms) port: LPCTSTR Serial() const { return m_strPort; } LPCTSTR Target() const { return m_Target; } - bool HasReset() const { return m_strReset.GetLength()>0; } + // Is there an associated reset string? + bool HasReset() const { return !m_strReset.empty(); } - int Baud() const { return m_nBaud; } // Baud rate + // Baud rate: + int Baud() const { return m_nBaud; } - void SetHostPort(LPCTSTR pszHost,int nPort) { m_strHost=pszHost;m_nPort=nPort; } + void SetHostPort(LPCTSTR pszHostPort) { CeCosSocket::ParseHostPort(pszHostPort,m_strHost,m_nPort); } void SetTarget (LPCTSTR target) { m_Target=target; } void SetDownload(LPCTSTR pszDownloadPort,int nBaud) { m_strPort=pszDownloadPort; m_nBaud=nBaud; } @@ -134,41 +141,53 @@ public: static unsigned int GetMatchCount (const CeCosTest::ExecutionParameters &e,bool bIgnoreLocking=false); static bool GetMatches (const CeCosTest::ExecutionParameters &e,StringArray &arstr,bool bIgnoreLocking=false); // as before, but callee allocates. Deallocate using delete []. - static void SetResourceServer (LPCTSTR pszHost,int nPort){ strResourceHost=pszHost;nResourcePort=nPort; } + static bool SetResourceServer (LPCTSTR pszHostPort) { bool b=CeCosSocket::IsLegalHostPort(pszHostPort);if(b)strResourceHostPort=pszHostPort; return b;} + static String GetResourceServer (){ return strResourceHostPort; } + static bool ResourceServerSet() { return CeCosSocket::IsLegalHostPort(GetResourceServer()); } static CTestResource *GetResource(const CeCosTest::ExecutionParameters &e); void Release() { - //TRACE(_T("Release %s\n"),Serial1()); + //VTRACE(_T("Release %s\n"),Serial1()); m_bInUse=false; } - + bool InUse() const { return m_bInUse; } static int Count (const CeCosTest::ExecutionParameters &e); // Reset the hardware attached to this port. Output goes to pfnLog CResetAttributes::ResetResult Reset(LogFunc *pfnLog=0, void *pfnLogparam=0); CResetAttributes::ResetResult Reset(String &str); // as above, output to string - static bool Matches(LPCTSTR pszHost, int nPort, const CeCosTest::ExecutionParameters &e); + static bool Matches(LPCTSTR pszHostPort, const CeCosTest::ExecutionParameters &e); bool FromStr(LPCTSTR pszImage); LPCTSTR ResetString() const { return m_strReset; } + + class CTestResourceProperties : public CProperties { + public: + CTestResourceProperties(CTestResource *pResource); + virtual ~CTestResourceProperties(){} + protected: + }; + protected: - CTestResource():m_pNextInstance(0),m_pPrevInstance(0){} // not chained or initialized - for internal use only + + friend class CTestResourceProperties; + + String FileName() const; String m_strReason,m_strUser,m_strEmail,m_strBoardID, m_strDate; String m_strReset; static void CALLBACK StringLogFunc (void *pParam,LPCTSTR psz); - static bool LoadSocket (LPCTSTR pszHost,int nPort,Duration dTimeout=10*1000); - static bool SaveSocket (LPCTSTR pszHost,int nPort,Duration dTimeout=10*1000); + static bool LoadSocket (LPCTSTR pszHostPort,Duration dTimeout=10*1000); + static bool SaveSocket (LPCTSTR pszHostPort,Duration dTimeout=10*1000); static LPCTSTR szFormat; void Chain(); unsigned static int nCount; - static String strResourceHost; - static int nResourcePort; + static String strResourceHostPort; static CTestResource *pFirstInstance; bool Matches (const CeCosTest::ExecutionParameters &e,bool bIgnoreLocking=false) const; diff --git a/host/tools/ecostest/common/X10.h b/host/tools/ecostest/common/X10.h --- a/host/tools/ecostest/common/X10.h +++ b/host/tools/ecostest/common/X10.h @@ -41,7 +41,7 @@ //####DESCRIPTIONEND#### #ifndef _CX10_H #define _CX10_H -#include "eCosTestSerial.h" +#include "eCosSerial.h" class CX10 { public: @@ -51,7 +51,7 @@ public: bool Power(bool bOn,int cControl1,int cControl2,int &nErr); // Perform a reset on this port, with these control chars bool Ok(){return m_Serial.Ok();} protected: - CeCosTestSerial m_Serial; + CeCosSerial m_Serial; bool PutChar (unsigned char c); bool GetChar (unsigned char &c); bool ReceiveIPS(); diff --git a/host/tools/ecostest/common/eCosTest.cpp b/host/tools/ecostest/common/eCosTest.cpp --- a/host/tools/ecostest/common/eCosTest.cpp +++ b/host/tools/ecostest/common/eCosTest.cpp @@ -42,29 +42,20 @@ /////////////////////////////////////////////////////////////////////////////// #include "eCosStd.h" #include "eCosTest.h" +#include "eCosTestPlatform.h" #include "eCosTrace.h" #include "TestResource.h" #include "eCosTestUtils.h" -#include "eCosTestSocket.h" -#include "eCosTestSerial.h" +#include "eCosSocket.h" +#include "eCosSerial.h" #include "eCosTestSerialFilter.h" #include "eCosTestDownloadFilter.h" +#include "Properties.h" +#include "Subprocess.h" #define WF(n) (n+50)/1000,((n+50)%1000)/100 // Present n as whole and fractional part. Round to nearest least significant digit #define WFS _T("%u.%u") // The format string to output the above -static int nAuxPort; //hack -static int nAuxListenSock; // hack - -#ifdef _WIN32 - #include "Subprocess.h" - #ifdef _DEBUG - #define CloseHandle(x) try { ::CloseHandle(x); } catch(...) { TRACE(_T("!!! Exception caught closing handle %08x\n"),x); } - #endif -#endif - -std::vector CeCosTest::arTargetInfo; - LPCTSTR const CeCosTest::arResultImage[1+CeCosTest::StatusTypeMax]= {_T("NotStarted"), _T("NoResult"), _T("Inapplicable"), _T("Pass"), _T("DTimeout"), _T("Timeout"), _T("Cancelled"), _T("Fail"), _T("AssertFail"), _T("Unknown")}; @@ -76,218 +67,6 @@ LPCTSTR const CeCosTest::arServerStatus LPCTSTR CeCosTest::ExecutionParameters::arRequestImage [1+ExecutionParameters::RequestTypeMax]={ _T("Run"), _T("Query"), _T("Lock"), _T("Unlock"), _T("Stop"), _T("Bad request") }; -const CeCosTest::TargetInfo CeCosTest::tDefault(_T("Unknown"),_T(""),-1); - -// Do not use spaces in image strings for consideration of _stscanf -// One day this can be loadable from some external resource. -int CeCosTest::InitTargetInfo(LPCTSTR pszFilename) -{ - TRACE(_T("InitTargetInfo %s\n"),pszFilename); - FILE *f=_tfopen(pszFilename,_T("rt")); - if(f){ - enum {BUFSIZE=512}; - int nLine=0; - TCHAR buf[BUFSIZE]; - while(_fgetts(buf,sizeof(buf)-1,f)){ - nLine++; - StringArray ar; - String(buf).Chop(ar); - switch(ar.size()){ - // [] - case 0: - continue; - case 3: - arTargetInfo.push_back(TargetInfo(ar[0],ar[1],ar[2],0)); - break; - case 1: - case 2: - ERROR(_T("Illegal configuration at line %d\n"),nLine); - continue; - default: - arTargetInfo.push_back(TargetInfo(ar[0],ar[1],ar[2],ar[3])); - break; - } - } - fclose(f); - } - return arTargetInfo.size(); -} - -int CeCosTest::InitTargetInfoReg(LPCTSTR pszRegKey) -{ - -#ifdef _WIN32 - HKEY hKey; - bool rc=ERROR_SUCCESS==RegOpenKeyEx (HKEY_LOCAL_MACHINE, pszRegKey, 0L, KEY_READ, &hKey); - DWORD dwSubKeys=0; - if(rc){ - // Found the given key. - // Subkeys' names are the target image names: - // Subkeys's values are: - // Prefix String - // Type String - // GdbCmd String [optional] - FILETIME ftLastWriteTime; - DWORD dwMaxSubKeyLen; - if(ERROR_SUCCESS==RegQueryInfoKey(hKey,NULL,NULL,NULL,&dwSubKeys,&dwMaxSubKeyLen,NULL,NULL,NULL,NULL,NULL,NULL)){ - TCHAR *szName=new TCHAR[1+dwMaxSubKeyLen]; - DWORD dwSizeName=dwMaxSubKeyLen; - for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime); dwIndex++){ - HKEY hKey2; - if(ERROR_SUCCESS!=RegOpenKeyEx (hKey, szName, 0L, KEY_READ, &hKey2)){ - ERROR(_T("Failed to open %s\\%s\n"),pszRegKey,szName); - rc=false; - } else { - DWORD dwMaxValueLen; - if(ERROR_SUCCESS==RegQueryInfoKey(hKey2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dwMaxValueLen,NULL,NULL)){ - DWORD dwSizePrefix=dwMaxValueLen; - DWORD dwSizeGdbCmd=dwMaxValueLen; - DWORD dwSizeHwType=dwMaxValueLen; - TCHAR *szPrefix=new TCHAR[1+dwMaxValueLen]; - TCHAR *szGdbCmd=new TCHAR[1+dwMaxValueLen]; - TCHAR *szHwType=new TCHAR[1+dwMaxValueLen]; - if(ERROR_SUCCESS==RegQueryValueEx(hKey2, _T("Prefix"),NULL, NULL,(LPBYTE)szPrefix,&dwSizePrefix)){ - arTargetInfo.push_back(TargetInfo(szName,szPrefix, - (ERROR_SUCCESS==RegQueryValueEx(hKey2,_T("HwType"),NULL, NULL,(LPBYTE)szHwType,&dwSizeHwType))?szHwType:_T(""), - (ERROR_SUCCESS==RegQueryValueEx(hKey2,_T("GdbCmd"),NULL, NULL,(LPBYTE)szGdbCmd,&dwSizeGdbCmd))?szGdbCmd:0 - )); - } - delete [] szPrefix; - delete [] szGdbCmd; - delete [] szHwType; - } - RegCloseKey(hKey2); - } - dwSizeName=dwMaxSubKeyLen; - } - delete [] szName; - } - RegCloseKey(hKey); - } - return rc?dwSubKeys:0; -#else // UNIX - return 0; -#endif -} - -bool CeCosTest::Init() -{ - TRACE(_T("CeCosTest::Init\n")); - srand( (unsigned)time( NULL ) ); - -#ifdef _WIN32 - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD( 2, 0 ); - WSAStartup( wVersionRequested, &wsaData ); - - // get target info from the registry - String strPlatformsKey = _T("Software\\Red Hat\\eCos\\"); - strPlatformsKey += GetGreatestSubkey (_T("Software\\Red Hat\\eCos")); - strPlatformsKey += _T("\\Platforms"); - InitTargetInfoReg (strPlatformsKey); - - // add target info from .eCosrc - LPCTSTR psz=_tgetenv(_T("HOMEDRIVE")); - if(psz){ - String strFile(psz); - psz=_tgetenv(_T("HOMEPATH")); - if(psz){ - strFile+=psz; - } - if(_TCHAR('\\')!=strFile[strFile.GetLength()-1]){ - strFile+=_TCHAR('\\'); - } - strFile+=_T(".eCosrc"); - InitTargetInfo(strFile); - } -#else // UNIX - sigset_t mask; - - // Clean out all the signals - sigemptyset(&mask); - - // Add our sigpipe - sigaddset(&mask, SIGPIPE); - - sigprocmask(SIG_SETMASK, &mask, NULL); - - // _WIN32 not defined so get target info from .eCosrc - LPCTSTR psz=_tgetenv(_T("HOME")); - if(psz){ - String strFile(psz); - strFile+=_T("/.eCosrc"); - InitTargetInfo(strFile); - } -#endif - if(0==TargetTypeMax()){ - ERROR(_T("Failed to initialize any targets\n")); - } - return true; -} - -void CeCosTest::Term() -{ - - TRACE(_T("CeCosTest::Term\n")); - -#ifdef _WIN32 - WSACleanup(); -#endif -}; - -bool CeCosTest::SaveTargetInfo() -{ -#ifdef _WIN32 - // save target info to the registry - String strPlatformsKey = _T("Software\\Red Hat\\eCos\\"); - strPlatformsKey += GetGreatestSubkey (_T("Software\\Red Hat\\eCos")); - strPlatformsKey += _T("\\Platforms"); - return SaveTargetInfoReg (strPlatformsKey); -#else // UNIX - // get target info from .eCosrc - String strFile=_tgetenv(_T("HOME")); - if(strFile.GetLength()>0){ - strFile+=_T("/.eCosrc"); - return SaveTargetInfo(strFile); - } else { - return false; - } -#endif -} - -bool CeCosTest::SaveTargetInfo(LPCTSTR pszFilename) -{ - return false; //FIXME -} - -#ifdef _WIN32 -bool CeCosTest::SaveTargetInfoReg(LPCTSTR pszRegKey) -{ - CProperties::CreateKey(pszRegKey,HKEY_LOCAL_MACHINE); - HKEY hKey; - bool rc=ERROR_SUCCESS==RegOpenKeyEx (HKEY_LOCAL_MACHINE, pszRegKey, 0L, KEY_ALL_ACCESS, &hKey); - if(rc){ - for(int i=0;i<(signed)arTargetInfo.size();i++){ - HKEY hKey2; - DWORD dwDisp; - const TargetInfo &ti=arTargetInfo[i]; - rc&=(ERROR_SUCCESS==RegCreateKeyEx(hKey,ti.Image(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey2, &dwDisp)); - if(rc){ - LPCTSTR pszPrefix=ti.Prefix(); - LPCTSTR pszGdb =ti.GdbCmd(); - LPCTSTR pszHwType=CeCosTest::TargetInfo::arHwTypeImage[ti.Type()]; - rc&=(ERROR_SUCCESS==RegSetValueEx(hKey2,_T("Prefix"),0,REG_SZ, (CONST BYTE *)pszPrefix,(1+_tcslen(pszPrefix))*sizeof TCHAR)) && - (ERROR_SUCCESS==RegSetValueEx(hKey2,_T("HwType"),0,REG_SZ, (CONST BYTE *)pszHwType,(1+_tcslen(pszHwType))*sizeof TCHAR)) && - (ERROR_SUCCESS==RegSetValueEx(hKey2,_T("GdbCmd"),0,REG_SZ, (CONST BYTE *)pszGdb,(1+_tcslen(pszGdb))*sizeof TCHAR)); - } - RegCloseKey(hKey2); - } - RegCloseKey(hKey); - } - return rc; -} -#endif - static bool CALLBACK IsCancelled(void *pThis) { return CeCosTest::Cancelled==((CeCosTest *)pThis)->Status(); @@ -295,7 +74,7 @@ static bool CALLBACK IsCancelled(void *p // Ctors and dtors: CeCosTest::CeCosTest(const ExecutionParameters &e, LPCTSTR pszExecutable,LPCTSTR pszTitle): -m_nRunCount(0), + m_pspPipe(0), m_nStrippedSize(0), m_nFileSize(0), m_bDownloading(false), @@ -306,13 +85,22 @@ m_nRunCount(0), m_nDownloadTime(0), m_nTotalTime(0), m_nMaxInactiveTime(0), - m_pPort(0) + m_pResource(0), + m_psp(0) { + + assert(e.Platform()); + SetExecutable (pszExecutable); TRACE(_T("%%%% Create test instance %08x count:=%d\n"),this,InstanceCount+1); - - GetPath(m_strPath); + + // By recording the path now, we ensure processes are always run in the context in which the test instance + // is created (important for the ConfigTool to be able to call PrepareEnvironment). + LPCTSTR pszPath=_tgetenv(_T("PATH")); + if(pszPath){ + m_strPath=pszPath; + } ENTERCRITICAL; InstanceCount++; @@ -328,13 +116,18 @@ m_nRunCount(0), CeCosTest::~CeCosTest() { + for(int i=0;i<(signed)m_arpExecsp.size();i++){ + delete (CSubprocess *)m_arpExecsp[i]; + } + delete m_pspPipe; + TRACE(_T("%%%% Delete test instance %08x\n"),this); Cancel(); CloseSocket(); - if(m_pPort){ - m_pPort->Release(); - //delete m_pPort; - //m_pPort=0; + if(m_pResource){ + m_pResource->Release(); + //delete m_pResource; + //m_pResource=0; } VTRACE(_T("~CeCosTest(): EnterCritical and decrease instance count\n")); @@ -356,10 +149,8 @@ CeCosTest::~CeCosTest() bool CeCosTest::RunRemote (LPCTSTR pszRemoteHostPort) { bool rc=false; - m_nRunCount++; TRACE(_T("RunRemote\n")); m_strExecutionHostPort=pszRemoteHostPort; - SetPath(m_strPath); m_Status=NotStarted; VTRACE(_T("RemoteThreadFunc()\n")); @@ -367,7 +158,7 @@ bool CeCosTest::RunRemote (LPCTSTR pszRe // Find a server. ConnectForExecution(); if(Cancelled!=Status()){ - if(ServerSideGdb()){ + if(m_ep.Platform()->ServerSideGdb()){ // The executable is transmitted to the server for execution. // Send file size if(m_pSock->sendInteger(m_nFileSize,_T("file size"))&&m_nFileSize>0){ @@ -377,16 +168,16 @@ bool CeCosTest::RunRemote (LPCTSTR pszRe int nToSend=m_nFileSize; FILE *f1=_tfopen(m_strExecutable,_T("rb")); if(0==f1){ - Log(_T("Failed to open %s - %s\n"),(LPCTSTR )m_strExecutable,strerror(errno)); + Log(_T("Failed to open %s - %s\n"),(LPCTSTR)m_strExecutable,strerror(errno)); } else { while (nToSend>0){ int nRead=fread( b.Data(), 1, nBufSize, f1); if(nRead<=0){ - Log(_T("Failure reading %s - %s\n"),(LPCTSTR )m_strExecutable,strerror(errno)); + Log(_T("Failure reading %s - %s\n"),(LPCTSTR)m_strExecutable,strerror(errno)); break; } if(!send( b.Data(), nRead, _T("executable"))){ - Log(_T("Failure sending %s - %s\n"),(LPCTSTR )m_strExecutable,(LPCTSTR )m_pSock->SocketErrString()); + Log(_T("Failure sending %s - %s\n"),(LPCTSTR)m_strExecutable,(LPCTSTR)m_pSock->SocketErrString()); break; } nToSend-=nRead; @@ -395,7 +186,7 @@ bool CeCosTest::RunRemote (LPCTSTR pszRe f1=0; if(nToSend>0){ TRACE(_T("done [%d bytes sent]\n"),m_nFileSize-nToSend); - Log(_T("Failed to transmit %s - %d/%d bytes sent\n"),(LPCTSTR )m_strExecutable,m_nFileSize-nToSend,m_nFileSize); + Log(_T("Failed to transmit %s - %d/%d bytes sent\n"),(LPCTSTR)m_strExecutable,m_nFileSize-nToSend,m_nFileSize); } else { TRACE(_T("done\n")); rc=true; @@ -405,12 +196,11 @@ bool CeCosTest::RunRemote (LPCTSTR pszRe Log(_T("Failed to receive result from remote server\n")); rc=false; } - m_pSock->sendInteger(1); // send an ack [n'importe quoi] + m_pSock->sendInteger(456); // send an ack [n'importe quoi] CloseSocket(); } } else { // The server sets up a connection between port and tcp/ip socket, and gdb is run locally - String strHostPort,strOutput; // Big timeout here because we have to wait for the target to be reset // We do this: // do { @@ -418,50 +208,50 @@ bool CeCosTest::RunRemote (LPCTSTR pszRe // any output so far // } while (2==target ready indicator) // read host:port + String strHostPort; if(GetTargetReady(strHostPort)){ - ENTERCRITICAL; - m_pPort=new CTestResource(Target(), strHostPort, 0); - m_pPort->Use(); - LEAVECRITICAL; + // Fix up a resource to represent permission to use the host:port we have been told about + CTestResource resource; + resource.SetTarget(m_ep.PlatformName()); + resource.SetDownload(strHostPort,0); + m_pResource=&resource; RunLocal(); - delete m_pPort; - m_pPort=0; - m_pSock->sendInteger(123,_T("Terminating ack")); + m_pResource=0; + m_pSock->sendInteger(Status(),_T("Terminating ack")); m_pSock->Close(); rc=true; } } } - TRACE(_T("RemoteThreadFunc(): Exiting\n")); + TRACE(_T("RemoteThreadFunc - exiting\n")); return rc; } // Run the test locally bool CeCosTest::RunLocal() { - m_nRunCount++; bool rc=false; - if(0==CTestResource::Count(m_ep)){ - Log(_T("Cannot run a %s test\n"),m_ep.Target()); + + TRACE(_T("RunLocal %s\n"),(LPCTSTR)Executable()); + + if(!CeCosTestUtils::IsFile(Executable())){ + Log(_T("Cannot run - %s is not a file\n"),(LPCTSTR)Executable()); + } else if(0==m_pResource && 0==CTestResource::Count(m_ep)){ + Log(_T("Cannot run a %s test\n"),(LPCTSTR)m_ep.PlatformName()); } else { - TRACE(_T("Run %s, timeouts: active=%d elapsed=%d\n"),(LPCTSTR )m_strExecutable, ActiveTimeout(), DownloadTimeout()); m_Status=NotStarted; - m_tPrevSample=Now(); - m_tGdbCpuTime=0; - GetPath(m_strPath); - - TRACE(_T("LocalThreadFunc - target=%s\n"),Target()); + TRACE(_T("LocalThreadFunc - target=%s\n"),(LPCTSTR)m_ep.PlatformName()); // Acquire a port (our caller may have done this for us) VTRACE(_T("LocalThreadFunc():Tring to acquire a port\n")); - if(0==m_pPort){ + if(0==m_pResource){ for(;;){ - m_pPort=CTestResource::GetResource(m_ep); - if(m_pPort||Cancelled==Status()){ + m_pResource=CTestResource::GetResource(m_ep); + if(m_pResource||Cancelled==Status()){ break; } - Sleep(2000); + CeCosThreadUtils::Sleep(2000); TRACE(_T("Waiting for a port\n")); } } @@ -470,117 +260,50 @@ bool CeCosTest::RunLocal() if(Cancelled!=Status()){ // This means we have acquired a local port bool bTargetReady=false; - if(!m_pPort->HasReset()){ + if(!m_pResource->HasReset()){ bTargetReady=true; } else { - bTargetReady=(CResetAttributes::RESET_OK==Reset(false)); + bTargetReady=(CResetAttributes::RESET_OK==m_pResource->Reset(0,this)); } // we may proceed to execute the test if(bTargetReady){ SetStatus(NotStarted); - if(_TCHAR('\0')!=*(m_pPort->Serial())){ + + if(NOTIMEOUT==m_ep.DownloadTimeout()){ // No elapsed timeout given - calculate from knowledge of executable size and baud rate // 10 baud ~= 1 byte/sec, but we halve this to account for download in hex :-( - // This means that a 200k executable is given ~100 seconds - // In any case the whole thing is an overestimate [we should use the stripped size] - // We use a minimum of 30 seconds and add 50% for safety - int nSpeed=((0==m_pPort->Baud()?9600:m_pPort->Baud())/10)/2; // Hex - nSpeed/=2; // Safety - if(NOTIMEOUT==m_ep.DownloadTimeout()){ - m_ep.SetDownloadTimeout (1000*MAX(60,(m_nStrippedSize/nSpeed))); + // We use a minimum of 30 seconds and double the calculated result for safety + // Note that the baud rate is generally unknown on the client side. + int nBaud=m_pResource->Baud(); + if(0==nBaud){ + CTestResource *pExecutionResource=CTestResource::Lookup(m_strExecutionHostPort); + if(pExecutionResource){ + nBaud=pExecutionResource->Baud(); + } } - TRACE(_T("Timeout=%d\n"),m_ep.DownloadTimeout()); - } - if(NOTIMEOUT==m_ep.ActiveTimeout()){ - m_ep.SetActiveTimeout(1000*(_TCHAR('\0')==*(m_pPort->Serial())?300:30)); + if(0==nBaud){ + nBaud=38400; + } + + int nBytesPerSec=(nBaud/10)/2; // division by 2 assumes download in "ascii" (2 bytes/char) + m_ep.SetDownloadTimeout (1000*MAX(30,2*(m_nStrippedSize/nBytesPerSec))); + TRACE(_T("Estimated download time %d sec (%d bytes @ %d bytes/sec [%d baud])\n"),m_nStrippedSize/nBytesPerSec,m_nStrippedSize,nBytesPerSec,nBaud); } - { - // Construct commands for gdb - const TargetInfo &t=Target(Target()); - TargetInfo::HwType hwt=t.Type(); - StringArray arstrGdbCmds; - LPCTSTR pszPrompt; - String strGdb; - // running using gdb - pszPrompt=_T("(gdb) "); - strGdb.Format(_T("%s-gdb -nw %s"),t.Prefix(),(LPCTSTR)CygPath(m_strExecutable)); - // Tell gdb its paper size :-) - arstrGdbCmds.push_back(_T("set height 0")); - arstrGdbCmds.push_back(_T("set remotedebug 0")); - - if(_TCHAR('\0')!=*t.GdbCmd()){ - arstrGdbCmds.push_back(t.GdbCmd()); - } - - String str; - if(_TCHAR('\0')!=*(m_pPort->Serial())){ - // Talking remotely - if(CeCosTestSocket::IsLegalHostPort(m_pPort->Serial())){ - // Talking to a tcp/ip socket - arstrGdbCmds.push_back(_T("set watchdog 0")); - } else { - // Talking to a serial port - str.Format(_T("set remotebaud %d"),m_pPort->Baud()); - arstrGdbCmds.push_back(str); - } - str.Format(_T("target remote %s"),m_pPort->Serial()); -#ifdef _WIN32 - // Serial names on windows must be in l.c. (gdb bug) - for(TCHAR *c=str.GetBuffer();*c;c++){ - if(isalpha(*c)){ - *c=(TCHAR)_totlower(*c); - } - } - str.ReleaseBuffer(); -#endif - arstrGdbCmds.push_back(str); - } - - if(TargetInfo::SYNTHETIC!=hwt){ - arstrGdbCmds.push_back(_T("load")); - } - - arstrGdbCmds.push_back(_T("break cyg_test_exit")); - arstrGdbCmds.push_back(_T("break cyg_assert_fail")); - if(/*start hack*/BreakpointsOperational()/*end hack*/){ - arstrGdbCmds.push_back(_T("break cyg_test_init")); - } - - switch(hwt){ - case TargetInfo::SYNTHETIC: - case TargetInfo::SIM: - arstrGdbCmds.push_back(_T("run")); - break; - case TargetInfo::HARDWARE: - case TargetInfo::HARDWARE_NO_BP: - case TargetInfo::REMOTE_SIM: - arstrGdbCmds.push_back(_T("cont")); // run the program - break; - default: - assert(false); - } - - if(BreakpointsOperational()){ - str.Format(_T("set cyg_test_is_simulator=%d"),hwt); - arstrGdbCmds.push_back(str); - arstrGdbCmds.push_back(_T("cont")); // continue from cyg_test_init breakpoint - } - - // run/cont command must be the last (logic in DriveGdb) - - TRACE(_T("Calling RunGdb\n")); - RunGdb(strGdb,pszPrompt,arstrGdbCmds); - rc=true; - } + TRACE(_T("Active timeout=%d download timeout=%d\n"),m_ep.ActiveTimeout(), m_ep.DownloadTimeout()); + + GetInferiorCommands(m_arstrInferiorCmds); + String strInferior(m_ep.Platform()->Inferior()); + strInferior.Replace(_T("%e"),CygPath(m_strExecutable),true); + RunInferior(strInferior); + rc=true; } } - TRACE(_T("LocalThreadFunc - releasing resource\n")); - if(m_pPort){ - m_pPort->Release(); - m_pPort=0; + if(m_pResource){ + m_pResource->Release(); + m_pResource=0; } - TRACE(_T("LocalThreadFunc - exiting\n")); + TRACE(_T("RunLocal - exiting\n")); } return rc; @@ -591,11 +314,11 @@ void CeCosTest::Cancel () SetStatus(Cancelled); } -CeCosTest::ServerStatus CeCosTest::Connect (String strHost,int port, CeCosTestSocket *&pSock, const ExecutionParameters &e,String &strInfo,Duration dTimeout) +CeCosTest::ServerStatus CeCosTest::Connect (LPCTSTR pszHostPort, CeCosSocket *&pSock, const ExecutionParameters &e,String &strInfo,Duration dTimeout) { // Find out whether this host is receptive ServerStatus s=CONNECTION_FAILED; - pSock=new CeCosTestSocket(strHost,port,dTimeout); + pSock=new CeCosSocket(pszHostPort,dTimeout); int nStatus; if(pSock->Ok() && pSock->sendString(e.Image(), _T("execution parameters")) && @@ -617,7 +340,7 @@ CeCosTest::ServerStatus CeCosTest::Conne void CeCosTest::ConnectForExecution () { - bool bSchedule=(0==m_strExecutionHostPort.GetLength()); + bool bSchedule=(0==m_strExecutionHostPort.size()); Duration nDelay=2000; m_pSock=0; @@ -637,7 +360,7 @@ void CeCosTest::ConnectForExecution () if(nChoices>0){ TRACE(_T("ConnectForExecution: choices are:\n")); for(int i=0;iOutput(),(LPCTSTR )strInfo,Image(s)); + str.Format(_T("%s %s %s"),(LPCTSTR)pResource->Image(),(LPCTSTR)strInfo,(LPCTSTR)Image(s)); arstrTries.push_back(str); } if(SERVER_READY==s){ // So that's ok then. We're outta here. - Interactive(_T("Connected to %s\n"),(LPCTSTR )m_strExecutionHostPort); + INTERACTIVE(_T("Connected to %s\n"),(LPCTSTR)m_strExecutionHostPort); goto Done; } else { delete m_pSock; @@ -696,23 +415,23 @@ SERVER_LOCKED: } } - Interactive(_T("Warning - could not connect to any test servers:\n")); + INTERACTIVE(_T("Warning - could not connect to any test servers:\n")); if(arstrTries.size()>0){ for(unsigned int i=0;iNext()){ - Interactive(_T(" %s\n"),(LPCTSTR )pResource->Output()); + INTERACTIVE(_T(" %s\n"),(LPCTSTR)pResource->Image()); } LEAVECRITICAL; } - Interactive(_T("Retry in %d seconds...\n"),nDelay/1000); + INTERACTIVE(_T("Retry in %d seconds...\n"),nDelay/1000); // We have tried all possibilities - sleep before retrying - Sleep(nDelay); + CeCosThreadUtils::Sleep(nDelay); if(Cancelled==m_Status){ TRACE(_T("ConnectForExecution : cancelled\n")); @@ -726,18 +445,11 @@ Done: delete [] arbHostTried; } -void CeCosTest::LogResult() -{ - CeCosTrace::Out(ResultString()); - CeCosTrace::Out(_T("\n") ); - CeCosTrace::Trace(_T("%s\n"),ResultString()); -} - void CeCosTest::SetStatus (StatusType status) { ENTERCRITICAL; if((int)status>(int)m_Status){ - TRACE(_T("Status <- %s\n"),Image(status)); + TRACE(_T("Status <- %s\n"),(LPCTSTR)Image(status)); m_Status=status; } LEAVECRITICAL; @@ -747,7 +459,7 @@ bool CeCosTest::WaitForAllInstances(int { Time t0=Now(); while(InstanceCount>0){ - Sleep(nPoll); + CeCosThreadUtils::Sleep(nPoll); if(NOTIMEOUT!=nTimeout && Now()-t0>nTimeout){ return false; } @@ -816,7 +528,7 @@ bool CeCosTest::Value ( int nDownloadTimeoutFrac=0; static String strFormat; - if(0==strFormat.GetLength()){ + if(0==strFormat.size()){ // Construct a version of the format string sans length attributes for %s items LPCTSTR c=pszFormat; TCHAR *d=strFormat.GetBuffer(_tcslen(pszFormat)); @@ -882,19 +594,20 @@ bool CeCosTest::Value ( ; } -LPCTSTR const CeCosTest::ResultString(bool bIncludeOutput) const +const String CeCosTest::ResultString(bool bIncludeOutput) const { + String strResultString; String strTitle(m_strTitle); String strExecutionHostPort(m_strExecutionHostPort); - if(0==strTitle.GetLength()){ - strTitle=CeCosTestUtils::SimpleHostName(); + if(0==strTitle.size()){ + strTitle=CeCosSocket::MySimpleHostName(); strTitle+=_TCHAR(':'); strTitle+=m_strExecutable; } - if(0==strExecutionHostPort.GetLength()){ - strExecutionHostPort=CeCosTestUtils::SimpleHostName(); + if(0==strExecutionHostPort.size()){ + strExecutionHostPort=CeCosSocket::MySimpleHostName(); strExecutionHostPort+=_T(":0"); } @@ -903,25 +616,25 @@ LPCTSTR const CeCosTest::ResultString(b time(<ime); struct tm *now=localtime( <ime ); - m_strResultString.Format( + strResultString.Format( pszFormat, 1900+now->tm_year,1+now->tm_mon,now->tm_mday, now->tm_hour,now->tm_min,now->tm_sec, // Time of day - (LPCTSTR )strExecutionHostPort, // Execution host:port - Target(), // Target - ExecutableTail(), // Executable - Image(Status()), // Result - m_nStrippedSize/1024,m_nFileSize/1024, // Sizes - WF(m_nDownloadTime),WF(DownloadTimeout()),WF(m_nTotalTime),// Times - WF(m_nMaxInactiveTime),WF(ActiveTimeout()), - (LPCTSTR )strTitle // Title + (LPCTSTR)strExecutionHostPort, // Execution host:port + (LPCTSTR)m_ep.PlatformName(), // Target + (LPCTSTR)CeCosTestUtils::Tail(m_strExecutable), // Executable + (LPCTSTR)Image(Status()), // Result + m_nStrippedSize/1024,m_nFileSize/1024, // Sizes + WF(m_nDownloadTime),WF(m_ep.DownloadTimeout()),WF(m_nTotalTime),// Times + WF(m_nMaxInactiveTime),WF(m_ep.ActiveTimeout()), + (LPCTSTR)strTitle // Title ); - if(bIncludeOutput && m_strOutput.GetLength()>0){ - m_strResultString+=_TCHAR('\n'); - m_strResultString+=m_strOutput; + if(bIncludeOutput && m_strOutput.size()>0){ + strResultString+=_TCHAR('\n'); + strResultString+=m_strOutput; } LEAVECRITICAL; - return m_strResultString; + return strResultString; } // Run as a server, listening on the port given as parameter @@ -929,168 +642,154 @@ bool CeCosTest::RunAgent(int nTcpPort) { bool bLocked=false; - nAuxPort=nTcpPort+3000;//hack - nAuxListenSock=CeCosTestSocket::Listen(nAuxPort);//hack - if(-1!=nAuxListenSock){ - // Create socket - int nSock = CeCosTestSocket::Listen(nTcpPort); - int nLastClient=0; - int nRejectionCount=0; - if (-1!=nSock) { - for (;;) { - try { - CeCosTestSocket *pSock=new CeCosTestSocket(nSock); // AcceptThreadFunc deletes if not deleted below - String str; - // Read the execution parameters - if(!pSock->recvString(str)){ - // Socket error on the recv - nothing much we can do - TRACE(_T("RunAgent : could not read execution parameters\n")); - delete pSock; - pSock=0; - } else { - ExecutionParameters e; - e.FromStr(str); - TRACE(_T("Execution parameters: %s\n"),(LPCTSTR)e.Image()); - bool bNuisance=false; - ServerStatus s; - CTestResource *pPort=0; - String strInfo; - if(!e.IsValid()){ - // Looks like a confused client ... - strInfo.Format(_T("Bad target value %s read from client\n"),e.Target()); - s=SERVER_CANT_RUN; - } else if(0==CTestResource::Count(e)){ - // No chance of running this test - strInfo.Format(_T("Cannot run a %s test from this server\n"),e.Target()); - s=SERVER_CANT_RUN; - } else { - switch(e.Request()) { - case ExecutionParameters::LOCK: - if(bLocked){ - s=SERVER_BUSY; - } else { - WaitForAllInstances(1000,NOTIMEOUT); - bLocked=true; - s=SERVER_LOCKED; - } - break; - case ExecutionParameters::UNLOCK: - if(bLocked){ - bLocked=false; - s=SERVER_READY; - } else { - s=SERVER_BUSY; - } - break; - case ExecutionParameters::QUERY: - if (bLocked) { - s=SERVER_LOCKED; - } else { - pPort=CTestResource::GetResource(e); - if(0==pPort){ - s=SERVER_BUSY; - strInfo.Format(_T("serving %s"),(LPCTSTR )CeCosTestSocket::ClientName(nLastClient)); - } else { + // Create socket + int nSock = CeCosSocket::Listen(nTcpPort); + int nLastClient=0; + if (-1!=nSock) { + for (;;) { + try { + CeCosSocket *pSock=new CeCosSocket(nSock); // AcceptThreadFunc deletes if not deleted below + String str; + // Read the execution parameters + if(!pSock->recvString(str)){ + // Socket error on the recv - nothing much we can do + TRACE(_T("RunAgent : could not read execution parameters\n")); + delete pSock; + pSock=0; + } else { + ExecutionParameters e; + e.FromStr(str); + TRACE(_T("Execution parameters: %s\n"),(LPCTSTR)e.Image()); + ServerStatus s; + CTestResource *pPort=0; + String strInfo; + + switch(e.Request()) { + case ExecutionParameters::LOCK: + if(bLocked){ + s=SERVER_BUSY; + } else { + WaitForAllInstances(1000,NOTIMEOUT); + bLocked=true; + s=SERVER_LOCKED; + } + break; + case ExecutionParameters::UNLOCK: + if(bLocked){ + bLocked=false; + s=SERVER_READY; + } else { + s=SERVER_BUSY; + } + break; + case ExecutionParameters::QUERY: + if (bLocked) { + s=SERVER_LOCKED; + } else { + s=SERVER_BUSY; + ENTERCRITICAL; + for(CTestResource *pResource=CTestResource::First();pResource;pResource=pResource->Next()){ + if(!pResource->InUse()){ s=SERVER_READY; - pPort->Release(); - pPort=0; + break; } } - break; - case ExecutionParameters::RUN: - if (bLocked) { - s=SERVER_LOCKED; + LEAVECRITICAL; + if(SERVER_READY!=s){ + strInfo.Format(_T("serving %s"),(LPCTSTR)CeCosSocket::ClientName(nLastClient)); + } + } + break; + case ExecutionParameters::RUN: + if(NULL==e.Platform()){ + // Looks like a confused client ... + strInfo.Format(_T("Bad target value %s read from client\n"),(LPCTSTR)str); + s=SERVER_CANT_RUN; + } else if(0==CTestResource::Count(e)){ + // No chance of running this test + strInfo.Format(_T("Cannot run a %s test from this server\n"),(LPCTSTR)e.PlatformName()); + s=SERVER_CANT_RUN; + } else if (bLocked) { + s=SERVER_LOCKED; + } else { + pPort=CTestResource::GetResource(e); + if(0==pPort){ + // We must disappoint our client + strInfo.Format(_T("serving %s"),(LPCTSTR)CeCosSocket::ClientName(nLastClient)); + s=SERVER_BUSY; } else { - pPort=CTestResource::GetResource(e); - if(0==pPort){ - // We must disappoint our client - nRejectionCount++; - strInfo.Format(_T("serving %s"),(LPCTSTR )CeCosTestSocket::ClientName(nLastClient)); - s=SERVER_BUSY; - /* - } else if(nLastClient==pSock->Client() && nRejectionCount>10) { - // Don't answer the phone to a nuisance caller - s=SERVER_BUSY; - bNuisance=true; - nRejectionCount--; - pPort->Release(); - pPort=0; - */ - } else { - s=SERVER_READY; - nRejectionCount=0; - nLastClient=pSock->Client(); - } + s=SERVER_READY; + nLastClient=pSock->Client(); } - break; - case ExecutionParameters::STOP: - s=SERVER_READY; - break; - default: - s=SERVER_CANT_RUN; } + break; + case ExecutionParameters::STOP: + s=SERVER_READY; + break; + default: + s=SERVER_CANT_RUN; + } + +#ifndef VERBOSE + if(ExecutionParameters::QUERY!=e.Request()) +#endif + TRACE(_T("RunAgent : %s request tActive=%d tDownload=%d Target=%s Reply status=%s %s\n"), + (LPCTSTR)e.Image(e.Request()),e.ActiveTimeout(),e.DownloadTimeout(), + (LPCTSTR)e.PlatformName(), + (LPCTSTR)Image(s),(LPCTSTR)strInfo); + + bool bSendok=pSock->sendInteger(s) && pSock->sendString(strInfo); + + if(SERVER_READY==s && bSendok && ExecutionParameters::RUN==e.Request()){ + + // Create a new class instance + // AcceptThreadFunc deletes the instance and closes new_sock + // RunLocal, called by AcceptThreadFunc, releases the port + // No need for meaningful callback, but must run asynchronously + + int nAuxPort=30000; + int nAuxListenSock=-1; + + do { + nAuxListenSock=CeCosSocket::Listen(nAuxPort); + } while (-1==nAuxListenSock && nAuxPort++<=0xffff); + + if(-1==nAuxListenSock){ + ERROR(_T("Couldn't find a socket to bind to for RDI\n")); + } else { + + CeCosTest *pTest=new CeCosTest(e,NULL); + pTest->m_nAuxPort=nAuxPort; + pTest->m_nAuxListenSock=nAuxListenSock; + pTest->m_pSock=pSock; + pTest->m_strExecutionHostPort=CeCosSocket::HostPort(CeCosSocket::MyHostName(),nTcpPort); + pTest->m_pResource=pPort; + CeCosThreadUtils::RunThread(SAcceptThreadFunc,pTest,_T("SAcceptThreadFunc")); + // AcceptThreadFunc deletes pSock } -#ifndef VERBOSE - if(ExecutionParameters::QUERY!=e.Request()) -#endif - TRACE(_T("RunAgent : %s request tActive=%d tElapsed=%d Target=%s Reply status=%s %s Nuisance=%d\n"), - e.Image(e.Request()), - e.ActiveTimeout(),e.DownloadTimeout(),e.Target(), - Image(s), - (LPCTSTR )strInfo, - bNuisance); - - bool bSendok=pSock->sendInteger(s) && pSock->sendString(strInfo); - - TRACE(_T("RunAgent(1)\n")); - - if(SERVER_READY==s && bSendok && ExecutionParameters::RUN==e.Request()){ - - // Create a new class instance - // AcceptThreadFunc deletes the instance and closes new_sock - // RunLocal, called by AcceptThreadFunc, releases the port - // We dream up a temporary name for the executable - // No need for meaningful callback, but must run asynchronously - String strTempFile; - ENTERCRITICAL; - strTempFile.Format(_T("%s-%s-%d"),_ttmpnam(0),e.Target(),nTcpPort); - LEAVECRITICAL; - - CeCosTest *pTest=new CeCosTest(e,strTempFile); - pTest->m_pSock=pSock; - pTest->m_strExecutionHostPort.Format(_T("%s:%d"),CeCosTestUtils::HostName(),nTcpPort); - pTest->m_pPort=pPort; - - CeCosThreadUtils::RunThread(SAcceptThreadFunc,pTest,_T("SAcceptThreadFunc")); - // AcceptThreadFunc deletes pSock - - } else { - TRACE(_T("RunAgent(2)\n")); - delete pSock; - pSock=0; - if(pPort){ - pPort->Release(); - pPort=0; - } - TRACE(_T("RunAgent(3)\n")); - if(CeCosTest::ExecutionParameters::STOP==e.Request()){ - CancelAllInstances(); - WaitForAllInstances(1000,20*1000); - break; - } + } else { + delete pSock; + pSock=0; + if(pPort){ + pPort->Release(); + pPort=0; } - } + if(CeCosTest::ExecutionParameters::STOP==e.Request()){ + CancelAllInstances(); + WaitForAllInstances(1000,20*1000); + break; } - catch(...){ - TRACE(_T("!!! Exception caught in RunAgent()\n")); - } + } } - CeCosTestSocket::CloseSocket (nSock); + } + catch(...){ + TRACE(_T("!!! Exception caught in RunAgent()\n")); + } } - VTRACE(_T("RunAgent(): returning false\n")); - CeCosTestSocket::CloseSocket(nAuxListenSock); + CeCosSocket::CloseSocket (nSock); } + return false; } @@ -1108,61 +807,55 @@ CeCosTest::StatusType CeCosTest::StatusT // Thread to run ConnectSocketToSerial void CeCosTest::ConnectSocketToSerialThreadFunc() { - TRACE(_T("ConnectSocketToSerialThreadFunc sock=%d\n"),nAuxListenSock); - { - - CeCosTestSerialFilter serial_filter; - CeCosTestSocket::FilterFunc *serial_filter_function = - &SerialFilterFunction; - - CeCosTestDownloadFilter download_filter; - CeCosTestSocket::FilterFunc *download_filter_function = - &DownloadFilterFunction; - - bool accept_connection = true; + TRACE(_T("ConnectSocketToSerialThreadFunc sock=%d\n"),m_nAuxListenSock); - CeCosTestSerial serial; - serial.SetBlockingReads(false); - bool rc=false; - // Open serial device. - if (!serial.Open(m_pPort->Serial(),m_pPort->Baud())){ - ERROR(_T("Couldn't open port %s\n"),m_pPort->Serial()); - } else { - while(accept_connection) { - // Flush the serial buffer. - serial.Flush(); - TRACE(_T("ConnectSocketToSerial: waiting for connection...\n")); - CeCosTestSocket socket; - if(!socket.Accept(nAuxListenSock,&m_bStopConnectSocketToSerial)){ - ERROR(_T("ConnectSocketToSerial - couldn't accept\n")); - break; - } else if (m_pSock->Client() != socket.Client()){ - // Make sure the client is who we think it is... - TRACE(_T("ConnectSocketToSerialThread - illegal connection attempted from %s\n"),(LPCTSTR )socket.ClientName(socket.Client())); - } else { - try { - rc=CeCosTestSocket::ConnectSocketToSerial(socket,serial,m_ep.m_bUseFilter?serial_filter_function:NULL, (void*)&serial_filter, m_ep.m_bUseFilter?download_filter_function:NULL, (void*)&download_filter, &m_bStopConnectSocketToSerial); - - // If the download filter was just active, it may - // allow the session to continue. - accept_connection = download_filter.ContinueSession(); - - } - catch (LPCTSTR pszMsg){ - Log(_T("!!! ConnectSocketToSerial exception caught: %s!!!\n"),pszMsg); - rc=false; + CeCosTestSerialFilter serial_filter; + CeCosTestDownloadFilter download_filter; + + CeCosSerial serial; + serial.SetBlockingReads(false); + bool rc=false; + // Open serial device. + if (!serial.Open(m_pResource->Serial(),m_pResource->Baud())){ + ERROR(_T("Couldn't open port %s\n"),m_pResource->Serial()); + } else { + for(;;){ + // Flush the serial buffer. + serial.Flush(); + TRACE(_T("ConnectSocketToSerial: waiting for connection...\n")); + CeCosSocket socket; + if(!socket.Accept(m_nAuxListenSock,&m_bStopConnectSocketToSerial)){ + ERROR(_T("ConnectSocketToSerial - couldn't accept: %s\n"),(LPCTSTR)socket.SocketErrString()); + break; + } else if (m_pSock->Client() != socket.Client()){ + // Make sure the client is who we think it is... + TRACE(_T("ConnectSocketToSerialThread - illegal connection attempted from %s\n"),(LPCTSTR)socket.ClientName(socket.Client())); + } else { + try { + rc=CeCosSocket::ConnectSocketToSerial(socket,serial,m_ep.m_bUseFilter?SerialFilterFunction:NULL, (void*)&serial_filter, m_ep.m_bUseFilter?DownloadFilterFunction:NULL, (void*)&download_filter, &m_bStopConnectSocketToSerial); + + // If the download filter was just active, it may + // allow the session to continue. + if(!download_filter.ContinueSession()){ break; } - catch (...){ - Log(_T("!!! ConnectSocketToSerial exception caught!!!\n")); - rc=false; - break; - } + + } + catch (LPCTSTR pszMsg){ + Log(_T("!!! ConnectSocketToSerial exception caught: %s!!!\n"),pszMsg); + rc=false; + break; + } + catch (...){ + Log(_T("!!! ConnectSocketToSerial exception caught!!!\n")); + rc=false; + break; } } } - TRACE(_T("ConnectSocketToSerial : done\n")); } + TRACE(_T("ConnectSocketToSerial : done\n")); + CeCosSocket::CloseSocket(m_nAuxListenSock); } static bool CALLBACK DerefBool(void *pParam) @@ -1171,11 +864,15 @@ static bool CALLBACK DerefBool(void *pPa } // Function called (on a separate thread) to process a successful connection to the RunAgent loop +// In the case of a simulator server, we can have many of these active at the same time. void CeCosTest::AcceptThreadFunc() { - SetPath(m_strPath); - - if(ServerSideGdb()){ + if(m_ep.Platform()->ServerSideGdb()){ + // We dream up a temporary name for the executable + ENTERCRITICAL; + m_strExecutable.Format(_T("%s-%s-%d"),_ttmpnam(0),(LPCTSTR)m_ep.PlatformName(),m_nAuxPort); + LEAVECRITICAL; + int n; if(m_pSock->recvInteger(n,_T("file size"))){ m_nFileSize=n; @@ -1185,7 +882,7 @@ void CeCosTest::AcceptThreadFunc() FILE *f2; f2=_tfopen(m_strExecutable,_T("wb")); if(0==f2){ - Log(_T("Could not create %s - %s\n"),(LPCTSTR )m_strExecutable,strerror(errno)); + Log(_T("Could not create %s - %s\n"),(LPCTSTR)m_strExecutable,strerror(errno)); bCanRun=false; } unsigned int nBufSize=MIN(100000,m_nFileSize); @@ -1203,7 +900,7 @@ void CeCosTest::AcceptThreadFunc() while(nToRead>0){ int w=fwrite(c,1,nToRead,f2); if(-1==w){ - Log(_T("Write error on %s - %s\n"),(LPCTSTR )m_strExecutable,strerror(errno)); + Log(_T("Write error on %s - %s\n"),(LPCTSTR)m_strExecutable,strerror(errno)); bCanRun=false; break; } @@ -1217,9 +914,9 @@ void CeCosTest::AcceptThreadFunc() if(0!=f2){ fclose(f2); _tchmod(m_strExecutable,00700); // user read, write and execute - } + } if(0!=f2 && m_nFileSize!=nWritten){ - Log(_T("Failed to create %s correctly [%d/%d bytes written]\n"),(LPCTSTR )m_strExecutable, nWritten, m_nFileSize); + Log(_T("Failed to create %s correctly [%d/%d bytes written]\n"),(LPCTSTR)m_strExecutable, nWritten, m_nFileSize); bCanRun=false; } SetExecutable(m_strExecutable); // to set stripped length and title @@ -1230,29 +927,29 @@ void CeCosTest::AcceptThreadFunc() m_pSock->recvInteger(n); // receive an ack } else { bool bTargetReady; - if(_TCHAR('\0')==*(m_pPort->ResetString())){ + if(_TCHAR('\0')==*(m_pResource->ResetString())){ bTargetReady=true; TRACE(_T("No reset possible\n")); } else { - Log(_T("Resetting target using %s"),(LPCTSTR)m_pPort->ResetString()); - bTargetReady=(CResetAttributes::RESET_OK==Reset(true)); + Log(_T("Resetting target using %s"),(LPCTSTR)m_pResource->ResetString()); + bTargetReady=(CResetAttributes::RESET_OK==m_pResource->Reset(ResetLogFunc,this)); } TRACE(_T("Send Target Ready indicator=%d\n"),bTargetReady); m_pSock->sendInteger(bTargetReady,_T("target ready indicator")); - int nAck; + int nAck=-1; int dTimeout=m_ep.DownloadTimeout()+MAX(3*m_ep.ActiveTimeout(),15*60*1000); if(bTargetReady){ - if(CeCosTestSocket::IsLegalHostPort(m_pPort->Serial())){ - TRACE(_T("Sending %s\n"),(LPCTSTR )m_pPort->Serial()); - m_pSock->sendString(m_pPort->Serial(),_T("Serial name")); - m_pSock->recvInteger(nAck,_T("Terminating ack"),dTimeout); - TRACE(_T("Terminating ack=%d\n"),nAck); + if(CeCosSocket::IsLegalHostPort(m_pResource->Serial())){ + TRACE(_T("Sending %s\n"),(LPCTSTR)m_pResource->Serial()); + if(m_pSock->sendString(m_pResource->Serial(),_T("Serial name")) && m_pSock->recvInteger(nAck,_T("Terminating ack"),dTimeout)){ + TRACE(_T("Terminating ack=%d\n"),nAck); + } } else { - String strHostPort(CeCosTestSocket::HostPort(CeCosTestUtils::HostName(),nAuxPort)); + String strHostPort(CeCosSocket::HostPort(CeCosSocket::MyHostName(),m_nAuxPort)); - TRACE(_T("Using %s\n"),(LPCTSTR )strHostPort); + TRACE(_T("Using %s\n"),(LPCTSTR)strHostPort); if(m_pSock->sendString(strHostPort,_T("host:port"))){ @@ -1266,16 +963,17 @@ void CeCosTest::AcceptThreadFunc() CeCosThreadUtils::RunThread(SConnectSocketToSerialThreadFunc,this,&bConnectSocketToSerialThreadDone,_T("SConnectSocketToSerialThreadFunc")); // Wait for either client or the ConnectSocketToSerial thread to finish. - m_pSock->recv(&nAck,1,_T("Terminating ack"),dTimeout,DerefBool,&bConnectSocketToSerialThreadDone); - TRACE(_T("Terminating ack=%d\n"),nAck); + if(m_pSock->recv(&nAck,sizeof(int),_T("Terminating ack"),dTimeout,DerefBool,&bConnectSocketToSerialThreadDone)){ + TRACE(_T("Session terminated by request of client (%s)\n"),(LPCTSTR)Image((StatusType)nAck)); + } else if(0!=m_pSock->SocketError()){ + TRACE(_T("Session terminated by socket error - %s\n"),(LPCTSTR)m_pSock->SocketErrString()); + } if(!bConnectSocketToSerialThreadDone){ // Tap ConnectSocketToSerial thread on the shoulder TRACE(_T("Waiting for ConnectSocketToSerial thread to terminate...\n")); m_bStopConnectSocketToSerial=true; CeCosThreadUtils::WaitFor(bConnectSocketToSerialThreadDone); } - TRACE(_T("ConnectSocketToSerial thread terminated...\n")); - } } } @@ -1343,192 +1041,58 @@ bool CeCosTest::recvResult(Duration dTim return rc; } -#ifndef _WIN32 -// This function may be run as a thread (win32) or called (unix). -// It runs gdb. -void CeCosTest::DriveGdb(LPCTSTR pszPrompt,const StringArray &arstrGdbCmds) +// Return time used by inferior gdb process - CPU for sim, wallclock otherwise +Time CeCosTest::InferiorTime() const { - unsigned int nCmdIndex=0; - - SetStatus(NotStarted); - - m_nMaxInactiveTime=0; - m_nTotalTime=0; - m_nDownloadTime=0; - - m_bDownloading=true; - - m_tBase=GdbTime(); - m_tBase0=GdbTime(); - m_tWallClock0=Now(); - - TRACE(_T("DriveGdb()\n")); - - int nLastGdbInst=0; - - // Loop until 1 of: - // 1. Timeout detected - // 2. Gdb process is dead - // 3. At a gdb prompt and no more commands to send to gdb - // 4. Pipe read failure - // 5. Pipe write failure - do { - String str; - int readrc=ReadPipe(str,/*bBlockingReads=*/false); - switch(readrc){ - case 0: - Sleep(250); // only unix will execute this - break; - case -1: - goto Done; // case 4 - break; - default: - LogTimeStampedOutput(str); - - if(m_strOutput.GetLength()>20000){ - LogString(_T("\n>>>> Infra FAIL\n*** too much output ***\n>>>>\n")); - SetStatus(Fail); - goto Done; - } - - // Test for program loaded and started: - // (remember SetStatus cannot downgrade the status if already > NoResult) - if(OutputContains(_T("Starting program: /")) || (OutputContains(_T("Start address"))&&OutputContains(_T("Continuing.")))){ - SetStatus(NoResult); - } - - m_tBase=GdbTime(); - // // If can only hit a single breakpoint don't expect cyg_test_exit to stop us: - // if(!BreakpointsOperational() && (OutputContains(_T("EXIT:"))||OutputContains(_T("NOTAPPLICABLE:")))){ - // goto Done; - // } - - if(AtPrompt(pszPrompt)){ - m_tBase=GdbTime(); - TRACE(_T("DriveGdb(1)\n")); - // gdb's output included one or more prompts - // Send another command along - if(nCmdIndex>=arstrGdbCmds.size()){ - // Nothing further to say to gdb - exit - TRACE(_T("DriveGdb(2)\n")); - goto Done; // case 3 - } else { - String strCmd(arstrGdbCmds[nCmdIndex++]); - TRACE(_T("DriveGdb(2a) - strCmd='%s' nLastGdbInst=%d\n"),(LPCTSTR)strCmd,nLastGdbInst); - // If at a prompt and we can see a GDB instruction, send it down - LPCTSTR pszGdbcmd=_tcsstr(nLastGdbInst+(LPCTSTR)m_strOutput,_T("GDB:")); - if(pszGdbcmd){ - TRACE(_T("DriveGdb(2b)\n")); - pszGdbcmd+=4; - TCHAR cTerm; - if(_TCHAR('<')==*pszGdbcmd){ - cTerm=_TCHAR('>'); - pszGdbcmd++; - } else { - cTerm=_TCHAR('\n'); - } - TRACE(_T("DriveGdb(2c)\n")); - LPCTSTR c=_tcschr(pszGdbcmd,cTerm); - if(c){ - TRACE(_T("DriveGdb(2d)\n")); - strCmd=String(pszGdbcmd,c-pszGdbcmd); - nLastGdbInst=c+1-(LPCTSTR)m_strOutput; - nCmdIndex--; // undo increment above - } - } - strCmd+=_TCHAR('\n'); - LogString(strCmd); - TRACE(_T("DriveGdb(3)\n")); - if(!WritePipe(strCmd)){ - TRACE(_T("Writepipe returned error\n")); - goto Done; // case 5 - } - TRACE(_T("DriveGdb(4)\n")); - if(0==_tcscmp(strCmd,_T("run\n"))||0==_tcscmp(strCmd,_T("cont\n"))){ - m_tBase=GdbTime(); - m_bDownloading=false; - } - TRACE(_T("DriveGdb(5)\n")); - } - } - break; - } - - } while (GdbProcessAlive() && CheckForTimeout()); // cases 2 and 1 - -Done: - - TRACE(_T("DriveGdb() - done\n")); - - Suck(pszPrompt); - if(GdbProcessAlive() && AtPrompt(pszPrompt)){ - LogString(_T("bt\n")); - WritePipe(_T("bt\n")); - Suck(pszPrompt); - LogString(_T("quit\n")); - WritePipe(_T("quit\n")); + if(*(m_pResource->Serial())){ + return Now(); + } + if(!m_psp){ + return 0; } - - // Read anything gdb has to say [within limits] - Suck(pszPrompt); - AnalyzeOutput(); - - m_nTotalTime=Now()-m_tWallClock0; - TRACE(_T("Exiting DriveGdb()\n")); - -} -#endif - -// Return time used by inferior gdb process - CPU for sim, wallclock otherwise -Time CeCosTest::GdbTime() -{ - return _TCHAR('\0')==*(m_pPort->Serial())?GdbCpuTime():Now(); + Time now=Now(); + if(now-m_tPrevSample>1000){ + m_tPrevSample=now; + m_tInferiorCpuTime=m_psp->CpuTime(); + } + return m_tInferiorCpuTime; } bool CeCosTest::CheckForTimeout() { - bool rc=false; + bool rc=(Cancelled!=Status()); if(TimeOut!=m_Status && DownloadTimeOut!=m_Status){ - Duration &dTime=m_bDownloading?m_nDownloadTime:m_nMaxInactiveTime; - Time t=GdbTime(); + Time t=InferiorTime(); if(t){ - dTime=MAX(dTime,Duration(GdbTime()-m_tBase)); + // We have been able to measure the time + if(m_bDownloading){ + m_nDownloadTime=MAX(m_nDownloadTime,Duration(InferiorTime()-m_tBase)); + if(m_nDownloadTime>m_ep.DownloadTimeout()){ + Log(_T("\n*** Timeout - download time ") WFS _T(" exceeds limit of ") WFS _T("\n"),WF(m_nDownloadTime),WF(m_ep.DownloadTimeout())); + rc=false; + } + } else { + m_nMaxInactiveTime=MAX(m_nMaxInactiveTime,Duration(InferiorTime()-m_tBase)); + if (m_nMaxInactiveTime>m_ep.ActiveTimeout()) { + Log(_T("\n*** Timeout - inactive time ") WFS _T(" exceeds limit of ") WFS _T("\n"),WF(m_nMaxInactiveTime),WF(m_ep.ActiveTimeout())); + rc=false; + } + } } - Duration dTimeout=m_bDownloading?DownloadTimeout():ActiveTimeout(); - if(dTimeout!=NOTIMEOUT && dTime>dTimeout) { - Log(_T("\n*** Timeout - %s time ") WFS _T(" exceeds limit of ") WFS _T("\n"), - m_bDownloading?_T("download"):_T("MAX inactive"),WF(dTime),WF(dTimeout)); + m_nTotalTime=Duration(Now()-m_tWallClock0); +/* + if(m_nTotalTime>m_ep.ElapsedTimeout()){ + Log(_T("\n*** Timeout - total time ") WFS _T(" exceeds limit of ") WFS _T("\n"), WF(m_nTotalTime),WF(m_ep.ElapsedTimeout())); + rc=false; + } +*/ + if(!rc){ SetStatus(m_bDownloading?DownloadTimeOut:TimeOut); - } else if(Now()-m_tWallClock0>MAX(3*dTimeout,15*60*1000)){ - Log(_T("\n*** Timeout - total time ") WFS _T(" exceeds limit of ") WFS _T("\n"), - WF(Now()-m_tWallClock0),WF(MAX(3*dTimeout,15*60*1000))); - SetStatus(m_bDownloading?DownloadTimeOut:TimeOut); - } else { - rc=true; } } return rc; } -void CeCosTest::Interactive(LPCTSTR pszFormat, ...) -{ - va_list marker; - va_start (marker, pszFormat); - String str; - str.vFormat(pszFormat,marker); - va_end (marker); - - if(CeCosTrace::IsInteractive()){ - CeCosTrace::Out(str); - } else { - CeCosTrace::Trace(_T("%s"),(LPCTSTR)str); - } -} - -LPCTSTR const CeCosTest::Title() const { - return m_strTitle; -} - // Convert a path to something a cygwin tool will understand. Used when invoking -size and -gdb String CeCosTest::CygPath (LPCTSTR pszPath) { @@ -1559,62 +1123,62 @@ String CeCosTest::CygPath (LPCTSTR pszPa void CeCosTest::SetExecutable(LPCTSTR pszExecutable) { m_strOutput=_T(""); - m_strResultString=_T(""); - m_strExecutable=pszExecutable; - if(pszExecutable && !GetSizes(m_strExecutable, m_ep.Target(), m_nFileSize, m_nStrippedSize)){ - const TargetInfo &t=Target(Target()); - Log(_T("Failed to run %s-size to determine executable size of %s\n"),t.Prefix(),pszExecutable); + if(pszExecutable){ + m_strExecutable=pszExecutable; + if(m_ep.Platform()){ + GetSizes(); + } else { + ERROR(_T("Don't know how to get sizes of this platform type\n")); + } + } else { + m_strExecutable=_T(""); } } // Calculate the sizes of the given file. The target parameter is necessary in order to // determine which -size executable to use to do the job. -bool CeCosTest::GetSizes(LPCTSTR pszExecutable, LPCTSTR target,unsigned int &nFileSize, unsigned int &nStrippedSize) +bool CeCosTest::GetSizes() { +TRACE(_T("GetSizes %s\n"),(LPCTSTR)Executable()); bool rc=false; - nStrippedSize=nFileSize=0; + m_nStrippedSize=m_nFileSize=0; + LPCTSTR pszPrefix=m_ep.Platform()->Prefix(); struct _stat buf; - const TargetInfo &t=Target(target); - LPCTSTR pszPrefix=t.Prefix(); - if(0==_tstat(pszExecutable,&buf) && _TCHAR('\0')!=*pszPrefix){ - // File at least exists... - nFileSize=buf.st_size; - String strSize(pszPrefix); - strSize+=_T("-size "); - strSize+=CygPath(pszExecutable); - const TCHAR *c=0; -#ifdef _WIN32 - CSubprocess sp; + if(-1==_tstat(Executable(),&buf)){ + Log(_T("%s does not exist\n"),(LPCTSTR)Executable()); + } else if (_TCHAR('\0')==*pszPrefix){ + LogString(_T("No prefix to run a size program\n")); + } else { + m_nFileSize=buf.st_size; + const String strSizeCmd(String::SFormat(_T("%s-size %s"),pszPrefix,(LPCTSTR)CygPath(Executable()))); String strOut; - if(!sp.Run(strOut,strSize,NULL)){ - return true; - } - c=_tcschr(strOut,_TCHAR('\n')); - if(c){ - c++; + CSubprocess sp; + if(!sp.Run(strOut,strSizeCmd)){ + Log(_T("Failed to run \"%s\" - %s\n"),(LPCTSTR)strSizeCmd,(LPCTSTR)sp.ErrorString()); + } else { + const TCHAR *c=_tcschr(strOut,_TCHAR('\n')); + if(c){ + c++; + } + int s1=0; + int s2=0; + if(c && 2==_stscanf(c,_T(" %d %d"),&s1,&s2)){ + rc=true; + m_nStrippedSize=s1+s2; + } + TRACE(_T("GetSizes %s rc=%d file size=%d stripped size=%d\n"),(LPCTSTR)Executable(),rc,m_nFileSize,m_nStrippedSize); } -#else // UNIX - TCHAR buf[256]; - FILE *f=POPEN(strSize,_T("r")); - if(f){ - _fgetts(buf,sizeof buf-1,f); - _fgetts(buf,sizeof buf-1,f); - PCLOSE(f); - c=buf; - } -#endif - int s1=0; - int s2=0; - rc=(c && 2==_stscanf(c,_T(" %d %d"),&s1,&s2)); - nStrippedSize=s1+s2; } return rc; } -void CeCosTest::SetTimeouts (Duration dActive,Duration dElapsed) +void CeCosTest::SetTimeouts (Duration dActive,Duration dDownload/*,Duration dElapsed*/) { - m_ep.SetActiveTimeout (dActive); - m_ep.SetDownloadTimeout(dElapsed); + m_ep.SetActiveTimeout (dActive); + m_ep.SetDownloadTimeout(dDownload); +/* + m_ep.SetElapsedTimeout (dElapsed); +*/ } void CeCosTest::CloseSocket (){ @@ -1622,72 +1186,14 @@ void CeCosTest::CloseSocket (){ m_pSock=0; } -bool CeCosTest::AtPrompt(LPCTSTR pszPrompt) -{ - unsigned int nPromptLen=_tcslen(pszPrompt); - return - m_strOutput.GetLength()>=nPromptLen && - 0==_tcscmp((LPCTSTR )m_strOutput+m_strOutput.GetLength()-nPromptLen,pszPrompt); -} - -#ifndef _WIN32 -bool CeCosTest::Suck(LPCTSTR pszPrompt,Duration d) +bool CeCosTest::AtPrompt() { - TRACE(_T("Suck handle=%08x\n"),m_rPipeHandle);//sdf - // Read until: - // 8k read - // timeout elapsed - // gdb prompt reached - // pipe error - Time t0=Now(); - int nLength=0; - while(nLength<8192 && m_rPipeHandle && !AtPrompt(pszPrompt) && Now()-t00){ - LogTimeStampedOutput(str); - nLength+=n; - } else if (n<0) { - break; - } - } - TRACE(_T("End suck\n"));//sdf - return nLength>0; -} -#endif - -void CeCosTest::LogTimeStampedOutput(LPCTSTR psz) -{ - LogString(psz); - /* - String str(psz); - // Timestamp the output at each _TCHAR('\n') - int nLen=m_strOutput.GetLength(); - TCHAR cPrev=(0==nLen?_TCHAR('\0'):((LPCTSTR )m_strOutput)[nLen-1]); - - TCHAR *c=str.GetBuffer(); - LPCTSTR d=c; - while(*c){ - if(_TCHAR('\n')==cPrev){ - TCHAR cSav=*c; - *c=_TCHAR('\0'); - LogString(d); - Duration &dTime=m_bDownloading?m_nDownloadTime:m_nMaxInactiveTime; - dTime=MAX(dTime,GdbTime()-m_tBase); - - String strTime; - strTime.Format(_T("<") WFS _T("/") WFS _T(">\t"),WF(GdbTime()-m_tBase0), WF(GdbTime()-m_tBase)); - //strTime.Format(_T("<%03d.%d> "),t/1000,(t%1000)/100); - LogString(strTime); - *c=cSav; - d=c; - } - cPrev=*c; - c++; - } - LogString(d); - str.ReleaseBuffer(); - */ + const String strPrompt(m_ep.Platform()->Prompt()); + unsigned int nPromptLen=_tcslen(strPrompt); + return + nPromptLen>0 && + m_strOutput.size()>=nPromptLen && + 0==_tcscmp((LPCTSTR)m_strOutput+m_strOutput.size()-nPromptLen,strPrompt); } #ifdef _WIN32 @@ -1701,19 +1207,24 @@ BOOL WINAPI HandlerRoutine( #endif -bool CeCosTest::InteractiveGdb(const String &strHost,int nPort,TCHAR **argv) +bool CeCosTest::InteractiveInferior(LPCTSTR pszHostPort,TCHAR **argv) { bool rc=false; - if(strHost.GetLength()>0){ - m_strExecutionHostPort=CeCosTestSocket::HostPort(strHost,nPort); - Log(_T("Waiting to connect to %s...\n"),(LPCTSTR )m_strExecutionHostPort); + if(_TCHAR('\0')!=*pszHostPort){ + if(!CeCosSocket::IsLegalHostPort(pszHostPort)){ + ERROR(_T("Illegal host:port '%s'\n"),pszHostPort); + return false; + } else { + m_strExecutionHostPort=pszHostPort; + Log(_T("Waiting to connect to %s...\n"),(LPCTSTR)m_strExecutionHostPort); + } } else { Log(_T("Waiting to connect to a server...\n")); } ConnectForExecution(); - Log(_T("Connected to %s - waiting for target reset\n"),(LPCTSTR )m_strExecutionHostPort); + Log(_T("Connected to %s - waiting for target reset\n"),(LPCTSTR)m_strExecutionHostPort); String strHostPort,strOutput; // We read: // target ready indicator @@ -1721,14 +1232,13 @@ bool CeCosTest::InteractiveGdb(const Str // (if target ready) host:port if(GetTargetReady(strHostPort)){ Log(_T("Use %s\n"),(LPCTSTR)strHostPort); - const TargetInfo &t=Target(Target()); - String strGdb(t.Prefix()); - strGdb+=_T("-gdb"); + String strInferior(m_ep.Platform()->Prefix()); + strInferior+=_T("-gdb"); #ifdef _WIN32 SetConsoleCtrlHandler(HandlerRoutine,TRUE); - int n=_tspawnvp(_P_WAIT,strGdb,argv); + int n=_tspawnvp(_P_WAIT,strInferior,argv); if(-1==n){ - Log(_T("Failed to spawn %s\n"),(LPCTSTR)strGdb); + Log(_T("Failed to spawn %s\n"),(LPCTSTR)strInferior); } else { rc=(0==n); } @@ -1743,8 +1253,8 @@ bool CeCosTest::InteractiveGdb(const Str break; case 0: // Process is created (we're the child) - execvp(strGdb,argv); - Log(_T("Error invoking %s - %s\n"),(LPCTSTR)strGdb,strerror(errno)); + execvp(strInferior,argv); + Log(_T("Error invoking %s - %s\n"),(LPCTSTR)strInferior,strerror(errno)); exit(1); break; default: @@ -1759,11 +1269,10 @@ bool CeCosTest::InteractiveGdb(const Str break; } #endif - Log(_T("Gdb terminated\n")); + Log(_T("Inferior terminated\n")); // Tell the server we're through m_pSock->sendInteger(123,_T("Terminating ack")); } - return rc; } @@ -1776,11 +1285,6 @@ void CALLBACK CeCosTest::ResetLogFunc(vo pTest->m_pSock->sendString(psz,_T("output so far")); } -CResetAttributes::ResetResult CeCosTest::Reset(bool bSendStatus) -{ - return m_pPort->Reset(bSendStatus?ResetLogFunc:0,this); -} - CeCosTest::ExecutionParameters::RequestType CeCosTest::ExecutionParameters::RequestTypeValue(LPCTSTR psz) { int r; @@ -1792,407 +1296,172 @@ CeCosTest::ExecutionParameters::RequestT return (RequestType)r; } -#ifdef _WIN32 -void CeCosTest::RunGdb(LPCTSTR pszCmdline,LPCTSTR pszPrompt,const StringArray &arstrGdbCmds) +void CeCosTest::InferiorOutputFunc(LPCTSTR pszMsg) { - SetPath(m_strPath); - CSubprocess sp; + LogString(pszMsg); + + m_nOutputLen+=_tcslen(pszMsg); - unsigned int idProcess=sp.Run(GetCurrentThreadId(),pszCmdline); - if(!idProcess){ - Log(_T("Failed to create gdb process: cmdline='%s'\n"),pszCmdline); - TCHAR *pszMsg; - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - sp.GetExitCode(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR)&pszMsg, - 0, - NULL - ); - - // Display the string. - Log(_T("%s\n"),pszMsg); - - // Free the buffer. - LocalFree(pszMsg); - } else { + if(m_pspPipe){ + m_pspPipe->Send(pszMsg); + } - unsigned int nCmdIndex=0; - - SetStatus(NotStarted); - - m_nMaxInactiveTime=0; - m_nTotalTime=0; - m_nDownloadTime=0; + if(m_nOutputLen>20000){ + LogString(_T("\n>>>> Infra FAIL\n*** too much output ***\n>>>>\n")); + SetStatus(Fail); + m_psp->Kill(); + } - m_bDownloading=true; - - m_tBase=GdbTime(); - m_tBase0=GdbTime(); - m_tWallClock0=Now(); - - TRACE(_T("RunGDb()\n")); - - int nLastGdbInst=0; + m_tBase=InferiorTime(); // We are seeing life, so reset the clock for timeouts - while(Cancelled!=Status() && CheckForTimeout()){ - MSG msg; - if(::PeekMessage(&msg,NULL,WM_SUBPROCESS,WM_SUBPROCESS+1,PM_NOREMOVE)){ - switch(::GetMessage(&msg,NULL,WM_SUBPROCESS,WM_SUBPROCESS+1)){ - case 0: //WM_QUIT - case -1: // error - goto Done; - case 1: - if(WM_SUBPROCESS==msg.message && msg.wParam==idProcess){ - if(msg.lParam){ - LPTSTR pszMsg=(LPTSTR)msg.lParam; - LogTimeStampedOutput(pszMsg); - - if(m_strOutput.GetLength()>20000){ - LogString(_T("\n>>>> Infra FAIL\n*** too much output ***\n>>>>\n")); - SetStatus(Fail); - goto Done; - } - - // Test for program loaded and started: - // (remember SetStatus cannot downgrade the status if already > NoResult) - if(OutputContains(_T("Starting program: /")) || (OutputContains(_T("Start address"))&&OutputContains(_T("Continuing.")))){ - SetStatus(NoResult); - } - - m_tBase=GdbTime(); - // // If can only hit a single breakpoint don't expect cyg_test_exit to stop us: - // if(!BreakpointsOperational() && (OutputContains(_T("EXIT:"))||OutputContains(_T("NOTAPPLICABLE:")))){ - // goto Done; - // } - - if(AtPrompt(pszPrompt)){ - m_tBase=GdbTime(); - TRACE(_T("RunGDb(1)\n")); - // gdb's output included one or more prompts - // Send another command along - if(nCmdIndex>=arstrGdbCmds.size()){ - // Nothing further to say to gdb - exit - TRACE(_T("RunGDb(2)\n")); - goto Done; // case 3 - } else { - String strCmd(arstrGdbCmds[nCmdIndex++]); - TRACE(_T("RunGDb(2a) - strCmd='%s' nLastGdbInst=%d\n"),(LPCTSTR)strCmd,nLastGdbInst); - // If at a prompt and we can see a GDB instruction, send it down - LPCTSTR pszGdbcmd=_tcsstr(nLastGdbInst+(LPCTSTR)m_strOutput,_T("GDB:")); - if(pszGdbcmd){ - TRACE(_T("RunGDb(2b)\n")); - pszGdbcmd+=4; - TCHAR cTerm; - if(_TCHAR('<')==*pszGdbcmd){ - cTerm=_TCHAR('>'); - pszGdbcmd++; - } else { - cTerm=_TCHAR('\n'); - } - TRACE(_T("RunGDb(2c)\n")); - LPCTSTR c=_tcschr(pszGdbcmd,cTerm); - if(c){ - TRACE(_T("RunGDb(2d)\n")); - strCmd=String(pszGdbcmd,c-pszGdbcmd); - nLastGdbInst=c+1-(LPCTSTR )m_strOutput; - nCmdIndex--; // undo increment above - } - } - strCmd+=_TCHAR('\n'); - LogString(strCmd); - TRACE(_T("RunGDb(3)\n")); - sp.Send(strCmd); - TRACE(_T("RunGDb(4)\n")); - if(0==_tcscmp(strCmd,_T("run\n"))||0==_tcscmp(strCmd,_T("cont\n"))){ - m_tBase=GdbTime(); - m_bDownloading=false; - } - TRACE(_T("RunGDb(5)\n")); - } - } - delete [] pszMsg; - } else { - goto Done; - } - } - break; - } - } else { // no message - Sleep (500l); // sleep 500ms before the next peek + if(AtPrompt()){ + + // gdb's output included one or more prompts + // Send another command along + if(m_nCmdIndex>=m_arstrInferiorCmds.size()){ + // Nothing further to say to gdb - exit + + m_psp->Kill(); // case 3 + } else { + + if(m_nCmdIndex>0 && 0==_tcscmp(_T("load"),m_arstrInferiorCmds[m_nCmdIndex-1])){ + // load command was previous command - we are no longer downloading + m_bDownloading=false; + } + + String strCmd(m_arstrInferiorCmds[m_nCmdIndex++]); + + // If we can there is a GDB instruction to send to gdb, do it + String str; + if(GetDirective(_T("GDB:"),str,m_nLastGdbInst)){ + strCmd=str; + m_nCmdIndex--; // undo increment above + } + + if(0==_tcscmp(_T("load"),strCmd)){ + // load command issued - we are now "downloading" + m_bDownloading=true; + } else if(0==_tcscmp(_T("run"),strCmd) || 0==_tcscmp(_T("cont"),strCmd)){ + SetStatus(NoResult); + } + + strCmd+=_TCHAR('\n'); + LogString(strCmd); + m_psp->Send(strCmd); + + } + } + + // If there is a EXEC instruction to process, obey it + String strCmd; + while(GetDirective(_T("EXEC:"),strCmd,m_nLastExecInst)){ + CSubprocess *pExecsp=new CSubprocess; + pExecsp->SetPath(m_strPath); + if(!pExecsp->Run(AppendFunc,this,(LPCTSTR)strCmd,false)){ + Log(_T("%%%% Failed to create process '%s'\n"),(LPCTSTR)strCmd); + delete pExecsp; + } else { + m_arpExecsp.push_back(pExecsp); + } + } + + // If there is a PIPE instruction to process, obey it + while(GetDirective(_T("PIPE:"),strCmd,m_nLastPipeInst)){ + if(m_pspPipe){ + Log(_T("%%%% Two PIPE commands are a no-no\n")); + } else { + m_pspPipe=new CSubprocess; + m_pspPipe->SetPath(m_strPath); + + if(!m_pspPipe->Run(AppendFunc,this,(LPCTSTR)strCmd,false)){ + Log(_T("%%%% Failed to create process '%s'\n"),(LPCTSTR)strCmd); + delete m_pspPipe; + m_pspPipe=0; + } else { + // Send what we read have so far + m_pspPipe->Send(m_strOutput); } } - -Done: - // Could use CygKill here - sp.Kill(); - TRACE(_T("RunGDb - Done\n")); - AnalyzeOutput(); - - m_nTotalTime=Duration(Now()-m_tWallClock0); } - TRACE(_T("Exiting RunGdb()\n")); -} - -bool CeCosTest::GdbProcessAlive() -{ - DWORD dwExitRc; - GetExitCodeProcess((HANDLE)m_pGdbProcesshandle,&dwExitRc); - return STILL_ACTIVE==dwExitRc; -} -Time CeCosTest::GdbCpuTime() -{ - HANDLE hProcess=(HANDLE)m_pGdbProcesshandle; - __int64 ftCreation,ftExit,ftKernel,ftUser; - if(NULL!=hProcess && GetProcessTimes (hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){ - return Time((int)((ftKernel+ftUser)/10000)); - } else { - return 0; - } -} - -void CeCosTest::GetPath(String &strPath) -{ - int nSize=GetEnvironmentVariable(_T("PATH"), NULL, 0); - if(nSize>0){ - GetEnvironmentVariable(_T("PATH"), strPath.GetBuffer(nSize), nSize); - strPath.ReleaseBuffer(); - } else { - strPath=_T(""); + while(GetDirective(_T("TIMEOUT:"),strCmd,m_nLastTimeoutInst)){ + int n=_ttoi(strCmd); + if(n){ + SetTimeouts(n); // second parameter is download timeout, which is now irrelevant + } else { + Log(_T("%%%% Illegal timeout specified: %s\n"),(LPCTSTR)strCmd); + } } } -void CeCosTest::SetPath(const String &strPath) -{ - SetEnvironmentVariable(_T("PATH"), strPath); -} - -#else // UNIX - -void CeCosTest::RunGdb(LPCTSTR pszCmdline,LPCTSTR pszPrompt,const StringArray &arstrGdbCmds) +void CeCosTest::RunInferior(LPCTSTR pszCmdline) { - int pipe_ends_w[2]; - if (pipe(pipe_ends_w) < 0 ) { - Log(_T("Failed to create pipe_ends_w - %s\n"),strerror(errno)); - } else { - int pipe_ends_r[2]; - if (pipe(pipe_ends_r) < 0 ) { - Log(_T("Failed to create pipe_ends_r - %s\n"),strerror(errno)); - } else { - int new_pid; - ENTERCRITICAL; - // Ensure no one else has the lock such that the child might block in future - new_pid = fork(); - // This leave is executed in *both* the child and parent - LEAVECRITICAL; - - switch (new_pid) { - // Fork failed - case -1: - Log(_T("Failed to create gdb process - %s\n"),strerror(errno)); - break; - case 0: - // Process is created (we're the child) - // No point in calling Log in this process - - // Input to child process - if (dup2(pipe_ends_w[0], 0) < 0) { - TRACE(_T("dup2 error\n")); - exit(1); - } - - // Output from process - if (dup2(pipe_ends_r[1], 2) < 0) { - TRACE(_T("dup2 error\n")); - exit(2); - } - if (dup2(pipe_ends_r[1], 1) < 0) { - TRACE(_T("dup2 error\n")); - exit(3); - } - setvbuf(stdout,0,_IONBF,0); - setvbuf(stderr,0,_IONBF,0); - { - StringArray ar; - int argc=String(pszCmdline).Chop(ar,_TCHAR(' '),true); - char **argv=new char *[1+argc]; - int i; - for(i=0;i\n"), pszCmdline, new_pid); - if (fcntl(pipe_ends_r[0], F_SETFL, O_NONBLOCK) <0) { - Log(_T("Couldn't set pipe non-blocking - %s\n"),strerror(errno)); - } else { - m_pGdbProcesshandle=(void *)new_pid; - VTRACE(_T("RunGdb():Calling DriveGdb\n")); - m_rPipeHandle=(void *)pipe_ends_r[0]; - m_wPipeHandle=(void *)pipe_ends_w[1]; - DriveGdb (pszPrompt,arstrGdbCmds); - // Finished one way or another. Kill gdb now - TRACE(_T("Finished processing this test.\n")); - if(GdbProcessAlive()){ - TRACE(_T("Killing gdb\n")); - - // We need to kill gdb *and* its children - FILE *f=popen(_T("ps -l"),_T("r")); - if(f){ - TCHAR buf[100]; - while(_fgetts(buf,sizeof(buf)-1,f)){ - int F,UID,PID,PPID,C,PRI,NI,SZ,HH,MM,SS; - TCHAR discard[100]; - // Output is in the form - // F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD - //100 S 490 877 876 0 70 0 - 368 wait4 pts/0 00:00:00 bash - if(15==_stscanf(buf, - _T("%d %s %d %d %d %d %d %d %s %d %s %s %d:%d:%d"),&F,discard,&UID,&PID,&PPID,&C,&PRI,&NI,discard,&SZ,discard,discard,&HH,&MM,&SS) && - (PID==new_pid || PPID==new_pid)){ - kill(PID,SIGTERM); - } - } - pclose(f); - TRACE(_T("waitpid <%d>"), new_pid); - int i; - for(i=0;i<10;i++){ - int status; - switch(waitpid(new_pid,&status,WNOHANG)){ - case 0: - Sleep(1000); - continue; - case -1: - Log(_T("Failed to wait for gdb process to die\n")); - SetStatus(TimeOut); - break; - default: - break; - } - break; - } - if(10==i){ - Log(_T("Failed to wait for gdb process to die\n")); - SetStatus(TimeOut); - } else { - TRACE(_T("Killed gdb\n")); - } - } else { - Log(_T("Failed to run ps to kill gdb process %d\n"),new_pid); - } - } - TRACE(_T("Total elapsed time is %d\n"), m_nTotalTime); - } + m_psp=new CSubprocess; + m_psp->SetContinuationFunc(SCheckForTimeout,this); + try { + m_nMaxInactiveTime=0; + m_nTotalTime=0; + m_nDownloadTime=0; + m_nOutputLen=0; + m_bDownloading=false; + + // Decide on the baseline status - NotStarted if there is a download element, NoResult otherwise. + m_Status=NoResult; + for(unsigned int i=0;iSetPath(m_strPath); + if(m_psp->Run(SInferiorOutputFunc,this,pszCmdline,true)){ -Time CeCosTest::GdbCpuTime() -{ - if(GdbProcessAlive()){ - Time now=Now(); - if(now-m_tPrevSample>1000){ - - m_tPrevSample=now; - // Output is in the form - // F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD - //100 S 490 877 876 0 70 0 - 368 wait4 pts/0 00:00:00 bash - FILE *f=popen(_T("ps -l"),_T("r")); - if(f){ - TCHAR buf[100]; - int t=0; - while(_fgetts(buf,sizeof(buf)-1,f)){ - int F,UID,PID,PPID,C,PRI,NI,SZ,HH,MM,SS; - TCHAR discard[100]; -TRACE(_T("ps -l : %s\n"),buf); - if(15==_stscanf(buf, - _T("%d %s %d %d %d %d %d %d %s %d %s %s %d:%d:%d"),&F,discard,&UID,&PID,&PPID,&C,&PRI,&NI,discard,&SZ,discard,discard,&HH,&MM,&SS) && - (PID==(int)m_pGdbProcesshandle || PPID==(int)m_pGdbProcesshandle)){ - t+=SS+60*(60*HH+MM); + if(m_pspPipe){ + m_pspPipe->Send(_T("\n")); + m_pspPipe->CloseInput(); + if(m_pspPipe->Wait(5000)){ + // OK the pipe process terminated. + int rc=m_pspPipe->GetExitCode(); + if(0!=rc){ + Log(_T("%%%% Pipe process returned rc=%d\n"),rc); + SetStatus(Fail); } + } else { + LogString(_T("%%%% Pipe process would not complete\n")); } - pclose(f); -TRACE(_T("---> t=%d [secs]\n"),t); - m_tGdbCpuTime=Time(1000*t); } + + AnalyzeOutput(); + + } else { + Log(_T("Failed to run \"%s\" - %s\n"),pszCmdline,(LPCTSTR)m_psp->ErrorString()); } - } else { - m_tGdbCpuTime=0; + } + catch(...){ + ERROR(_T("!!! Exception caught in RunInferior()\n")); } -VTRACE(_T("GdbCpuTime rc=%d"),m_tGdbCpuTime/1000); - return m_tGdbCpuTime; -} - -bool CeCosTest::WritePipe (const String &str) -{ - const char *pszBuf=(const char *)str; - int write_fd = (int)m_wPipeHandle; - int dwWritten; - int nToWrite=_tcslen(pszBuf); - do { - dwWritten = write(write_fd, pszBuf, nToWrite); - if(-1==dwWritten){ - Log(_T("pipe write error - %s\n"),strerror(errno)); - return false; - } - nToWrite-=(int)dwWritten; - pszBuf+=(int)dwWritten; - if(!CheckForTimeout()){ - return false; - } - } while (nToWrite>0); - return true; + delete m_psp; // will cause process to be killed as necessary and completion to be waited for + m_psp=NULL; + for(int i=0;i<(signed)m_arpExecsp.size();i++){ + delete (CSubprocess *)m_arpExecsp[i]; // ditto + } + m_arpExecsp.clear(); + TRACE(_T("Exiting RunInferior()\n")); } -int CeCosTest::ReadPipe (String &str,bool bBlocking /* This param ignored */) -{ - TCHAR buf[4096]; - int rc=read((int)m_rPipeHandle, buf, sizeof(buf)-1); - if(-1==rc && EAGAIN==errno){ - rc=0; - } - buf[MAX(0,rc)]=_TCHAR('\0'); - str=buf; - return rc; -} - -void CeCosTest::GetPath(String &strPath) -{ - strPath=getenv(_T("PATH")); -} - - -void CeCosTest::SetPath(const String &strPath) -{ - String str; - str.Format(_T("PATH=%s"),(LPCTSTR )strPath); - putenv(str); -} -#endif - void CeCosTest::AnalyzeOutput() { // This test is pulled out to allow ser_filter to simulate a test failure @@ -2205,7 +1474,7 @@ void CeCosTest::AnalyzeOutput() static const StatusType arStatus[] ={Fail, Inapplicable, Pass}; for(unsigned int i=0;i') - for(LPCTSTR d=_tcschr(c,_TCHAR('>'));d;d=_tcschr(d+1,_TCHAR('>'))){ - if(d[-1]!=_TCHAR('\\')){ - - /* - // Skip whitespace immediately following the EXPECT:<...> - do { - d++; - } while (_istspace(*d)); - */ - - /* - // Skip timestamp - if(_TCHAR('<')==*d){ - d=_tcschr(d,_TCHAR('>')); - if(0==d){ - continue; - } - do { - d++; - } while (_istspace(*d)); - } - */ - - // Now d points to the terminating _TCHAR('>') and c at the start of the expected string - for(LPCTSTR e=d+1;c!=d;c++,e++){ - if(_TCHAR('\\')==*c){ - c++; - } - if(*c!=*e){ - LogString(_T("EXPECT:<> failure\n")); - SetStatus(Fail); - break; - } - } - break; - } + int nIndex=0; + String str; + while(GetDirective(_T("EXPECT:"),str,nIndex)){ + // s1 is the pointer to the text following the expect - that to be tested + LPCTSTR s1=(LPCTSTR)m_strOutput+nIndex; + while (_istspace(*s1)){ + s1++; + } + // whereas s2 is the pointer to the text in the expect string (what we are expecting) + LPCTSTR s2=(LPCTSTR)str; + while(*s2){ + if(*s2!=*s1){ + Log(_T("EXPECT:<> failure - expected '%s' saw '%s'\n"),(LPCTSTR)str,(LPCTSTR)m_strOutput+nIndex); + SetStatus(Fail); + break; } + s1++; + s2++; } } } @@ -2312,7 +1554,7 @@ bool CeCosTest::ExecutionParameters::Fro } } m_Request=(RequestType)r; - return CeCosTest::IsValid(m_Target); + return CeCosTestPlatform::IsValid(m_Target); } CeCosTest::ExecutionParameters::ExecutionParameters (RequestType r, @@ -2335,7 +1577,8 @@ CeCosTest::ExecutionParameters::Executio String CeCosTest::ExecutionParameters::Image() const { String str; - str.Format(_T("%s %s %d %d %d %d %d %d %d %d"),Target(),Image(Request()),ActiveTimeout(),DownloadTimeout(), + str.Format(_T("%s %s %d %d %d %d %d %d %d %d"),(LPCTSTR)PlatformName(),(LPCTSTR)Image(Request()), + ActiveTimeout(),DownloadTimeout(), m_nUnused1, m_nUnused2, m_nUnused3, @@ -2345,55 +1588,13 @@ String CeCosTest::ExecutionParameters::I return str; } -CeCosTest::TargetInfo::TargetInfo() -{ -}; - -LPCTSTR CeCosTest::TargetInfo::arHwTypeImage[]={_T("HARDWARE"), _T("SIM"), _T("SYNTHETIC"), _T("HARDWARE_NO_BP"), _T("REMOTE_SIM") -}; - -CeCosTest::TargetInfo::TargetInfo(LPCTSTR pszIm,LPCTSTR pszPre,int nHwtype,LPCTSTR pszGdb/*=_T("")*/): - pszImage(pszIm), - pszPrefix(pszPre), - nType((HwType)nHwtype), - pszGdbcmd(pszGdb) -{ -} - -CeCosTest::TargetInfo::TargetInfo(LPCTSTR pszIm,LPCTSTR pszPre,LPCTSTR pszHwtype,LPCTSTR pszGdb/*=_T("")*/): - pszImage(pszIm), - pszPrefix(pszPre), - nType(INVALID), - pszGdbcmd(pszGdb) -{ - if(_istdigit(pszHwtype[0])){ - nType=(HwType)_ttoi(pszHwtype); - if((unsigned)nType>sizeof(arHwTypeImage)){ - nType=INVALID; - } - } else { - for(unsigned int i=0;irecvInteger(nTargetReady,_T("Target ready"),120*1000)){ - Log(_T("Failed to read target ready indicator from server - %s\n"),(LPCTSTR )m_pSock->SocketErrString()); + Log(_T("Failed to read target ready indicator from server - %s\n"),(LPCTSTR)m_pSock->SocketErrString()); break; } switch(nTargetReady){ @@ -2402,10 +1603,10 @@ bool CeCosTest::GetTargetReady(String &s break; case 1: if(m_pSock->recvString(strHostPort, _T("host:port"))){ - TRACE(_T("Instructed to use %s\n"),(LPCTSTR )strHostPort); + TRACE(_T("Instructed to use %s\n"),(LPCTSTR)strHostPort); rc=true; } else { - Log(_T("Failed to read host:port - %s\n"),(LPCTSTR )m_pSock->SocketErrString()); + Log(_T("Failed to read host:port - %s\n"),(LPCTSTR)m_pSock->SocketErrString()); } break; case 2: @@ -2414,7 +1615,7 @@ bool CeCosTest::GetTargetReady(String &s if(m_pSock->recvString(strOutput, _T("output"))){ LogString(strOutput); } else { - Log(_T("Failed to read output\n"),(LPCTSTR )m_pSock->SocketErrString()); + Log(_T("Failed to read output\n"),(LPCTSTR)m_pSock->SocketErrString()); return false; } } @@ -2424,39 +1625,6 @@ bool CeCosTest::GetTargetReady(String &s return rc; } -#ifdef _WIN32 -String CeCosTest::GetGreatestSubkey (LPCTSTR pszKey) -{ - String strSubkey = _T(""); - HKEY hKey; - - if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, pszKey, 0L, KEY_READ, &hKey)) - { - DWORD dwIndex = 0; - TCHAR pszBuffer [MAX_PATH + 1]; - - while (ERROR_SUCCESS == RegEnumKey (hKey, dwIndex++, (LPTSTR) pszBuffer, sizeof (pszBuffer))) - { - if (strSubkey.compare (pszBuffer) < 0) - strSubkey = pszBuffer; - } - - RegCloseKey (hKey); - } - - TRACE (_T("CeCosTest::GetGreatestSubkey(\"%s\"): %s\n"), pszKey, (LPCTSTR)strSubkey); - return strSubkey; -} -#endif - - -void CeCosTest::RemoveAllPlatforms() -{ - for(int i=TargetTypeMax()-1;i>=0;--i){ - delete &Target(i); - } - arTargetInfo.clear(); -} CeCosTest::ServerStatus CeCosTest::ServerStatusValue(LPCTSTR psz) { @@ -2470,13 +1638,127 @@ CeCosTest::ServerStatus CeCosTest::Serve } -const CeCosTest::TargetInfo &CeCosTest::Target (LPCTSTR psz) -{ - for(int i=0;i<(signed)arTargetInfo.size();i++){ - const TargetInfo &t=arTargetInfo[i]; - if(0==_tcsicmp(t.Image(),psz)){ - return t; +// Gets a directive from the test output (like EXEC:) +bool CeCosTest::GetDirective(LPCTSTR pszDirective, String &str, int &nIndex) +{ + bool rc=false; + ENTERCRITICAL; + LPCTSTR pszOutput=(LPCTSTR)m_strOutput; + LPCTSTR pc=_tcsstr(pszOutput+nIndex,pszDirective); + if(pc){ + + pc+=_tcslen(pszDirective); // Now after the final character (':') of the directive + if(_TCHAR('<')==*pc){ + + pc++; + + // Extract the argument + str=_T(""); + while(*pc){ + // Process escapes: FIXME more escapes? + TCHAR c=*pc; + if(_TCHAR('\\')==c){ + switch(pc[1]){ + case _TCHAR('t'): + c=_TCHAR('\t'); + break; + case _TCHAR('n'): + c=_TCHAR('\n'); + break; + case _TCHAR('\0'): + pc--; // avoid grief + break; + default: + c=pc[1]; + break; + } + pc++; + } else if (_TCHAR('>')==c) { + nIndex=pc+1-pszOutput; + rc=true; + break; + } else if (_TCHAR('\n')==c) { + nIndex=pc+1-pszOutput; + Log(_T("%%%% Unterminated directive: %s"),(LPCTSTR)str); + break; + } + str+=c; + pc++; + } } } - return tDefault; + LEAVECRITICAL; + return rc; } + +void CeCosTest::GetInferiorCommands(StringArray &arstrInferiorCmds) +{ + arstrInferiorCmds.clear(); + + // Construct commands for gdb. The commands may be found (semicolon-separated) in the target info: + const String strInferiorCmds(m_ep.Platform()->GdbCmds()); + StringArray ar; + int nCmds=strInferiorCmds.Chop(ar,_TCHAR(';'),false); + for(int i=0;iBaud()){ + goto NextCmd; // Suppress output of this command if there is no baud rate to output + } + strCmd+=String::SFormat(_T("%d"),m_pResource->Baud()); + pc++; + continue; + case _TCHAR('p'): + if(_TCHAR('\0')==*(m_pResource->Serial())){ + goto NextCmd; // Suppress output of this command if there is no serial port + } + strCmd+=m_pResource->Serial(); + pc++; + continue; + case _TCHAR('\0'): + continue; + default: + break; + } + break; + default: + break; + } + strCmd+=*pc; + } + arstrInferiorCmds.push_back(strCmd); +NextCmd: + ; + } + return; +} + diff --git a/host/tools/ecostest/common/eCosTest.h b/host/tools/ecostest/common/eCosTest.h --- a/host/tools/ecostest/common/eCosTest.h +++ b/host/tools/ecostest/common/eCosTest.h @@ -42,58 +42,30 @@ #ifndef _ECOSTEST_H #define _ECOSTEST_H -// eCos testing infrastructure + +//================================================================= // This class represents a single eCos test [executable]. -// It includes member functions to run the test and to manage -// related system resources. +// It includes member functions to run the test and to manage related system resources. +//================================================================= +#include "Collections.h" #include "eCosStd.h" +#include "eCosTestPlatform.h" #include "eCosTestUtils.h" -#include "eCosThreadUtils.h" -#include "Properties.h" #include "ResetAttributes.h" -#include +class CSubprocess; class CTestResource; -class CeCosTestSocket; +class CeCosSocket; + class CeCosTest{ public: - static bool Init(); - static void Term(); - - static bool SaveTargetInfo(); - class TargetInfo { - public: - // Update arHwTypeImage if you add to this enum - enum HwType {INVALID=-1, HARDWARE=0, SIM=1, SYNTHETIC=2, HARDWARE_NO_BP=3, REMOTE_SIM=4 - }; - protected: - String pszImage; - String pszPrefix; - HwType nType; - String pszGdbcmd; - public: - static LPCTSTR arHwTypeImage[]; - static HwType FromStr (LPCTSTR psz); - bool IsValid() const { return nType!=INVALID; } - LPCTSTR Image() const { return pszImage.c_str(); } - LPCTSTR Prefix() const { return pszPrefix.c_str(); } - LPCTSTR GdbCmd() const { return pszGdbcmd.c_str(); } - HwType Type() const { return nType; } - TargetInfo(); - TargetInfo(LPCTSTR pszIm,LPCTSTR pszPre,LPCTSTR pszHwtype,LPCTSTR pszGdb=0); - TargetInfo(LPCTSTR pszIm,LPCTSTR pszPre,int nHwtype,LPCTSTR pszGdb=0); // FIXME: phase this out as soon as we can - }; - - static int AddPlatform (const TargetInfo &t); - static int InitTargetInfoReg (LPCTSTR szRegKey); - static bool SaveTargetInfoReg (LPCTSTR szRegKey); static LPCTSTR pszFormat; /////////////////////////////////////////////////////////////////////////// // Representation of an elapsed time (units of milliseconds) - enum {NOTIMEOUT=0}; // No timeout specified + enum {NOTIMEOUT=0x7fffffff}; // No timeout specified /////////////////////////////////////////////////////////////////////////// // ctors, dtors and their friends @@ -111,15 +83,6 @@ public: /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// - // Representation of target: - static unsigned int TargetTypeMax() { return (unsigned)arTargetInfo.size(); } - static LPCTSTR const Image(unsigned int i) { return arTargetInfo[i].Image(); } - static const TargetInfo &Target(unsigned int i) { return arTargetInfo[i]; } - static const TargetInfo &Target(LPCTSTR t); - static void RemoveAllPlatforms(); - /////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////// // Class used to represent execution parameters (to be passed with request to execute a test) /////////////////////////////////////////////////////////////////////////// class ExecutionParameters { @@ -127,17 +90,18 @@ public: enum RequestType { RUN, QUERY, LOCK, UNLOCK, STOP, RequestTypeMax}; static RequestType RequestTypeValue(LPCTSTR ); - static LPCTSTR Image (RequestType r) { return arRequestImage[r]; } - - Duration ActiveTimeout() const { return m_nActiveTimeout; } - Duration DownloadTimeout() const { return m_nDownloadTimeout; } + static const String Image(RequestType r) { return (r>=0 && r<=RequestTypeMax)?String(arRequestImage[r]):String::SFormat(_T("Unknown(%d)"),r); } - LPCTSTR Target() const { return m_Target.c_str(); } - bool IsValid() const { return m_Request!=RUN || CeCosTest::IsValid(m_Target); } + Duration ActiveTimeout() const { return m_nActiveTimeout; } + Duration DownloadTimeout() const { return m_nDownloadTimeout; } + + const CeCosTestPlatform *Platform() const { return CeCosTestPlatform::Get(m_Target); } + LPCTSTR PlatformName() const { return Platform()?Platform()->Name():_T("UNKNOWN"); } + RequestType Request() const { return m_Request;} - void SetActiveTimeout (Duration t){m_nActiveTimeout=t;} + void SetActiveTimeout (Duration t){m_nActiveTimeout=t;} void SetDownloadTimeout (Duration t){m_nDownloadTimeout=t;} - + ExecutionParameters ( RequestType r=CeCosTest::ExecutionParameters::RUN, LPCTSTR Target=_T(""), @@ -153,9 +117,9 @@ public: String m_Target; Duration m_nActiveTimeout,m_nDownloadTimeout; RequestType m_Request; - int m_nUnused1; - int m_nUnused2; - int m_nUnused3; + int m_nUnused1; + int m_nUnused2; + int m_nUnused3; bool m_bUnused2; bool m_bUnused3; }; @@ -168,35 +132,23 @@ public: enum StatusType {NotStarted, NoResult, Inapplicable, Pass, DownloadTimeOut, TimeOut, Cancelled, Fail, AssertFail, StatusTypeMax}; static StatusType StatusTypeValue (LPCTSTR const pszStr); - static LPCTSTR const Image(StatusType s) { return arResultImage[MIN(s,StatusTypeMax)]; } + static const String Image(StatusType s) { return (s>=0 && sLog(_T("%%%% %s"),psz);} -protected: - static String GetGreatestSubkey (LPCTSTR pszKey); + void GetInferiorCommands (StringArray &arstrInferiorCmds); + CSubprocess *m_pspPipe; + PtrArray m_arpExecsp; + + // Extract a directive (such as "EXEC:") from the test output. The index passed keeps track of the last such + // directive extracted such that successive calls march through the output, returning a different one each time. + bool GetDirective (LPCTSTR pszDirective, String &str,int &nIndex); + + // Keep track of directives in the gdb output + int m_nLastGdbInst; // GDB + int m_nLastExecInst; // EXEC + int m_nLastTimeoutInst; // TIMEOUT + int m_nLastPipeInst; // PIPE + + // Commands to be sent to gdb, or other inferior process + StringArray m_arstrInferiorCmds; + // Last command sent + unsigned int m_nCmdIndex; + + // Inferior process output comes through here + static void CALLBACK SInferiorOutputFunc(void *pParam,LPCTSTR psz) { ((CeCosTest *)pParam)->InferiorOutputFunc(psz); } + void InferiorOutputFunc(LPCTSTR psz); + + // Has a timeout occurred? Returns false if so. + static bool CALLBACK SCheckForTimeout(void *pParam) { return ((CeCosTest *)pParam)->CheckForTimeout(); } + + // Read target ready indicator from server bool GetTargetReady(String &strHostPort); - unsigned int m_nRunCount; - void Interactive(LPCTSTR pszFormat, ...); - + // This may be set to force the socket-to-serial connection to terminate bool m_bStopConnectSocketToSerial; + // Convert a path to one understandable by Cygwin static String CygPath (LPCTSTR pszPath); - CResetAttributes::ResetResult Reset(bool bSendStatus); - void LogTimeStampedOutput(LPCTSTR psz); -#ifndef _WIN32 - bool Suck(LPCTSTR pszPrompt,Duration d=1000); -#endif - bool AtPrompt(LPCTSTR pszPrompt); - bool BreakpointsOperational() const { return TargetInfo::HARDWARE_NO_BP!=Target(Target()).Type(); } - void * m_wPipeHandle; - void * m_rPipeHandle; + + // Are we at a prompt? + bool AtPrompt(); - // For Unix to limit calls to ps: - Time m_tGdbCpuTime; - Time m_tPrevSample; + // To limit calls to ps, under UNIX. This prevents the acquisition of cpu time consuming the whole machine :-). + mutable Time m_tInferiorCpuTime; + mutable Time m_tPrevSample; + Time InferiorTime() const; unsigned int m_nStrippedSize; - void SendKeepAlives(bool &b); - void WaitForRemoteCompletion(); - Time GdbTime(); + + // Path to use to execute subprocesses String m_strPath; - void GetPath(String &strPath); - void SetPath(const String &strPath); - unsigned int m_nFileSize; // Size of executable + // Size of executable + unsigned int m_nFileSize; + // host:port we are connecting to String m_strExecutionHostPort; /////////////////////////////////////////////////////////////////////////// - // Stuff to manage running gdb as child subprocess + // Stuff to manage running gdb (or some other inferior process) bool CheckForTimeout(); // Check for a timeout - set status and return false if it happens bool m_bDownloading; // Are we currently downloading executable? - bool GdbProcessAlive (); // Is gdb still alive and kicking? + bool InferiorProcessAlive (); // Is gdb still alive and kicking? Time m_tBase; // Base used for measurement of timeouts Time m_tBase0; // Base used for measurement of timeouts Time m_tWallClock0; // When the test was actually started - void * m_pGdbProcesshandle; // Handle associated with gdb process -#ifndef _WIN32 - bool WritePipe (const String &str); // Write to gdb process - void DriveGdb(LPCTSTR pszPrompt,const StringArray &arstrGdbCmds); // Run gdb -#endif + /////////////////////////////////////////////////////////////////////////// // Close the socket used by the current class instance void CloseSocket (); @@ -329,11 +292,7 @@ protected: /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// - CeCosTestSocket *m_pSock; - - mutable String m_strResultString; - - LPCTSTR ExecutableTail() const { return CeCosTestUtils::Tail(m_strExecutable); } + CeCosSocket *m_pSock; ExecutionParameters m_ep; @@ -342,7 +301,7 @@ protected: CeCosTest * m_pPrevInstance; CeCosTest * m_pNextInstance; - void RunGdb (LPCTSTR pszCmdline,LPCTSTR pszPrompt,const StringArray &arstrGdbCmds); + void RunInferior (LPCTSTR pszCmdline); bool OutputContains(LPCTSTR psz) const { return 0!=_tcsstr(m_strOutput,psz); } @@ -352,12 +311,6 @@ protected: static void CALLBACK SConnectSocketToSerialThreadFunc(void *pParam) { ((CeCosTest *)pParam)->ConnectSocketToSerialThreadFunc(); } void ConnectSocketToSerialThreadFunc(); - // Stuff. - // Thread function used by RunLocal to execute a non-blocking test locally - void LocalThreadFunc (); - // Thread function used by RunRemote to execute a non-blocking test remotely - void RemoteThreadFunc (); - String m_strExecutable; String m_strTitle; @@ -368,17 +321,21 @@ protected: Duration m_nTotalTime; Duration m_nMaxInactiveTime; - CTestResource * m_pPort; + CTestResource *m_pResource; + CSubprocess *m_psp; - String m_strOutput; - - static std::vector arTargetInfo; - static const TargetInfo tDefault; + String m_strOutput; // the output of the test run goes here static LPCTSTR const arResultImage[1+StatusTypeMax]; static LPCTSTR const arServerStatusImage[1+ServerStatusMax]; bool m_bConnectSocketToSerialThreadDone; static void CALLBACK ResetLogFunc(void *pParam, LPCTSTR psz); + + // These are used by RunAgent and its friends for setting up the RDI connection + int m_nAuxPort; + int m_nAuxListenSock; + + }; // class CeCosTest diff --git a/host/tools/ecostest/common/eCosTestDownloadFilter.cpp b/host/tools/ecostest/common/eCosTestDownloadFilter.cpp --- a/host/tools/ecostest/common/eCosTestDownloadFilter.cpp +++ b/host/tools/ecostest/common/eCosTestDownloadFilter.cpp @@ -53,7 +53,7 @@ #include "eCosStd.h" #include "eCosTrace.h" -#define DL_FILTER_VER "$Id: eCosTestDownloadFilter.cpp,v 1.3 2000/04/07 07:45:09 jlarmour Exp $" +#define DL_FILTER_VER "$Id: eCosTestDownloadFilter.cpp,v 1.4 2000/04/18 21:51:58 jlarmour Exp $" #include "eCosTestDownloadFilter.h" CeCosTestDownloadFilter::CeCosTestDownloadFilter(): @@ -145,7 +145,7 @@ CeCosTestDownloadFilter::PrintHex(const } void -CeCosTestDownloadFilter::TargetWrite(CeCosTestSerial &pSer, +CeCosTestDownloadFilter::TargetWrite(CeCosSerial &pSer, const unsigned char* buffer, int len) { unsigned int __written; @@ -213,7 +213,7 @@ int CeCosTestDownloadFilter::put_binary (unsigned char* buf, int len, unsigned long dl_address, int packet_size, - CeCosTestSerial& serial) + CeCosSerial& serial) { int i; unsigned char csum; @@ -323,7 +323,7 @@ CeCosTestDownloadFilter::put_binary (uns serial.Read(ok_msg, 6, __read); // Reply with ACK - serial.Write("+", 1, __written); + serial.Write((void*)"+", 1, __written); // And process next packet. resend = 0; @@ -353,8 +353,8 @@ CeCosTestDownloadFilter::put_binary (uns bool CALLBACK DownloadFilterFunction(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket, + CeCosSerial& serial, + CeCosSocket& socket, void* pParem) { CeCosTestDownloadFilter* p = (CeCosTestDownloadFilter*) pParem; @@ -376,8 +376,8 @@ DownloadFilterFunction(void*& pBuf, bool CeCosTestDownloadFilter::FilterFunctionProper(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket) + CeCosSerial& serial, + CeCosSocket& socket) { char* buffer = (char*) pBuf; @@ -461,7 +461,7 @@ CeCosTestDownloadFilter::FilterFunctionP // Send + to target, acking whatever packet was pending unsigned int __written = 0; - serial.Write("+", 1, __written); + serial.Write((void*)"+", 1, __written); // Convert to packets and transfer to target. if (put_binary((unsigned char*) buf.Data(), @@ -469,7 +469,7 @@ CeCosTestDownloadFilter::FilterFunctionP // Send detach signal to target unsigned char ch; unsigned int __read; - serial.Write("$D#44", 5, __written); + serial.Write((void*)"$D#44", 5, __written); serial.Read(&ch, 1, __read); // Reply to host marking end of download diff --git a/host/tools/ecostest/common/eCosTestDownloadFilter.h b/host/tools/ecostest/common/eCosTestDownloadFilter.h --- a/host/tools/ecostest/common/eCosTestDownloadFilter.h +++ b/host/tools/ecostest/common/eCosTestDownloadFilter.h @@ -41,8 +41,8 @@ #include "eCosStd.h" #include "eCosTest.h" -#include "eCosTestSocket.h" -#include "eCosTestSerial.h" +#include "eCosSocket.h" +#include "eCosSerial.h" //---------------------------------------------------------------------------- // Macros to help extract values from the argument string. @@ -77,8 +77,8 @@ public: bool FilterFunctionProper(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket); + CeCosSerial& serial, + CeCosSocket& socket); private: // If we can guarantee a minimum buffer size in the stub, we can @@ -94,7 +94,7 @@ private: data_origin_t origin=SF_TARGET); // Target read/write methods - void TargetWrite(CeCosTestSerial &pSer, + void TargetWrite(CeCosSerial &pSer, const unsigned char* buffer, int len); // GDB stuff @@ -102,7 +102,7 @@ private: int hexnumstr(unsigned char* buf, unsigned long num); int hexnumlen(unsigned long num); int put_binary (unsigned char* buf, int cnt, unsigned long dl_address, - int packet_size, CeCosTestSerial& serial); + int packet_size, CeCosSerial& serial); // Options used for configuring behavior. bool m_bNullFilter; @@ -118,8 +118,8 @@ private: extern bool CALLBACK DownloadFilterFunction(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket, + CeCosSerial& serial, + CeCosSocket& socket, void* pParem); #endif // _CECOSDOWNLOADFILTER_H diff --git a/host/tools/ecostest/common/eCosTestMonitorFilter.cpp b/host/tools/ecostest/common/eCosTestMonitorFilter.cpp --- a/host/tools/ecostest/common/eCosTestMonitorFilter.cpp +++ b/host/tools/ecostest/common/eCosTestMonitorFilter.cpp @@ -45,7 +45,7 @@ #include "eCosStd.h" -#define SER_FILTER_VER "$Id: eCosTestMonitorFilter.cpp,v 1.2 2000/04/07 07:45:09 jlarmour Exp $" +#define SER_FILTER_VER "$Id: eCosTestMonitorFilter.cpp,v 1.3 2000/04/18 21:51:58 jlarmour Exp $" #include "eCosTestMonitorFilter.h" CeCosTestMonitorFilter::CeCosTestMonitorFilter(): @@ -138,8 +138,8 @@ CeCosTestMonitorFilter::PrintHex(const u bool CALLBACK SerialMonitorFunction(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket, + CeCosSerial& serial, + CeCosSocket& socket, void* pParem) { CeCosTestMonitorFilter* p = (CeCosTestMonitorFilter*) pParem; diff --git a/host/tools/ecostest/common/eCosTestMonitorFilter.h b/host/tools/ecostest/common/eCosTestMonitorFilter.h --- a/host/tools/ecostest/common/eCosTestMonitorFilter.h +++ b/host/tools/ecostest/common/eCosTestMonitorFilter.h @@ -41,8 +41,8 @@ #include "eCosStd.h" #include "eCosTest.h" -#include "eCosTestSocket.h" -#include "eCosTestSerial.h" +#include "eCosSocket.h" +#include "eCosSerial.h" //---------------------------------------------------------------------------- // The filter class @@ -82,8 +82,8 @@ private: extern bool CALLBACK SerialMonitorFunction(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket, + CeCosSerial& serial, + CeCosSocket& socket, void* pParem); #endif // _CECOSMONITORFILTER_H diff --git a/host/tools/ecostest/common/eCosTestPlatform.cpp b/host/tools/ecostest/common/eCosTestPlatform.cpp new file mode 100644 --- /dev/null +++ b/host/tools/ecostest/common/eCosTestPlatform.cpp @@ -0,0 +1,272 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//================================================================= +// +// eCosTestPlatform.cpp +// +// platform information implementation +// +//================================================================= +#include "eCosTestPlatform.h" +#include "eCosTestUtils.h" +#include "eCosTrace.h" + +std::vector CeCosTestPlatform::arPlatforms; + +const CeCosTestPlatform *CeCosTestPlatform::Get(LPCTSTR psz) +{ + for(int i=0;i<(signed)arPlatforms.size();i++){ + const CeCosTestPlatform &t=arPlatforms[i]; + if(0==_tcsicmp(t.Name(),psz)){ + return &t; + } + } + return NULL; +} + +CeCosTestPlatform::CeCosTestPlatformProperties::CeCosTestPlatformProperties(CeCosTestPlatform *pti) +{ + Add(_T("platform"),pti->m_strName); + Add(_T("prefix"), pti->m_strPrefix); + Add(_T("commands"),pti->m_strCommands); + Add(_T("inferior"),pti->m_strInferior); + Add(_T("prompt"), pti->m_strPrompt); + Add(_T("ServerSideGdb"),pti->m_nServerSideGdb); +} + +bool CeCosTestPlatform::LoadFromDir(LPCTSTR pszDir) +{ + bool rc=true; + TRACE(_T("CeCosTestPlatform::LoadFromDir %s\n"),pszDir); + // Find all the files in directory pszDir and load from each of them + TCHAR szOrigDir[256]; + _tgetcwd(szOrigDir,sizeof szOrigDir-1); + if(0==_tchdir(pszDir)){ + String strFile; + void *pHandle; + for(bool b=CeCosTestUtils::StartSearch(pHandle,strFile);b;b=CeCosTestUtils::NextFile(pHandle,strFile)){ + if(CeCosTestUtils::IsFile(strFile)){ + CeCosTestPlatform t; + t.m_strName=strFile; + CeCosTestPlatformProperties prop(&t); + if(prop.LoadFromFile(strFile)){ + Add(t); + } else { + ERROR(_T("Illegal platform specification in %s%c%s\n"),pszDir,cPathsep,(LPCTSTR)strFile); + rc=false; + } + } + } + CeCosTestUtils::EndSearch(pHandle); + } else { + ERROR(_T("Failed to change to %s from %s\n"),pszDir,szOrigDir); + } + _tchdir(szOrigDir); + + return rc; +} + +#ifdef _WIN32 +bool CeCosTestPlatform::SaveToRegistry(HKEY hTopKey,LPCTSTR pszKey) +{ + // save target info to the registry + + CProperties::CreateKey(pszKey,hTopKey); + HKEY hKey; + bool rc=ERROR_SUCCESS==RegOpenKeyEx (hTopKey, pszKey, 0L, KEY_ALL_ACCESS, &hKey); + if(rc){ + for(int i=0;i<(signed)arPlatforms.size();i++){ + HKEY hKey2; + DWORD dwDisp; + const CeCosTestPlatform &ti=arPlatforms[i]; + rc&=(ERROR_SUCCESS==RegCreateKeyEx(hKey,ti.Name(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey2, &dwDisp)); + if(rc){ + LPCTSTR pszPrefix=ti.Prefix(); + LPCTSTR pszGdb =ti.GdbCmds(); + rc&=(ERROR_SUCCESS==RegSetValueEx(hKey2,_T("Prefix"),0,REG_SZ, (CONST BYTE *)pszPrefix,(1+_tcslen(pszPrefix))*sizeof TCHAR)) && + (ERROR_SUCCESS==RegSetValueEx(hKey2,_T("GdbCmd"),0,REG_SZ, (CONST BYTE *)pszGdb,(1+_tcslen(pszGdb))*sizeof TCHAR)); + } + RegCloseKey(hKey2); + } + RegCloseKey(hKey); + } + return rc; +} + +const String CeCosTestPlatform::GetGreatestSubkey (LPCTSTR pszKey) +{ + String strSubkey; + HKEY hKey; + + if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, pszKey, 0L, KEY_READ, &hKey)) { + DWORD dwIndex = 0; + TCHAR pszBuffer [MAX_PATH + 1]; + + while (ERROR_SUCCESS == RegEnumKey (hKey, dwIndex++, (LPTSTR) pszBuffer, sizeof (pszBuffer))) { + if (strSubkey.compare (pszBuffer) < 0) { + strSubkey = pszBuffer; + } + } + + RegCloseKey (hKey); + } + + TRACE (_T("CeCosTestPlatform::GetGreatestSubkey(\"%s\"): %s\n"), pszKey, (LPCTSTR)strSubkey); + return strSubkey; +} +#endif + +bool CeCosTestPlatform::Load() +{ + TRACE(_T("CeCosTestPlatform::Load\n")); + srand( (unsigned)time( NULL ) ); + +#ifdef _WIN32 + + // get target info from the registry + String strPlatformsKey = _T("Software\\Red Hat\\eCos\\"); + strPlatformsKey += GetGreatestSubkey (_T("Software\\Red Hat\\eCos")); + strPlatformsKey += _T("\\Platforms"); + + HKEY hKey; + bool rc=ERROR_SUCCESS==RegOpenKeyEx (HKEY_LOCAL_MACHINE, strPlatformsKey, 0L, KEY_READ, &hKey); + DWORD dwSubKeys=0; + if(rc){ + // Found the given key. + // Subkeys' names are the target image names: + // Subkeys's values are: + // Prefix String + // Type String + // GdbCmd String [optional] + FILETIME ftLastWriteTime; + DWORD dwMaxSubKeyLen; + if(ERROR_SUCCESS==RegQueryInfoKey(hKey,NULL,NULL,NULL,&dwSubKeys,&dwMaxSubKeyLen,NULL,NULL,NULL,NULL,NULL,NULL)){ + TCHAR *szName=new TCHAR[1+dwMaxSubKeyLen]; + DWORD dwSizeName=dwMaxSubKeyLen; + for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumKeyEx(hKey, dwIndex, szName, &dwSizeName, NULL, NULL, NULL, &ftLastWriteTime); dwIndex++){ + CeCosTestPlatform t; + if(t.LoadFromRegistry(hKey,szName)){ + t.m_strName=szName; + CeCosTestPlatform::Add(t); + } + dwSizeName=dwMaxSubKeyLen; + } + delete [] szName; + } + RegCloseKey(hKey); + } +#endif + const String strDir(CeCosTestUtils::HomeFile(_T(".eCosPlatforms"))); +#ifdef _WIN32 + if(!CeCosTestUtils::Exists(strDir)){ + return rc; + } +#endif + LoadFromDir(strDir); + if(0==Count()){ + ERROR(_T("Failed to initialize any targets\n")); + } + return true; +} + +int CeCosTestPlatform::Add(const CeCosTestPlatform &t) +{ + for(std::vector::iterator it=arPlatforms.begin();it!=arPlatforms.end();){ + if(0==_tcsicmp(it->Name(),t.Name())){ + // Careful - there's already something here with this name: + ERROR(_T("Warning: duplicate target info %s\n"),it->Name()); + it=arPlatforms.erase(it); + } else { + it++; + } + } + arPlatforms.push_back(t); + return arPlatforms.size()-1; +} + +void CeCosTestPlatform::RemoveAllPlatforms() +{ + arPlatforms.clear(); +} + +bool CeCosTestPlatform::LoadFromCommandString(LPCTSTR psz) +{ + CeCosTestPlatformProperties prop(this); + return prop.LoadFromCommandString(psz); +} + +#ifdef _WIN32 +bool CeCosTestPlatform::LoadFromRegistry(HKEY hKey,LPCTSTR pszKey) +{ + CeCosTestPlatformProperties prop(this); + return prop.LoadFromRegistry(hKey,pszKey); +} +#endif + +bool CeCosTestPlatform::Save() +{ + const String strDir(CeCosTestUtils::HomeFile(_T(".eCosPlatforms"))); +#ifdef _WIN32 + if(!CeCosTestUtils::Exists(strDir)){ + String strPlatformsKey = _T("Software\\Red Hat\\eCos\\"); + strPlatformsKey += GetGreatestSubkey (_T("Software\\Red Hat\\eCos")); + strPlatformsKey += _T("\\Platforms"); + + return SaveToRegistry(HKEY_LOCAL_MACHINE,strPlatformsKey); + } +#endif + return SaveToDir(strDir); +} + +bool CeCosTestPlatform::SaveToDir (LPCTSTR pszDir) +{ + bool rc=false; + void *pHandle; + TCHAR szOrigDir[256]; + _tgetcwd(szOrigDir,sizeof szOrigDir-1); + if(0==_tchdir(pszDir)){ + // Delete all the files under directory "pszDir" + String strFile; + for(bool b=CeCosTestUtils::StartSearch(pHandle,strFile);b;b=CeCosTestUtils::NextFile(pHandle,strFile)){ + if(CeCosTestUtils::IsFile(strFile)){ + _tunlink(strFile); + } + } + CeCosTestUtils::EndSearch(pHandle); + rc=true; + // Rewrite the files + for(int i=0;i<(signed)arPlatforms.size();i++){ + CeCosTestPlatform &t=arPlatforms[i]; + CeCosTestPlatformProperties prop(&t); + rc&=prop.SaveToFile(t.Name()); + } + } else { + ERROR(_T("Failed to change to %s from %s\n"),pszDir,szOrigDir); + } + + return rc; +} + + diff --git a/host/tools/ecostest/common/eCosTestPlatform.h b/host/tools/ecostest/common/eCosTestPlatform.h new file mode 100644 --- /dev/null +++ b/host/tools/ecostest/common/eCosTestPlatform.h @@ -0,0 +1,118 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// This program is part of the eCos host tools. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ---------------------------------------------------------------------------- +// +//####COPYRIGHTEND#### +//================================================================= +// +// eCosTestPlatform.h +// +// platform information header +// +//================================================================= +//================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contributors: sdf +// Date: 2000-04-01 +// Description: eCosTestPlatform +// Usage: +// +//####DESCRIPTIONEND#### + +#ifndef _CeCosTestPlatform_H +#define _CeCosTestPlatform_H + +#include "eCosStd.h" +#include "Collections.h" +#include "Properties.h" +#include + +//================================================================= +// This class holds properties associated with a platform type (i.e. common to all instances of that platform) +// The information is read from a .eCosrc file or from the registry. +// An instance of a platform corresponds to the class CTestResource. +//================================================================= + +class CeCosTestPlatform { + class CeCosTestPlatformProperties : public CProperties { + public: + CeCosTestPlatformProperties(CeCosTestPlatform *pti); + virtual ~CeCosTestPlatformProperties(){} + protected: + }; + friend class CeCosTestPlatformProperties; +public: + + static bool Load(); + static bool Save(); + + bool IsValid() const { return NULL!=Get(m_strName); } + LPCTSTR Name() const { return m_strName.c_str(); } + LPCTSTR Prefix() const { return m_strPrefix.c_str(); } + LPCTSTR GdbCmds() const { return m_strCommands.c_str(); } + LPCTSTR Prompt() const { return m_strPrompt.c_str(); } + LPCTSTR Inferior()const { return m_strInferior.c_str(); } + bool ServerSideGdb() const { return 0!=m_nServerSideGdb; } + CeCosTestPlatform():m_nServerSideGdb(0){} + bool LoadFromCommandString(LPCTSTR psz); + CeCosTestPlatform(LPCTSTR pszIm,LPCTSTR pszPre,LPCTSTR pszPrompt,LPCTSTR pszGdb,bool bServerSideGdb,LPCTSTR pszInferior): + m_strName(pszIm), + m_strPrefix(pszPre), + m_strCommands(pszGdb), + m_strPrompt(pszPrompt), + m_nServerSideGdb(bServerSideGdb), + m_strInferior(pszInferior) + {} + static int Add (const CeCosTestPlatform &t); + + static unsigned int Count() { return (unsigned)arPlatforms.size(); } + + // Get a platform by name: + static const CeCosTestPlatform *Get(LPCTSTR t); + + // This is only used to enumerate the available platforms: + static const CeCosTestPlatform *Get(unsigned int i) { return (i arPlatforms; +}; + +#endif diff --git a/host/tools/ecostest/common/eCosTestSerial.cpp b/host/tools/ecostest/common/eCosTestSerial.cpp deleted file mode 100644 --- a/host/tools/ecostest/common/eCosTestSerial.cpp +++ /dev/null @@ -1,557 +0,0 @@ -//####COPYRIGHTBEGIN#### -// -// ---------------------------------------------------------------------------- -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// -// This program is part of the eCos host tools. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// ---------------------------------------------------------------------------- -// -//####COPYRIGHTEND#### -//================================================================= -// -// eCosTestSerial.cpp -// -// Serial test class -// -//================================================================= -//================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): sdf -// Contributors: sdf -// Date: 1999-04-01 -// Description: This class abstracts the serial port for use in the testing infrastructure -// Usage: -// -//####DESCRIPTIONEND#### - -#include "eCosStd.h" -#include "eCosTestSerial.h" -#include "eCosTrace.h" - -CeCosTestSerial::CeCosTestSerial(): - m_nErr(0), - m_pHandle(0), - m_nDataBits(8), - m_nStopBits(ONE_STOP_BIT), - m_bParity(false), - m_nBaud(0), - m_nTotalReadTimeout(10*1000), - m_nTotalWriteTimeout(10*1000), - m_nInterCharReadTimeout(500), - m_nInterCharWriteTimeout(500), - m_bBlockingReads(true) -{ -} - -CeCosTestSerial::~CeCosTestSerial() -{ - Close(); -} - -CeCosTestSerial::CeCosTestSerial(LPCTSTR pszPort,int nBaud): - m_nErr(0), - m_pHandle(0), - m_nDataBits(8), - m_nStopBits(ONE_STOP_BIT), - m_bParity(false), - m_nTotalReadTimeout(10*1000), - m_nTotalWriteTimeout(10*1000), - m_nInterCharReadTimeout(500), - m_nInterCharWriteTimeout(500), - m_bBlockingReads(true) -{ - Open(pszPort,nBaud); -} - -bool CeCosTestSerial::SetBlockingReads(bool b,bool bApplySettingsNow/*=true*/) -{ - m_bBlockingReads=b; - return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); -} - -bool CeCosTestSerial:: SetBaud(unsigned int nBaud,bool bApplySettingsNow/*=true*/) -{ - m_nBaud=nBaud; - return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); -} - -bool CeCosTestSerial:: SetParity(bool bParityOn,bool bApplySettingsNow/*=true*/) -{ - m_bParity=bParityOn; - return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); -} - -bool CeCosTestSerial:: SetDataBits(int n,bool bApplySettingsNow/*=true*/) -{ - m_nDataBits=n; - return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); -} - -bool CeCosTestSerial:: SetStopBits(StopBitsType n,bool bApplySettingsNow/*=true*/) -{ - m_nStopBits=n; - return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); -} - -bool CeCosTestSerial:: SetReadTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow/*=true*/) // mSec -{ - m_nTotalReadTimeout=nTotal; - m_nInterCharReadTimeout=nBetweenChars; - - return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); -} - -bool CeCosTestSerial:: SetWriteTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow/*=true*/) // mSec -{ - m_nTotalWriteTimeout=nTotal; - m_nInterCharWriteTimeout=nBetweenChars; - return 0==m_pHandle || !bApplySettingsNow || ApplySettings(); -} -/* -bool CeCosTestSerial::Read (String &str) -{ -TCHAR *c=str.GetBuffer(); -unsigned int nRead=0; -bool rc=Read(c,str.GetLength(),nRead); -c[nRead]=_TCHAR('\0'); -str.ReleaseBuffer(); -return rc; -} - - bool CeCosTestSerial::Write(const String &str) - { - unsigned int nWritten=0; - return Write((void *)(LPCTSTR)str,str.GetLength(),nWritten) && nWritten==str.GetLength(); - } -*/ -#ifdef _WIN32 -bool CeCosTestSerial::Open(LPCTSTR pszPort,int nBaud) -{ - bool rc=false; - m_nBaud=nBaud, - m_strPort=pszPort; - HANDLE hCom=::CreateFile(pszPort,GENERIC_READ|GENERIC_WRITE, 0,NULL,OPEN_EXISTING,0,NULL); - SaveError(); - if (INVALID_HANDLE_VALUE==hCom) { - ERROR(_T("Failed to open port %s - %s\n"),pszPort,(LPCTSTR)ErrString()); - } else { - m_pHandle=(void *)hCom; - if(ApplySettings()){ - Flush(); - rc=true; - } else { - Close(); - } - } - return rc; -} - -bool CeCosTestSerial::Close() -{ - bool rc=false; - if(m_pHandle){ - try { - rc=(TRUE==CloseHandle((HANDLE)m_pHandle)); - } - catch(...) { - TRACE(_T("!!! Exception caught closing serial handle %08x\n"),m_pHandle); - } - m_pHandle=0; - } else { - rc=true; - } - return rc; -} - -bool CeCosTestSerial::ApplySettings() -{ - bool rc=false; - try { - DCB dcb; - - ZeroMemory(&dcb,sizeof dcb); - dcb.DCBlength=sizeof dcb; - dcb.BaudRate=m_nBaud; - dcb.fBinary=true; - dcb.fParity=true; - dcb.Parity=(BYTE) ((m_bParity) ? EVENPARITY : NOPARITY); - dcb.StopBits=(BYTE)m_nStopBits; - dcb.ByteSize=(BYTE)m_nDataBits; - LPCTSTR arpszStopbits[3]={_T("1"),_T("1.5"),_T("2")}; - TRACE(_T("Applysettings baud=%d Parity=%d stopbits=%s databits=%d\n"), - dcb.BaudRate, - dcb.Parity, - arpszStopbits[dcb.StopBits], - dcb.ByteSize); - - // No control over the following yet - dcb.fDtrControl=DTR_CONTROL_ENABLE; - dcb.fTXContinueOnXoff=1; - dcb.fRtsControl=RTS_CONTROL_ENABLE; - dcb.fAbortOnError=1; - dcb.XonLim=2048; - dcb.XoffLim=512; - dcb.XonChar=17; - dcb.XoffChar=19; - - HANDLE hCom=(HANDLE)m_pHandle; - if (!SetCommState(hCom, &dcb)) { - SaveError(); - ERROR(_T("Failed to set comm state - port %s handle=%d err=%d\n"),(LPCTSTR)m_strPort,hCom,GetLastError()); - } else { - COMMTIMEOUTS commtimeouts; - if(m_bBlockingReads){ - commtimeouts.ReadIntervalTimeout=m_nInterCharReadTimeout; - commtimeouts.ReadTotalTimeoutMultiplier=0; - commtimeouts.ReadTotalTimeoutConstant=m_nTotalReadTimeout; - } else { - commtimeouts.ReadIntervalTimeout=MAXDWORD; - commtimeouts.ReadTotalTimeoutMultiplier=0; - commtimeouts.ReadTotalTimeoutConstant=0; - } - commtimeouts.WriteTotalTimeoutMultiplier=m_nTotalWriteTimeout; - commtimeouts.WriteTotalTimeoutConstant=m_nInterCharWriteTimeout; - - if (SetCommTimeouts(hCom, &commtimeouts)) { - rc=true; - } else { - SaveError(); - ERROR(_T("Failed to set comm timeouts - port %s\n"),(LPCTSTR)m_strPort); - } - } - } - catch(...) - { - TRACE(_T("!!! Exception caught in CeCosTestSerial::ApplySettings!!!\n")); - } - return rc; -} - -bool CeCosTestSerial::Read (void *pBuf,unsigned int nSize,unsigned int &nRead) -{ - bool rc=(TRUE==ReadFile((HANDLE)m_pHandle,pBuf,nSize,(LPDWORD)&nRead,0)); - SaveError(); - return rc; -} - -bool CeCosTestSerial::Write(void *pBuf,unsigned int nSize,unsigned int &nWritten) -{ - bool rc=(TRUE==WriteFile((HANDLE)m_pHandle,pBuf,nSize,(LPDWORD)&nWritten,0)); - SaveError(); - return rc; -} - -bool CeCosTestSerial::ClearError() -{ - DWORD dwErrors; - bool rc=(TRUE==ClearCommError(HANDLE(m_pHandle),&dwErrors,0)); - if(dwErrors&CE_BREAK)TRACE(_T("The hardware detected a break condition.\n")); - if(dwErrors&CE_DNS)TRACE(_T("Windows 95 and Windows 98: A parallel device is not selected.\n")); - if(dwErrors&CE_FRAME)TRACE(_T("The hardware detected a framing error.\n")); - if(dwErrors&CE_IOE)TRACE(_T("An I/O error occurred during communications with the device.\n")); - if(dwErrors&CE_MODE)TRACE(_T("The requested mode is not supported, or the hFile parameter is invalid. If this value is specified, it is the only valid error.\n")); - if(dwErrors&CE_OOP)TRACE(_T("Windows 95 and Windows 98: A parallel device signaled that it is out of paper.\n")); - if(dwErrors&CE_OVERRUN)TRACE(_T("A character-buffer overrun has occurred. The next character is lost.\n")); - if(dwErrors&CE_PTO)TRACE(_T("Windows 95 and Windows 98: A time-out occurred on a parallel device.\n")); - if(dwErrors&CE_RXOVER)TRACE(_T("An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.\n")); - if(dwErrors&CE_RXPARITY)TRACE(_T("The hardware detected a parity error.\n")); - if(dwErrors&CE_TXFULL)TRACE(_T("The application tried to transmit a character, but the output buffer was full.\n")); - return rc; -} - -bool CeCosTestSerial::Flush (void) -{ - bool rc=(TRUE==PurgeComm ((HANDLE)m_pHandle,PURGE_TXCLEAR|PURGE_RXCLEAR)); - SaveError(); - return rc; -} - -String CeCosTestSerial::ErrString() -{ - String str; - LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - m_nErr, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - str=(LPCTSTR)lpMsgBuf; - // Free the buffer. - LocalFree( lpMsgBuf ); - return str; -} - -#else // UNIX - -String CeCosTestSerial::ErrString() -{ - return strerror(errno); -} - -bool CeCosTestSerial::Close() -{ - bool rc=m_pHandle && (-1!=close((int)m_pHandle)); - m_pHandle=0; - return rc; -} - -bool CeCosTestSerial::Open(LPCTSTR pszPort,int nBaud) -{ - bool rc=false; - m_nBaud=nBaud, - m_strPort=pszPort; - int fd = open(pszPort,O_RDWR|O_NONBLOCK); - if (-1==fd) { - ERROR(_T("Failed to open port %s\n"),pszPort); - return false; - } else { - m_pHandle=(void *)fd; - if(ApplySettings()){ - rc=true; - } else { - Close(); - ERROR(_T("Failed to apply settings.\n")); - return false; - } - } - return rc; -} - -bool CeCosTestSerial::ApplySettings() -{ - struct termios buf, buf_verify; - int rate; - - // Clear the two structures so we can make a binary comparison later on. - memset(&buf, 0, sizeof(buf)); - memset(&buf_verify, 0, sizeof(buf_verify)); - - LPCTSTR arpszStopbits[3]={_T("1"),_T("1.5"),_T("2")}; - TRACE(_T("Applysettings baud=%d bParity=%d stopbits=%s databits=%d\n"), - m_nBaud, - m_bParity, - arpszStopbits[m_nStopBits], - m_nDataBits); - - switch(m_nBaud) { - case 110: - rate = B110; - break; - case 150: - rate = B150; - break; - case 300: - rate = B300; - break; - case 600: - rate = B600; - break; - case 1200: - rate = B1200; - break; - case 2400: - rate = B2400; - break; - case 4800: - rate = B4800; - break; - case 9600: - rate = B9600; - break; - case 19200: - rate = B19200; - break; - case 38400: - rate = B38400; - break; - case 57600: - rate = B57600; - break; - case 115200: - rate = B115200; - break; - default: - return false; - }; - - TRACE(_T("Changing configuration...\n")); - - // Get current settings. - if (tcgetattr((int) m_pHandle, &buf)) { - fprintf(stderr, _T("Error: tcgetattr\n")); - return false; - } - - // Reset to raw. - buf.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP - |INLCR|IGNCR|ICRNL|IXON); - buf.c_oflag &= ~OPOST; - buf.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - buf.c_cflag &= ~(CSIZE|PARENB); - buf.c_cflag |= CS8; - - // Set baud rate. - cfsetispeed(&buf, rate); - cfsetospeed(&buf, rate); - - // Set data bits. - { - int data_bits[9] = {0, 0, 0, 0, 0, CS5, CS6, CS7, CS8}; - - buf.c_cflag &= ~CSIZE; - buf.c_cflag |= data_bits[m_nDataBits]; - } - - // Set stop bits. - { - buf.c_cflag &= ~CSTOPB; - if (ONE_STOP_BIT != m_nStopBits) - buf.c_cflag |= CSTOPB; - } - - // Set parity. - { - buf.c_cflag &= ~(PARENB | PARODD); // no parity. - if (m_bParity) // even parity. - buf.c_cflag |= PARENB; - } - - // Set the new settings - if (tcsetattr((int) m_pHandle, TCSADRAIN, &buf)) { - fprintf(stderr, _T("Error: tcsetattr\n")); - return false; - } - - // Now read back the settings. On SunOS tcsetattr only returns - // error if _all_ settings fail. If just a few settings are not - // supported, the call returns true while the hardware is set to a - // combination of old and new settings. - if (tcgetattr((int) m_pHandle, &buf_verify)) { - fprintf(stderr, _T("Error: tcgetattr\n")); - return false; - } - if (memcmp(&buf, &buf_verify, sizeof(buf))) { - fprintf(stderr, _T("Error: termios verify failed\n")); - return false; - } - - // A slight delay to allow things to settle. - Sleep(10); - - TRACE(_T("Done.\n")); - - return true; -} - -bool CeCosTestSerial::Flush (void) -{ - return 0==tcflush((int) m_pHandle, TCIOFLUSH); -} - -bool CeCosTestSerial::Read (void *pBuf,unsigned int nSize,unsigned int &nRead) -{ - - if (!m_bBlockingReads) { - nRead = 0; - int n = read((int)m_pHandle, pBuf, nSize); - if (-1 == n) { - if (EAGAIN == errno) - return true; - ERROR(_T("Read failed: %d\n"), errno); - return false; - } - nRead = n; - return true; - } - - // Blocking reads: emulate the Windows semantics: - // If m_nTotalReadTimeout elapses before we see the first TCHAR, - // return. - // If m_nInterCharReadTimeout elapses after reading any - // subsequent TCHAR, return. - - fd_set rfds; - FD_ZERO(&rfds); - FD_SET((int)m_pHandle, &rfds); - - // Start with total timeout. - struct timeval tv; - tv.tv_sec = m_nTotalReadTimeout / 1000; - tv.tv_usec = (m_nTotalReadTimeout % 1000) * 1000; - - unsigned char* pData = (unsigned char*) pBuf; - nRead = 0; - while (nSize) { - switch(select((int)m_pHandle + 1, &rfds, NULL, NULL, &tv)) { - case 1: - { - int n = read((int)m_pHandle, pData, nSize); - if (-1 == n && EAGAIN != errno) { - ERROR(_T("Read failed: %d\n"), errno); - return false; // FAILED - } - nRead += n; - pData += n; - nSize -= n; - - // Now use inter-char timeout. - tv.tv_sec = m_nInterCharReadTimeout / 1000; - tv.tv_usec = (m_nInterCharReadTimeout % 1000) * 1000; - } - break; - case 0: - return true; // Timeout - case -1: - ERROR(_T("Select failed: %d\n"), errno); - return false; - } - } - - return true; -} - -bool CeCosTestSerial::Write(void *pBuf,unsigned int nSize,unsigned int &nWritten) -{ - bool rc; - int n=write((int)m_pHandle,pBuf,nSize); - if(-1==n){ - nWritten=0; - if (errno == EAGAIN) - rc = true; - else - rc=false; - } else { - nWritten=n; - rc=true; - } - return rc; -} - -bool CeCosTestSerial::ClearError() -{ - return false; -} - -#endif diff --git a/host/tools/ecostest/common/eCosTestSerial.h b/host/tools/ecostest/common/eCosTestSerial.h deleted file mode 100644 --- a/host/tools/ecostest/common/eCosTestSerial.h +++ /dev/null @@ -1,123 +0,0 @@ -//####COPYRIGHTBEGIN#### -// -// ---------------------------------------------------------------------------- -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// -// This program is part of the eCos host tools. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// ---------------------------------------------------------------------------- -// -//####COPYRIGHTEND#### -//================================================================= -// -// eCosTestSerial.h -// -// Serial test class -// -//================================================================= -//================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): sdf -// Contributors: sdf -// Date: 1999-04-01 -// Description: This class abstracts the serial port for use in the testing infrastructure -// Usage: -// -// -//####DESCRIPTIONEND#### - -#ifndef _CECOSSERIAL_H -#define _CECOSSERIAL_H -#include "eCosStd.h" -#include "eCosTestSocket.h" -#include "Collections.h" - -class CeCosTestSerial { - friend int CeCosTestSocket::SSRead (CeCosTestSerial &serial,CeCosTestSocket &socket,void *pBuf,unsigned int nSize,unsigned int &nRead,bool *pbStop); - -public: - enum StopBitsType { ONE_STOP_BIT, ONE_POINT_FIVE_STOP_BITS, TWO_STOP_BITS }; - CeCosTestSerial(LPCTSTR pszPort,int nBaud); // ctor and open all in one go - CeCosTestSerial(); // Call Open() later - virtual ~CeCosTestSerial(); // Call Open() later - - bool Open(LPCTSTR pszPort,int nBaud); - - // Set various line characteristics. This can be done with the line open or closed. - bool SetBaud(unsigned int nBaud,bool bApplySettingsNow=true); - bool SetParity(bool bParityOn,bool bApplySettingsNow=true); - bool SetDataBits(int n,bool bApplySettingsNow=true); - bool SetStopBits(StopBitsType n,bool bApplySettingsNow=true); - bool SetReadTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow=true); // mSec - bool SetWriteTimeOuts(int nTotal,int nBetweenChars,bool bApplySettingsNow=true); // mSec - - bool ApplySettings(); - - // Get them: - int GetParity() const { return m_bParity; } - int GetDataBits() const { return m_nDataBits; } - StopBitsType GetStopBits() const { return m_nStopBits; } - unsigned int GetBaud() const { return m_nBaud; } - bool GetReadTimeOuts(int &nTotal,int &nBetweenChars) const {nTotal=m_nTotalReadTimeout; nBetweenChars=m_nInterCharReadTimeout; return true; }// mSec - bool GetWriteTimeOuts(int &nTotal,int &nBetweenChars) const {nTotal=m_nTotalWriteTimeout; nBetweenChars=m_nInterCharWriteTimeout; return true; }// mSec - bool GetBlockingReads() const { return m_bBlockingReads; } - bool Close(); - - bool Flush (void); - - // Use to test success after open ctor - bool Ok() { return 0!=m_pHandle; } - - // Will read up to the length provided: - bool Read (void *pBuf,unsigned int nSize,unsigned int &nRead); - bool Write(void *pBuf,unsigned int nSize,unsigned int &nWritten); - - //Removed, as dangerous when using UNICODE: - //bool Read (String &str); - //bool Write(const String &str); - - // Use in the event of an error that needs to be cleared before the next operation: - bool ClearError(); - - bool SetBlockingReads(bool b,bool bApplySettingsNow=true); - - int Error() { return m_nErr; } - // Return last socket error, translated to a string - String ErrString(); - -protected: - int m_nErr; - void SaveError() { - #ifdef _WIN32 - m_nErr=WSAGetLastError(); - #else // UNIX - m_nErr=errno; - #endif - } - - void *m_pHandle; - int m_nDataBits; - StopBitsType m_nStopBits; - bool m_bParity; - unsigned int m_nBaud; - int m_nTotalReadTimeout,m_nTotalWriteTimeout; - int m_nInterCharReadTimeout,m_nInterCharWriteTimeout; - bool m_bBlockingReads; - String m_strPort; -}; -#endif diff --git a/host/tools/ecostest/common/eCosTestSerialFilter.cpp b/host/tools/ecostest/common/eCosTestSerialFilter.cpp --- a/host/tools/ecostest/common/eCosTestSerialFilter.cpp +++ b/host/tools/ecostest/common/eCosTestSerialFilter.cpp @@ -51,8 +51,9 @@ #include "eCosStd.h" -#define SER_FILTER_VER "$Id: eCosTestSerialFilter.cpp,v 1.3 2000/04/07 07:45:09 jlarmour Exp $" +#define SER_FILTER_VER "$Id: eCosTestSerialFilter.cpp,v 1.4 2000/04/18 21:51:58 jlarmour Exp $" #include "eCosTestSerialFilter.h" +#include "eCosThreadUtils.h" char msg_ok[] = "OK"; char msg_er[] = "ER"; @@ -229,7 +230,7 @@ CeCosTestSerialFilter::PrintHex(const un } void -CeCosTestSerialFilter::TargetWrite(CeCosTestSerial &pSer, +CeCosTestSerialFilter::TargetWrite(CeCosSerial &pSer, const unsigned char* buffer, int len) { unsigned int __written; @@ -251,7 +252,7 @@ CeCosTestSerialFilter::TargetWrite(CeCos bool -CeCosTestSerialFilter::TargetRead(CeCosTestSerial &pSer, +CeCosTestSerialFilter::TargetRead(CeCosSerial &pSer, unsigned char* buffer, int len) { unsigned int __read; @@ -312,7 +313,7 @@ CeCosTestSerialFilter::TargetRead(CeCosT } if (0 == __read) { - Sleep(20); + CeCosThreadUtils::Sleep(20); __timeouts++; if (25 == __timeouts) { __timeouts = 0; @@ -350,7 +351,7 @@ CeCosTestSerialFilter::TargetRead(CeCosT // Send C ASCII string to target. void -CeCosTestSerialFilter::TargetASCIIWrite(CeCosTestSerial &pSer, const char* s) +CeCosTestSerialFilter::TargetASCIIWrite(CeCosSerial &pSer, const char* s) { TargetWrite(pSer, (const unsigned char*) s, strlen(s)); } @@ -359,7 +360,7 @@ CeCosTestSerialFilter::TargetASCIIWrite( // Configuration Command. // Set serial configuration. bool -CeCosTestSerialFilter::SetConfig(CeCosTestSerial &pSer, +CeCosTestSerialFilter::SetConfig(CeCosSerial &pSer, const ser_cfg_t* new_cfg, ser_cfg_t* old_cfg) { @@ -378,7 +379,7 @@ CeCosTestSerialFilter::SetConfig(CeCosTe // Return false if the serial configuration is not valid for the host. bool -CeCosTestSerialFilter::VerifyConfig(CeCosTestSerial &pSer, ser_cfg_t* new_cfg) +CeCosTestSerialFilter::VerifyConfig(CeCosSerial &pSer, ser_cfg_t* new_cfg) { ser_cfg_t old_cfg; bool rc; @@ -427,7 +428,7 @@ CeCosTestSerialFilter::VerifyConfig(CeCo // Host&protocol currently only supports: // - no/even parity void -CeCosTestSerialFilter::CMD_ChangeConfig(CeCosTestSerial &pSer, char* cfg_str) +CeCosTestSerialFilter::CMD_ChangeConfig(CeCosSerial &pSer, char* cfg_str) { ser_cfg_t new_cfg, old_cfg; @@ -442,7 +443,7 @@ CeCosTestSerialFilter::CMD_ChangeConfig( // Tell target we're ready to go, wait 1/10 sec, and then change // the config. TargetASCIIWrite(pSer, "OK"); - Sleep(100); + CeCosThreadUtils::Sleep(100); SetConfig(pSer, &new_cfg, &old_cfg); int loops; @@ -491,7 +492,7 @@ CeCosTestSerialFilter::CMD_ChangeConfig( TargetASCIIWrite(pSer, "S"); } - Sleep(1); + CeCosThreadUtils::Sleep(1); delay_mticks++; // Timeout. if (100 == delay_mticks/10) @@ -516,11 +517,11 @@ CeCosTestSerialFilter::CMD_ChangeConfig( // Set default configuration. void -CeCosTestSerialFilter::CMD_DefaultConfig(CeCosTestSerial &pSer) +CeCosTestSerialFilter::CMD_DefaultConfig(CeCosSerial &pSer) { static const ser_cfg_t default_ser_cfg = { 9600, 8, - CeCosTestSerial::ONE_STOP_BIT, + CeCosSerial::ONE_STOP_BIT, false }; TargetASCIIWrite(pSer, "OK"); @@ -534,10 +535,10 @@ void CeCosTestSerialFilter::ParseConfig(char* args, ser_cfg_t* new_cfg) { int ecos_parity, ecos_stop_bits, ecos_baud_rate; - CeCosTestSerial::StopBitsType t2h_stop_bits[3] = { - CeCosTestSerial::ONE_STOP_BIT, - CeCosTestSerial::ONE_POINT_FIVE_STOP_BITS, - CeCosTestSerial::TWO_STOP_BITS}; + CeCosSerial::StopBitsType t2h_stop_bits[3] = { + CeCosSerial::ONE_STOP_BIT, + CeCosSerial::ONE_POINT_FIVE_STOP_BITS, + CeCosSerial::TWO_STOP_BITS}; INIT_VALUE(args); SET_VALUE(int, ecos_baud_rate); @@ -607,7 +608,7 @@ CeCosTestSerialFilter::DoCRC(unsigned ch } void -CeCosTestSerialFilter::SendChecksum(CeCosTestSerial &pSer, int crc) +CeCosTestSerialFilter::SendChecksum(CeCosSerial &pSer, int crc) { char buffer[128]; int len; @@ -618,7 +619,7 @@ CeCosTestSerialFilter::SendChecksum(CeCo } void -CeCosTestSerialFilter::SendStatus(CeCosTestSerial &pSer, int state) +CeCosTestSerialFilter::SendStatus(CeCosSerial &pSer, int state) { if (state) TargetWrite(pSer, (unsigned char*) &msg_ok, 2); @@ -629,7 +630,7 @@ CeCosTestSerialFilter::SendStatus(CeCosT // Receive test DONE message from target. void -CeCosTestSerialFilter::ReceiveDone(CeCosTestSerial &pSer, +CeCosTestSerialFilter::ReceiveDone(CeCosSerial &pSer, unsigned char* data_in, int size) { static const char msg_done[] = "DONE"; @@ -679,7 +680,7 @@ CeCosTestSerialFilter::ReceiveDone(CeCos // o Clean up the DUPLEX_ECHO implementation. Currently it's an ugly hack // that doesn't match the arguments / behavior of the two other modes. void -CeCosTestSerialFilter::CMD_TestBinary(CeCosTestSerial &pSer, char* args) +CeCosTestSerialFilter::CMD_TestBinary(CeCosSerial &pSer, char* args) { int size; cyg_mode_t mode; @@ -875,10 +876,8 @@ CeCosTestSerialFilter::CMD_TestBinary(Ce // To Do: // Implement. void -CeCosTestSerialFilter::CMD_TestText(CeCosTestSerial &pSer, char* args) +CeCosTestSerialFilter::CMD_TestText(CeCosSerial &pSer, char* /*args*/) { - CYG_UNUSED_PARAM(args); - SendStatus(pSer, 1); } @@ -889,17 +888,15 @@ CeCosTestSerialFilter::CMD_TestText(CeCo // Format out: // OK void -CeCosTestSerialFilter::CMD_TestPing(CeCosTestSerial &pSer, char* args) +CeCosTestSerialFilter::CMD_TestPing(CeCosSerial &pSer, char* /*args*/) { - CYG_UNUSED_PARAM(args); - SendStatus(pSer, 1); } //----------------------------------------------------------------------------- // Dispatch test command. void -CeCosTestSerialFilter::DispatchCommand(CeCosTestSerial &pSer, char* cmd) +CeCosTestSerialFilter::DispatchCommand(CeCosSerial &pSer, char* cmd) { char* args; @@ -938,8 +935,8 @@ CeCosTestSerialFilter::DispatchCommand(C bool CALLBACK SerialFilterFunction(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket, + CeCosSerial& serial, + CeCosSocket& socket, void* pParem) { CeCosTestSerialFilter* p = (CeCosTestSerialFilter*) pParem; @@ -949,8 +946,8 @@ SerialFilterFunction(void*& pBuf, bool CeCosTestSerialFilter::FilterFunctionProper(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket) + CeCosSerial& serial, + CeCosSocket& socket) { char* buffer = (char*) pBuf; diff --git a/host/tools/ecostest/common/eCosTestSerialFilter.h b/host/tools/ecostest/common/eCosTestSerialFilter.h --- a/host/tools/ecostest/common/eCosTestSerialFilter.h +++ b/host/tools/ecostest/common/eCosTestSerialFilter.h @@ -41,8 +41,8 @@ #include "eCosStd.h" #include "eCosTest.h" -#include "eCosTestSocket.h" -#include "eCosTestSerial.h" +#include "eCosSocket.h" +#include "eCosSerial.h" //---------------------------------------------------------------------------- // Macros to help extract values from the argument string. @@ -68,7 +68,7 @@ struct filter_abort_t { typedef struct ser_cfg { int baud_rate; int data_bits; - CeCosTestSerial::StopBitsType stop_bits; + CeCosSerial::StopBitsType stop_bits; bool parity; // etc... } ser_cfg_t; @@ -101,8 +101,8 @@ public: bool FilterFunctionProper(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket); + CeCosSerial& serial, + CeCosSocket& socket); private: enum {MAX_CMD_LEN=128}; @@ -118,32 +118,32 @@ private: data_origin_t origin=SF_TARGET); // Target read/write methods - void TargetWrite(CeCosTestSerial &pSer, + void TargetWrite(CeCosSerial &pSer, const unsigned char* buffer, int len); - void TargetASCIIWrite(CeCosTestSerial &pSer, const char* s); - bool TargetRead(CeCosTestSerial &pSer, + void TargetASCIIWrite(CeCosSerial &pSer, const char* s); + bool TargetRead(CeCosSerial &pSer, unsigned char* buffer, int len); // Configuration CMD and helper methods void ParseConfig(char* args, ser_cfg_t* new_cfg); - bool SetConfig(CeCosTestSerial &pSer, const ser_cfg_t* new_cfg, + bool SetConfig(CeCosSerial &pSer, const ser_cfg_t* new_cfg, ser_cfg_t* old_cfg); - bool VerifyConfig(CeCosTestSerial &pSer, ser_cfg_t* new_cfg); - void CMD_ChangeConfig(CeCosTestSerial &pSer, char* cfg_str); - void CMD_DefaultConfig(CeCosTestSerial &pSer); + bool VerifyConfig(CeCosSerial &pSer, ser_cfg_t* new_cfg); + void CMD_ChangeConfig(CeCosSerial &pSer, char* cfg_str); + void CMD_DefaultConfig(CeCosSerial &pSer); // Other CMD methods. - void CMD_TestBinary(CeCosTestSerial &pSer, char* args); - void CMD_TestText(CeCosTestSerial &pSer, char* args); - void CMD_TestPing(CeCosTestSerial &pSer, char* args); + void CMD_TestBinary(CeCosSerial &pSer, char* args); + void CMD_TestText(CeCosSerial &pSer, char* args); + void CMD_TestPing(CeCosSerial &pSer, char* args); // Misc helper methods int DoCRC(unsigned char* data, int size); - void SendChecksum(CeCosTestSerial &pSer, int crc); - void SendStatus(CeCosTestSerial &pSer, int state); - void ReceiveDone(CeCosTestSerial &pSer, unsigned char* data_in, int size); - void DispatchCommand(CeCosTestSerial &pSer, char* cmd); + void SendChecksum(CeCosSerial &pSer, int crc); + void SendStatus(CeCosSerial &pSer, int state); + void ReceiveDone(CeCosSerial &pSer, unsigned char* data_in, int size); + void DispatchCommand(CeCosSerial &pSer, char* cmd); // Options used for configuring behavior. bool m_bOptConsoleOutput; @@ -164,13 +164,13 @@ private: // serial tracing while GDB is trying // to connect, or it will get confused. - CeCosTestSocket* m_cGDBSocket; // gdb_socket + CeCosSocket* m_cGDBSocket; // gdb_socket }; extern bool CALLBACK SerialFilterFunction(void*& pBuf, unsigned int& nRead, - CeCosTestSerial& serial, - CeCosTestSocket& socket, + CeCosSerial& serial, + CeCosSocket& socket, void* pParem); #endif // _CECOSSERIALFILTER_H diff --git a/host/tools/ecostest/common/eCosTestSocket.cpp b/host/tools/ecostest/common/eCosTestSocket.cpp deleted file mode 100644 --- a/host/tools/ecostest/common/eCosTestSocket.cpp +++ /dev/null @@ -1,780 +0,0 @@ -//####COPYRIGHTBEGIN#### -// -// ---------------------------------------------------------------------------- -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// -// This program is part of the eCos host tools. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// ---------------------------------------------------------------------------- -// -//####COPYRIGHTEND#### -//================================================================= -// -// eCosTestSocket.cpp -// -// Socket test class -// -//================================================================= -//================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): sdf -// Contributors: sdf -// Date: 1999-04-01 -// Description: This class abstracts tcp/ip sockets for use in the testing infrastructure -// Usage: -// -//####DESCRIPTIONEND#### - -#include "eCosStd.h" -#include "eCosTestSocket.h" -#include "eCosTestSerial.h" -#include "eCosTrace.h" - -enum {ERR_TIMEOUT=20000, ERR_READ_AFTER_CLOSE=20001}; - -// Blocking read on one or other of the data sources: -// Result: 0 - error occurred -// 1 - data read from socket -// 2 - data read from serial -int CeCosTestSocket::SSRead (CeCosTestSerial &serial,CeCosTestSocket &socket,void *pBuf,unsigned int nSize,unsigned int &nRead,bool *pbStop) -{ - int rc=0; - bool bBlocking=serial.GetBlockingReads(); - bool bBlockingModified=false; - while(0==pbStop || !(*pbStop)){ - if(!socket.Peek(nRead)){ - break; - } else if(nRead){ - nRead=MIN(nRead,nSize); - rc=socket.recv(pBuf,nRead)?1:0; - break; - } else { - if(bBlocking){ - serial.SetBlockingReads(false); - bBlockingModified=true; - bBlocking=false; - } - if(serial.Read(pBuf,nSize,nRead)){ - if(nRead>0){ - rc=2; - break; - } - } else { - break; - } - } - Sleep(1); - } - if(bBlockingModified){ - serial.SetBlockingReads(true); - } - return rc; -} - -// ctors and dtors - -CeCosTestSocket::CeCosTestSocket (): - m_nDefaultTimeout(10*1000), - m_nSock(-1), - m_nClient(0) -{ - TRACE(_T("Create socket instance %08x\n"),(unsigned int)this); -} - -CeCosTestSocket::CeCosTestSocket (int sock /*result of previous call of Listen*/, bool *pbStop): - m_nDefaultTimeout(10*1000), - m_nSock(-1), - m_nClient(0) -{ - TRACE(_T("Create socket instance %08x\n"),(unsigned int)this); - Accept(sock,pbStop); -} - -CeCosTestSocket::CeCosTestSocket (String strHost,int port,Duration dTimeout): - m_nDefaultTimeout(10*1000), - m_nSock(-1), - m_nClient(0) -{ - TRACE(_T("Create socket instance %08x\n"),(unsigned int)this); - Connect(strHost,port,dTimeout); -} - -bool CeCosTestSocket::Accept(int sock /*result of previous call of Listen*/, bool *pbStop) -{ - m_nSock=-1; - while(0==pbStop||!*pbStop){ - struct sockaddr cli_addr; - #ifndef _WIN32 - unsigned - #endif - int clilen=sizeof(struct sockaddr); - m_nSock=::accept(sock, (struct sockaddr *) &cli_addr, &clilen); - SaveError(); - if(-1==m_nSock){ - if(WOULDBLOCK==SocketError()){ - Sleep(100); - continue; - } - } else { - memcpy(&m_nClient,cli_addr.sa_data+2,4); - TRACE(_T("Connection accepted from %s - socket %d\n"),(LPCTSTR )ClientName(m_nClient),m_nSock); - SetSocketOptions(); - break; - } - } - return -1!=m_nSock; -} - -int CeCosTestSocket::Listen(int nTcpPort) -{ - // Create socket - int sock=::socket(AF_INET, SOCK_STREAM, 0); - if (sock == -1) { - ERROR(_T("Couldn't create socket\n")); - } else { - TRACE(_T("Created socket %d listening on port %d\n"),sock,nTcpPort); - // Bind socket to address - struct sockaddr_in serv_addr; - memset(&serv_addr, 0, sizeof serv_addr); - - serv_addr.sin_family = AF_INET; - serv_addr.sin_port=htons((short)nTcpPort); - serv_addr.sin_addr.s_addr = INADDR_ANY; - - if (::bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) { - TRACE(_T("Couldn't bind socket on port %d\n"),nTcpPort); - CloseSocket(sock); - } else if (-1==::listen(sock, SOMAXCONN)){ - CloseSocket(sock); - TRACE(_T("socket error on listen - port %d\n"),nTcpPort); - } else { - #ifdef _WIN32 - int nTrue=1; - bool rc=(0==::ioctlsocket(sock, FIONBIO, (unsigned long *)&nTrue)); - #else //UNIX - int flags=::fcntl(sock,F_GETFL); - flags|=O_NONBLOCK; - bool rc=(0==::fcntl (sock, F_SETFL, flags)); - #endif - if(!rc){ - TRACE(_T("Failed to set socket options on socket %d\n"),sock); - } - } - } - return sock; -} - -bool CeCosTestSocket::Connect(String strHost,int port,Duration dTimeout) -{ - dTimeout=TimeoutDuration(dTimeout); - struct sockaddr_in serv_addr; - - struct hostent* host_dat; - - char ip[16]; // for nnn.nnn.nnn.nnn - - VTRACE(_T("Connect: %s:%d timeout=%d\n"),(LPCTSTR )strHost,port,dTimeout); - - // Get the target host address - String strErr; - char *pszHost=strHost.GetCString(); - if (0==(host_dat=::gethostbyname(pszHost))){ - SaveError(); - TRACE(_T("Could not get IP address for host %s - %s\n"),(LPCTSTR )strHost,(LPCTSTR )SocketErrString()); - } else { - char *c=inet_ntoa( *( (struct in_addr *)host_dat->h_addr_list[0] ) ); - if(0==c){ - SaveError(); - TRACE(_T("Could inet_ntoa %s - %s\n"),(LPCTSTR )strHost,(LPCTSTR )SocketErrString()); - } else { - - strcpy(ip, c); - memset(&serv_addr, 0, sizeof serv_addr); - - // Create socket - m_nSock = ::socket(AF_INET, SOCK_STREAM, 0); - if (-1 == m_nSock) { - TRACE(_T("Could not create socket [%s:%d]\n"),(LPCTSTR )strHost,port); - } else { - #ifdef _WIN32 - SetSocketOptions(); - #endif - TRACE(_T("Created socket %d connected to %s:%d\n"),m_nSock,(LPCTSTR )strHost,port); - // Bind socket to address - serv_addr.sin_family = AF_INET; - serv_addr.sin_port=htons((short)port); - SaveError(); - serv_addr.sin_addr.s_addr = inet_addr(ip); - - // Connect to server - VTRACE(_T("Connect() : connecting to server\n")); - int cc=::connect(m_nSock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); - SaveError(); - String strMsg; - if(-1==cc){ - if( - #ifdef _WIN32 - WOULDBLOCK==SocketError() - #else // UNIX - EINPROGRESS==SocketError() - #endif - ){ - // Allow dTimeout milliseconds for connect to complete - fd_set set; - FD_ZERO(&set); - #ifdef _WIN32 - #pragma warning( push ) - #pragma warning( disable : 4127 ) // conditional expression is constant - #endif - FD_SET((unsigned)m_nSock, &set); - #ifdef _WIN32 - #pragma warning( pop ) - #endif - struct timeval tv; - tv.tv_sec = dTimeout/1000; - tv.tv_usec = 1000*(dTimeout % 1000); - switch(::select(m_nSock, NULL, &set , NULL, &tv)){ - case 0: - m_nErr=ERR_TIMEOUT; - strMsg.Format(_T("attempt timed out after %d seconds"),dTimeout/1000); - break; - case -1: - SaveError(); - strMsg=SocketErrString(); - break; - default: - cc=0; - } - } else { - strMsg=SocketErrString(); - } - } - - if(-1==cc){ - TRACE(_T("Could not connect to %s:%d - %s\n"),(LPCTSTR )strHost,port,(LPCTSTR )strMsg); - CloseSocket(m_nSock); - } else { - #ifndef _WIN32 - SetSocketOptions(); - #endif - } - } - } - } - delete [] pszHost; - return -1!=m_nSock; -} - -bool CeCosTestSocket::sendrecv(bool bSend,const void *pData,unsigned int nLength, - LPCTSTR pszMsg,Duration dTimeout,CeCosTestSocket::StopFunc pFnStop,void *pParam) -{ - - dTimeout=TimeoutDuration(dTimeout); - - LPCTSTR pszSR=(bSend?_T("sending"):_T("receiving")); - LPTSTR c=(LPTSTR )pData; - Time ft0=Now(); - int nTodo=nLength; - while((nTodo>0) && ((0==pFnStop) || (!pFnStop(pParam)))){ - int s=bSend?::send(m_nSock, (const char *)c, nTodo, 0): ::recv(m_nSock, (char *)c, nTodo, 0); - if(0==s && !bSend){ - m_nErr=ERR_READ_AFTER_CLOSE; - } else { - SaveError(); - } - if(-1==s && WOULDBLOCK==SocketError()){ - Duration d=Duration(Now()-ft0); - if(d>dTimeout){ - TRACE(_T("%d/%d mSec timeout on socket %d %s %s - processed %d/%d bytes\n") , - d,dTimeout,m_nSock,pszSR,pszMsg, - nLength-nTodo,nLength); - m_nErr=ERR_TIMEOUT; - break; - } - Sleep(100); - } else if (s>0) { - c+=s; - nTodo-=s; - ft0=Now(); - } else { - TRACE(_T("Error on socket %d %s %s - %s\n") ,m_nSock, pszSR, pszMsg, (LPCTSTR )SocketErrString()); - break; - } - } - return 0==nTodo; -} - -// Graceful socket closedown -CeCosTestSocket::~CeCosTestSocket() -{ - Close(); - TRACE(_T("Delete socket instance %08x\n"),(unsigned int)this); -} - -bool CeCosTestSocket::CloseSocket(int &sock) -{ - bool rc=false; - if(-1!=sock){ - TRACE(_T("Closing socket %d\n"),sock); - try{ - shutdown(sock,0);// SD_BOTH - #ifdef _WIN32 - rc=(0==closesocket(sock)); - #else // UNIX - rc=(0==close(sock)); - #endif - } - catch(...) { - TRACE(_T("!!! Exception caught in CeCosTestSocket::CloseSocket!!!\n")); - } - sock=-1; - } - return rc; -} - -bool CeCosTestSocket::SetSocketOptions() -{ - bool rc; - #ifdef _WIN32 - int nTrue=1; - rc=(0==::ioctlsocket(m_nSock, FIONBIO, (unsigned long *)&nTrue)); - SaveError(); - #else // UNIX - int flags=::fcntl(m_nSock,F_GETFL); - SaveError(); - flags|=O_NONBLOCK; - rc=(0==::fcntl (m_nSock, F_SETFL, flags)); - SaveError(); - #endif - //LINGER linger; - //setsockopt(m_nSock,SOL_SOCKET,SO_LINGER,(LPCTSTR )linger, sizeof(LINGER)); - if(!rc){ - TRACE(_T("Failed to set socket options socket %d - %s\n"),m_nSock,(LPCTSTR )SocketErrString()); - } - return rc; -} - -String CeCosTestSocket::SocketErrString(int nErr) -{ - String str; - #ifdef _WIN32 - switch(nErr){ - case ERR_TIMEOUT: str=_T("Read operation timed out");break; - case ERR_READ_AFTER_CLOSE: str=_T("Read operation after socket closed");break; - - case WSAEACCES: str=_T("Permission denied");break; - case WSAEADDRINUSE: str=_T("Address already in use");break; - case WSAEADDRNOTAVAIL: str=_T("Cannot assign requested address");break; - case WSAEAFNOSUPPORT: str=_T("Address family not supported by protocol family");break; - case WSAEALREADY: str=_T("Operation already in progress");break; - case WSAECONNABORTED: str=_T("Software caused connection abort");break; - case WSAECONNREFUSED: str=_T("Connection refused");break; - case WSAECONNRESET: str=_T("Connection reset by peer");break; - case WSAEDESTADDRREQ: str=_T("Destination address required");break; - case WSAEFAULT: str=_T("Bad address");break; - case WSAEHOSTDOWN: str=_T("Host is down");break; - case WSAEHOSTUNREACH: str=_T("No route to host");break; - case WSAEINPROGRESS: str=_T("Operation now in progress");break; - case WSAEINTR: str=_T("Interrupted function call");break; - case WSAEINVAL: str=_T("Invalid argument");break; - case WSAEISCONN: str=_T("Socket is already connected");break; - case WSAEMFILE: str=_T("Too many open files");break; - case WSAEMSGSIZE: str=_T("Message too long");break; - case WSAENETDOWN: str=_T("Network is down");break; - case WSAENETRESET: str=_T("Network dropped connection on reset");break; - case WSAENETUNREACH: str=_T("Network is unreachable");break; - case WSAENOBUFS: str=_T("No buffer space available");break; - case WSAENOPROTOOPT: str=_T("Bad protocol option");break; - case WSAENOTCONN: str=_T("Socket is not connected");break; - case WSAENOTSOCK: str=_T("Socket operation on non-socket");break; - case WSAEOPNOTSUPP: str=_T("Operation not supported");break; - case WSAEPFNOSUPPORT: str=_T("Protocol family not supported");break; - case WSAEPROCLIM: str=_T("Too many processes");break; - case WSAEPROTONOSUPPORT: str=_T("Protocol not supported");break; - case WSAEPROTOTYPE: str=_T("Protocol wrong type for socket");break; - case WSAESHUTDOWN: str=_T("Cannot send after socket shutdown");break; - case WSAESOCKTNOSUPPORT: str=_T("Socket type not supported");break; - case WSAETIMEDOUT: str=_T("Connection timed out");break; - case WSATYPE_NOT_FOUND: str=_T("Class type not found");break; - case WSAEWOULDBLOCK: str=_T("Resource temporarily unavailable");break; - case WSAHOST_NOT_FOUND: str=_T("Host not found");break; - case WSA_INVALID_HANDLE: str=_T("Specified event object handle is invalid");break; - case WSA_INVALID_PARAMETER: str=_T("One or more parameters are invalid");break; - //case WSAINVALIDPROCTABLE: str=_T("Invalid procedure table from service provider");break; - //case WSAINVALIDPROVIDER: str=_T("Invalid service provider version number");break; - case WSA_IO_INCOMPLETE: str=_T("Overlapped I/O event object not in signaled state");break; - case WSA_IO_PENDING: str=_T("Overlapped operations will complete later");break; - case WSA_NOT_ENOUGH_MEMORY: str=_T("Insufficient memory available");break; - case WSANOTINITIALISED: str=_T("Successful case WSAStartup not yet:performed");break; - case WSANO_DATA: str=_T("Valid name, no data record of requested type");break; - case WSANO_RECOVERY: str=_T("This is a non-recoverable error");break; - //case WSAPROVIDERFAILEDINIT: str=_T("Unable to initialize a service provider");break; - case WSASYSCALLFAILURE: str=_T("System call failure");break; - case WSASYSNOTREADY: str=_T("Network subsystem is unavailable");break; - case WSATRY_AGAIN: str=_T("Non-authoritative host not found");break; - case WSAVERNOTSUPPORTED: str=_T("WINSOCK.DLL version out of range");break; - case WSAEDISCON: str=_T("Graceful shutdown in progress");break; - case WSA_OPERATION_ABORTED: str=_T("Overlapped operation aborted");break; - default: - str.Format(_T("Unknown error %d (0x%08x)"),nErr,nErr); - } -#else // UNIX - switch(nErr){ - case ERR_TIMEOUT: str=_T("Read operation timed out");break; - case ERR_READ_AFTER_CLOSE: str=_T("Read operation after socket closed");break; - default: - str=strerror(errno); - } -#endif - return str; -} - -bool CeCosTestSocket::sendInteger(int n,LPCTSTR pszMsg,Duration dTimeout) -{ - // This has to support cross-architectural endianness - unsigned char c[sizeof(int)]; - for(unsigned int i=0;i>=8; - } - return send (c, sizeof(int),pszMsg,dTimeout); -} - -bool CeCosTestSocket::recvInteger(int & n,LPCTSTR pszMsg,Duration dTimeout) -{ - // This has to support cross-architectural endianness - unsigned char c[sizeof(int)]; - bool rc=recv (c, sizeof(int),pszMsg,dTimeout); - n=0; - if(rc){ - for(int i=sizeof(int)-1;i>=0;--i){ - n<<=8; - n|=c[i]; - } - } - return rc; -} - -// Socket communications for strings are always non-UNICODE: -bool CeCosTestSocket::recvString (String &str,LPCTSTR pszMsg,Duration dTimeout) -{ - int nLength; - bool rc=false; - if(recvInteger(nLength,pszMsg,dTimeout)){ - if(0==nLength){ - rc=true; - } else { - Buffer b(1+nLength); - char *c=(char *)b.Data(); - if(c){ - rc=recv(c,nLength,pszMsg,dTimeout); - c[nLength]='\0'; - str=String::CStrToUnicodeStr(c); - } - } - } - return rc; -} - -// Socket communications for strings are always non-UNICODE: -bool CeCosTestSocket::sendString (const String &str,LPCTSTR pszMsg,Duration dTimeout) -{ - char *psz=str.GetCString(); - int nLength=strlen(psz); - bool rc=sendInteger(nLength,pszMsg,dTimeout) && (0==nLength || send(psz,nLength,pszMsg,dTimeout)); - delete [] psz; - return rc; -} - - -// Give indication of bytes available to be read (but don't read them) -bool CeCosTestSocket::Peek (unsigned int &nAvail) -{ - char buf[8192]; - int n=::recv(m_nSock, buf, sizeof buf, MSG_PEEK); - nAvail=0; - bool rc=false; - switch(n) { - case -1: - SaveError(); - if(WOULDBLOCK==SocketError()){ - rc=true; // nAvail stays==0 - } else { - ERROR(_T("Peek: err=%d %s\n"),SocketError(),(LPCTSTR )SocketErrString()); - } - break; - case 0: - m_nErr=ERR_READ_AFTER_CLOSE; - break; - default: - rc=true; - nAvail=n; - } - return rc; -} - -// Connect tcp/ip port and serial port together. -// Traffic is passed through pFunc, passed parameter pParam. -// The pFunc function: -// may reallocate pBuf (using malloc/realloc etc...) -// must leave pBuf allocated on exit -// should not close either serial or socket -// should leave writing to its caller -// should return false if it wishes to terminate the connection (after caller has written output) -bool CeCosTestSocket::ConnectSocketToSerial (CeCosTestSocket &socket,CeCosTestSerial &serial,FilterFunc *pSerialToSocketFilterFunc/*=0*/,void *pSerialParam/*=0*/,FilterFunc *pSocketToSerialFilterFunc/*=0*/,void *pSocketParam/*=0*/,bool *pbStop/*=0*/) -{ - serial.ClearError(); - enum {BUFSIZE=8192}; - void *pBuf=malloc(BUFSIZE); - TRACE(_T("ConnectSocketToSerial: connected\n")); - bool rc=true; - try { - /* - { //hack - unsigned int nWritten;//hack - serial.Write(_T("+"),1,nWritten);//hack - }//hack - */ - while(rc && (0==pbStop || !(*pbStop))){ - unsigned int nRead=0; - switch(SSRead (serial,socket,pBuf,BUFSIZE,nRead,pbStop)){ - case 2: - VTRACE(_T("Serial:%d\n"),nRead); - if(pSerialToSocketFilterFunc){ - rc=pSerialToSocketFilterFunc(pBuf,nRead,serial,socket,pSerialParam); - } - if(nRead && !socket.send(pBuf,nRead)){ - TRACE(_T("Failed to write to socket\n")); - rc=false; - } - break; - case 1: - unsigned int nWritten; - VTRACE(_T("Socket:%d\n"),nRead); - if(pSocketToSerialFilterFunc){ - rc=pSocketToSerialFilterFunc(pBuf,nRead,serial,socket,pSocketParam); - } - { - LPTSTR c=(LPTSTR )pBuf; - int nToWrite=nRead; - while(nToWrite>0){ - if(!serial.Write(pBuf,nRead,nWritten)){ - TRACE(_T("Failed to write to serial\n")); - rc=false; - break; - } - nToWrite-=nWritten; - c+=nWritten; - } - } - break; - case 0: - TRACE(_T("SSRead returned error indication\n")); - rc=false; - break; - // Error - } - } - } - catch (...){ - TRACE(_T("!!! ConnectSocketToSerial exception caught!!!\n")); - free(pBuf); - throw; - } - free(pBuf); - return rc; -} - -// Connect two tcp/ip ports together. -// Traffic is passed through pFunc, passed parameter pParam. -// The pFunc function: -// may reallocate pBuf (using malloc/realloc etc...) -// must leave pBuf allocated on exit -// should not close either serial or socket -// should leave writing to its caller -// should return false if it wishes to terminate the connection (after caller has written output) -bool CeCosTestSocket::ConnectSocketToSocket (CeCosTestSocket &o,FilterFunc *pSocketToSocketFilterFunc1,FilterFunc *pSocketToSocketFilterFunc2,void *pParam,bool *pbStop) -{ - enum {BUFSIZE=8192}; - void *pBuf=malloc(BUFSIZE); - TRACE(_T("ConnectSocketToSocket: connected\n")); - bool rc=true; - try { - while(rc && (0==pbStop || !(*pbStop))){ - fd_set set; - FD_ZERO(&set); - FD_SET((unsigned)m_nSock, &set); - FD_SET((unsigned)o.m_nSock, &set); - struct timeval tv; - tv.tv_sec = 1; - tv.tv_usec = 0; - switch(::select(m_nSock,&set,0,0,&tv)){ - case -1: - rc=false; - break; - case 1: - case 2: - { - unsigned int nAvail=0; - if(FD_ISSET((unsigned)m_nSock, &set) && Peek(nAvail) && recv(pBuf,nAvail)){ - //rc=pSocketToSocketFilterFunc1(pBuf,nAvail,socket,this,o); - o.send(pBuf,nAvail); - } - if(FD_ISSET((unsigned)o.m_nSock, &set) && o.Peek(nAvail) && o.recv(pBuf,nAvail)){ - //rc=pSocketToSocketFilterFunc2(pBuf,nAvail,socket,o,this); - send(pBuf,nAvail); - } - } - case 0: - break; - } - } - } - catch (...){ - TRACE(_T("!!! ConnectSocketToSocket exception caught!!!\n")); - rc=false; - } - free(pBuf); - return rc; -} - -bool CeCosTestSocket::ConnectSocketToSerial ( - int nListenSock,LPCTSTR pszPort, int nBaud, - FilterFunc *pSerialToSocketFilterFunc/*=0*/,void *pSerialParam/*=0*/,FilterFunc *pSocketToSerialFilterFunc/*=0*/,void *pSocketParam/*=0*/, - bool *pbStop) -{ - bool rc=false; - try{ - TRACE(_T("ConnectSocketToSerial : socket %d <--> %s\n"),nListenSock,pszPort); - - CeCosTestSerial serial; - serial.SetBlockingReads(false); - // Open serial device. - if (!serial.Open(pszPort,nBaud)){ - ERROR(_T("Couldn't open port %s\n"),pszPort); - } else { - // Flush the serial buffer. - serial.Flush(); - - TRACE(_T("ConnectSocketToSerial: waiting for connection...\n")); - CeCosTestSocket socket; - if(!socket.Accept(nListenSock,pbStop)){ - ERROR(_T("ConnectSocketToSerial - couldn't accept\n")); - } else { - rc=ConnectSocketToSerial (socket,serial,pSerialToSocketFilterFunc,pSerialParam,pSocketToSerialFilterFunc,pSocketParam,pbStop); - } - } - TRACE(_T("ConnectSocketToSerial : done\n")); - } - catch(...){ - TRACE(_T("ConnectSocketToSerial !!!exception handled!!!\n")); - } - return rc; -} - -String CeCosTestSocket::ClientName(int nClient) -{ - char ip[4]; - memcpy(ip,&nClient,4); - struct hostent *he=::gethostbyaddr((const char *)ip,4,AF_INET); - String str; - if(he){ - str=String::CStrToUnicodeStr(he->h_name); - } else { - str.Format(_T("%u.%u.%u.%u"),ip[0],ip[1],ip[2],ip[3]); - } - return str; -} - -String CeCosTestSocket::HostPort(LPCTSTR pszHost,int nPort) -{ - String str; - str.Format(_T("%s:%d"),pszHost,nPort); - return str; -} - -// Split the string into host:port parts. Result tells us whether it was successful. -bool CeCosTestSocket::ParseHostPort (LPCTSTR pszHostPort, String &strHost, int &nPort) -{ - int n=_stscanf(pszHostPort,_T("%[^:]:%d"),strHost.GetBuffer(_tcslen(pszHostPort)),&nPort); - strHost.ReleaseBuffer(); - return 2==n && nPort>0 && nPort<=0xffff; -} - -// Is the string in the form host:port? -bool CeCosTestSocket::IsLegalHostPort (LPCTSTR pszHostPort) -{ - int nPort=0; - String strHost; - return ParseHostPort(pszHostPort,strHost,nPort); -} - -// Translate a timeout that may be one of the special values DEFAULTTIMEOUT or NOTIMEOUT to a value in milliseconds. -Duration CeCosTestSocket::TimeoutDuration(Duration dTimeout) -{ - switch(dTimeout){ - case DEFAULTTIMEOUT: - dTimeout=m_nDefaultTimeout; - break; - case NOTIMEOUT: - dTimeout=0x7fffffff; - break; - default: - break; - } - return dTimeout; -} - -bool CeCosTestSocket::IsSocketError(int n) -{ - #ifdef _WIN32 - return n>=WSABASEERR && n<30000; // include our own (e.g. ERR_READ_AFTER_CLOSE) - #else // UNIX - return true; - #endif -} - -String CeCosTestSocket::SocketErrString() { - return SocketErrString(m_nErr); -} - - -bool CeCosTestSocket::SameHost(LPCTSTR host1, LPCTSTR host2) -{ - char *h1=String(host1).GetCString(); - char *h2=String(host2).GetCString(); - char ip1[16],ip2[16]; - struct hostent* host_dat; - bool rc=(0==_tcscmp(host1,host2)); - if (0!=(host_dat=::gethostbyname(h1))){ - char *c=inet_ntoa( *( (struct in_addr *)host_dat->h_addr_list[0] ) ); - if(c){ - strcpy(ip1,c); - if (0!=(host_dat=::gethostbyname(h2))){ - char *c=inet_ntoa( *( (struct in_addr *)host_dat->h_addr_list[0] ) ); - if(c){ - strcpy(ip2,c); - } - } - rc=(0==strcmp(ip1,ip2)); - } - } - delete [] h1; - delete [] h2; - return rc; -} diff --git a/host/tools/ecostest/common/eCosTestSocket.h b/host/tools/ecostest/common/eCosTestSocket.h deleted file mode 100644 --- a/host/tools/ecostest/common/eCosTestSocket.h +++ /dev/null @@ -1,134 +0,0 @@ -//####COPYRIGHTBEGIN#### -// -// ---------------------------------------------------------------------------- -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// -// This program is part of the eCos host tools. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// ---------------------------------------------------------------------------- -// -//####COPYRIGHTEND#### -//================================================================= -// -// eCosTestSocket.h -// -// Socket test class -// -//================================================================= -//================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): sdf -// Contributors: sdf -// Date: 1999-04-01 -// Description: This class abstracts tcp/ip sockets for use in the testing infrastructure -// Usage: -// -//####DESCRIPTIONEND#### -#include "eCosStd.h" -#include "Collections.h" - -#ifndef _SOCKETUTILS_H -#define _SOCKETUTILS_H - -class CeCosTestSerial; - -class CeCosTestSocket { -public: - static bool SameHost (LPCTSTR host1,LPCTSTR host2); - - typedef bool (CALLBACK FilterFunc)(void *&,unsigned int &,CeCosTestSerial&,CeCosTestSocket &,void *); - static int CeCosTestSocket::SSRead (CeCosTestSerial &serial,CeCosTestSocket &socket,void *pBuf,unsigned int nSize,unsigned int &nRead,bool *pbStop); - - static bool ConnectSocketToSerial (int nListenSock,LPCTSTR pszPort, int nBaud,FilterFunc *pSerialToSocketFilterFunc=0,void *pSerialParam=0,FilterFunc *pSocketToSerialFilterFunc=0,void *pSocketParam=0,bool *pbStop=0); - static bool ConnectSocketToSerial (CeCosTestSocket &socket,CeCosTestSerial &serial,FilterFunc *pSerialToSocketFilterFunc=0,void *pSerialParam=0, FilterFunc *pSocketToSerialFilterFunc=0,void *pSocketParam=0,bool *pbStop=0); - bool ConnectSocketToSocket (CeCosTestSocket &o,FilterFunc *pSocketToSocketFilterFunc1,FilterFunc *pSocketToSocketFilterFunc2,void *pParam,bool *pbStop); - - typedef bool (CALLBACK StopFunc)(void *); - - static bool IsSocketError(int n); - - enum {NOTIMEOUT=-1,DEFAULTTIMEOUT=-2}; // No explicit timeout specified - - // Listen and this form of constructor used to act as server - static int Listen(int nTcpPort); - CeCosTestSocket (); // Caller promises to call Accept() or Connect() later - - // Accept-like ctor (act as server) - CeCosTestSocket (int sock /*result of previous call of Listen*/, bool *pbStop=0); - // Connect-like ctor (act as client) - CeCosTestSocket (String strHost,int port,Duration dTimeout); - - bool Accept(int sock /*result of previous call of Listen*/, bool *pbStop=0); - // This form of constructor used to act as client - bool Connect(String strHost,int port,Duration dTimeout); - ~CeCosTestSocket(); - - int Client() const { return m_nClient; } - static String ClientName(int nClient); - - int Sock() const { return m_nSock; } - - // Set the default timeout for all operations - void SetTimeout (Duration dTimeout) { m_nDefaultTimeout=dTimeout; } - - bool send(const void *pData,unsigned int nLength,LPCTSTR pszMsg=_T(""),int dTimeout=DEFAULTTIMEOUT,StopFunc *pFunc=0,void *pParam=0){ - return sendrecv(true,pData,nLength,pszMsg,dTimeout,pFunc,pParam); - } - bool recv(const void *pData,unsigned int nLength,LPCTSTR pszMsg=_T(""),int dTimeout=DEFAULTTIMEOUT,StopFunc *pFunc=0,void *pParam=0){ - return sendrecv(false,pData,nLength,pszMsg,dTimeout,pFunc,pParam); - } - bool Ok() { return -1!=m_nSock; } - // Close the given socket - bool Close () { return CloseSocket(m_nSock); } - - int SocketError() { return m_nErr; } - // Return last socket error, translated to a string - String SocketErrString(); - static String SocketErrString(int nErr); - - bool recvInteger (int &n,LPCTSTR pszMsg=_T(""),Duration dTimeout=DEFAULTTIMEOUT); - bool sendInteger (int n,LPCTSTR pszMsg=_T(""),Duration dTimeout=DEFAULTTIMEOUT); - - bool recvString (String &str,LPCTSTR pszMsg=_T(""),Duration dTimeout=DEFAULTTIMEOUT); - bool sendString (const String &str,LPCTSTR pszMsg=_T(""),Duration dTimeout=DEFAULTTIMEOUT); - - static bool CloseSocket (int &sock); - bool Peek (unsigned int &nAvail); - static String HostPort(LPCTSTR pszHost,int nPort); - static bool ParseHostPort (LPCTSTR pszHostPort, String &pszHost, int &nPort); - static bool IsLegalHostPort (LPCTSTR pszHostPort); - -protected: - Duration m_nDefaultTimeout; - Duration TimeoutDuration (Duration dTimeout); - // Set appropriate socket options (most importantly, non-blocking mode) - bool SetSocketOptions (); - int m_nSock; - int m_nClient; - int m_nErr; - void SaveError() { -#ifdef _WIN32 - m_nErr=WSAGetLastError(); -#else // UNIX - m_nErr=errno; -#endif - } - bool sendrecv(bool bSend,const void *pData,unsigned int nLength,LPCTSTR pszMsg=_T(""),int dTimeout=DEFAULTTIMEOUT,StopFunc *pFunc=0,void *pParam=0); - -}; -#endif diff --git a/host/tools/ecostest/common/eCosTestUtils.cpp b/host/tools/ecostest/common/eCosTestUtils.cpp --- a/host/tools/ecostest/common/eCosTestUtils.cpp +++ b/host/tools/ecostest/common/eCosTestUtils.cpp @@ -41,9 +41,11 @@ //####DESCRIPTIONEND#### #include "eCosStd.h" +#include "eCosSocket.h" #include "eCosTestUtils.h" #include "eCosThreadUtils.h" #include "eCosTrace.h" +#include "TestResource.h" LPCTSTR const CeCosTestUtils::Tail(LPCTSTR const pszFile) { @@ -54,42 +56,6 @@ LPCTSTR const CeCosTestUtils::Tail(LPCT return (0==pszTail)?pszFile:pszTail+1; } -LPCTSTR CeCosTestUtils::HostName() -{ - static bool bFirstTime=true; - static String str; - static int nErr; - if(bFirstTime){ - char szMyname[256]; - nErr=gethostname(szMyname,sizeof szMyname); - bFirstTime=false; - if(0==nErr){ - str=String::CStrToUnicodeStr(szMyname); - } else { - str=_T(""); - } - } - return str; -} - -LPCTSTR CeCosTestUtils::SimpleHostName() -{ - static bool bFirstTime=true; - static String str; - if(bFirstTime){ - str=HostName(); - // Remove all after a '.' - LPCTSTR c=_tcschr(str,_TCHAR('.')); - if(c){ - str.SetLength(c-(LPCTSTR )str); - } - bFirstTime=false; - } - return str; -} - - - // File iterator. Gets next file in directory, avoiding _T(".") and _T("..") bool CeCosTestUtils::NextFile (void *&pHandle,String &str) { @@ -147,19 +113,53 @@ void CeCosTestUtils::EndSearch (void *&p // deal with common command-line actions -bool CeCosTestUtils::CommandLine(int &argc,TCHAR **argv) +bool CeCosTestUtils::CommandLine(int &argc,TCHAR **argv,bool bRequireResourceServer) { + LPCTSTR psz=_tgetenv(_T("RESOURCESERVER")); + if(psz && !CTestResource::SetResourceServer(psz)){ + _ftprintf(stderr,_T("Illegal host:port '%s' defined in RESOURCESERVER environment variable\n"),psz); + return false; + } + for(int i=1;i0){ break; } - Sleep(1); + CeCosThreadUtils::Sleep(1); } else { fprintf(stderr, "Serial read failed (%d)\n", errno); } @@ -129,15 +130,13 @@ main(int argc, char** argv) if(!CeCosTestUtils::CommandLine(argc,argv)){ goto Usage; } - if(!CeCosTest::Init()){ - goto Usage; - } while(iSetVerbose(true); // Set filter functions - CeCosTestSocket::FilterFunc *host_filter_function = + CeCosSocket::FilterFunc *host_filter_function = &SerialMonitorFunction; - CeCosTestSocket::FilterFunc *target_filter_function = + CeCosSocket::FilterFunc *target_filter_function = &SerialMonitorFunction; try { - CeCosTestSocket::ConnectSocketToSerial(nSock, ser_port, + CeCosSocket::ConnectSocketToSerial(nSock, ser_port, baud_rate, target_filter_function, (void*)target_filter, @@ -251,7 +250,7 @@ main(int argc, char** argv) new CeCosTestSerialFilter(); CeCosTestDownloadFilter* download_filter = new CeCosTestDownloadFilter(); - + // Set filter configuration serial_filter->SetFilterTrace(opt_filter_trace); serial_filter->SetSerialDebug(opt_ser_debug); @@ -262,13 +261,13 @@ main(int argc, char** argv) download_filter->SetSerialDebug(opt_ser_debug); // Set serial side filter - CeCosTestSocket::FilterFunc *ser_filter_function = + CeCosSocket::FilterFunc *ser_filter_function = &SerialFilterFunction; if (opt_null_filter) ser_filter_function = NULL; // Set socket side filter - CeCosTestSocket::FilterFunc *sock_filter_function = + CeCosSocket::FilterFunc *sock_filter_function = &DownloadFilterFunction; try { @@ -276,7 +275,7 @@ main(int argc, char** argv) no_gdb(ser_port, baud_rate, ser_filter_function, (void*)serial_filter, NULL); else - CeCosTestSocket::ConnectSocketToSerial(nSock, ser_port, + CeCosSocket::ConnectSocketToSerial(nSock, ser_port, baud_rate, ser_filter_function, (void*)serial_filter, @@ -299,26 +298,21 @@ main(int argc, char** argv) delete download_filter; } - CeCosTest::Term(); return 0; Usage: const char *pszMe="ser_filter"; - fprintf(stderr,"Usage: %s [-t -c -S -0 -Xab] TcpIPport SerialPort BaudRate\n", - // 1 2 3 - pszMe); - fprintf(stderr," or: %s -n [-t -c -S -0 -Xab] SerialPort BaudRate\n", - // 1 2 - pszMe); - fprintf(stderr, " -t: Enable tracing.\n"); - fprintf(stderr, " -f: Enable filter output tracing.\n"); - fprintf(stderr, " -S: Output data read from serial line.\n"); - fprintf(stderr, " -c: Output data on console instead of via GDB.\n"); - fprintf(stderr, " -m: Work only as a monitor filter. Implies -c.\n"); - fprintf(stderr, " -n: No GDB.\n"); - fprintf(stderr, " -0: Use null filter.\n"); - fprintf(stderr, " -Xab: Reset X-10 Port 'a b' when TCP connection breaks\n"); - CeCosTest::Term(); + fprintf(stderr,"Usage: %s [-c -S -0 -Xab] TcpIPport SerialPort BaudRate\n" + " or: %s -n [-c -S -0 -Xab] SerialPort BaudRate\n" + " Switches:\n" + " -f: Enable filter output tracing.\n" + " -S: Output data read from serial line.\n" + " -c: Output data on console instead of via GDB.\n" + " -m: Work only as a monitor filter. Implies -c.\n" + " -n: No GDB.\n" + " -0: Use null filter.\n" + " -Xab: Reset X-10 Port 'a b' when TCP connection breaks\n",pszMe,pszMe); + CeCosTestUtils::UsageMessage(); + return 1; } - diff --git a/host/tools/ecostest/unix/Makefile b/host/tools/ecostest/unix/Makefile --- a/host/tools/ecostest/unix/Makefile +++ b/host/tools/ecostest/unix/Makefile @@ -1,17 +1,19 @@ common_sources = \ ../../Utils/common/Properties.cpp \ + ../../Utils/common/Subprocess.cpp \ ../../Utils/common/Collections.cpp \ ../../Utils/common/eCosStd.cpp \ ../../Utils/common/eCosThreadUtils.cpp \ ../../Utils/common/eCosTrace.cpp \ - ../common/eCosTestUtils.cpp \ - ../common/eCosTestSocket.cpp \ - ../common/TestResource.cpp \ - ../common/ResetAttributes.cpp \ - ../common/eCosTest.cpp \ - ../common/eCosTestSerial.cpp \ - ../common/eCosTestDownloadFilter.cpp \ - ../common/eCosTestMonitorFilter.cpp \ + ../../Utils/common/eCosSerial.cpp \ + ../../Utils/common/eCosSocket.cpp \ + ../common/eCosTestUtils.cpp \ + ../common/TestResource.cpp \ + ../common/ResetAttributes.cpp \ + ../common/eCosTest.cpp \ + ../common/eCosTestPlatform.cpp \ + ../common/eCosTestDownloadFilter.cpp \ + ../common/eCosTestMonitorFilter.cpp \ ../common/eCosTestSerialFilter.cpp common_objects = $(notdir $(common_sources:.cpp=.o)) diff --git a/host/tools/ecostest/win32/eCosTest.dsp b/host/tools/ecostest/win32/eCosTest.dsp --- a/host/tools/ecostest/win32/eCosTest.dsp +++ b/host/tools/ecostest/win32/eCosTest.dsp @@ -89,6 +89,23 @@ SOURCE=..\..\Utils\common\Collections.cp # End Source File # Begin Source File +SOURCE=..\..\Utils\common\eCosSerial.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Utils\common\eCosSocket.cpp + +!IF "$(CFG)" == "eCosTest - Win32 Release" + +!ELSEIF "$(CFG)" == "eCosTest - Win32 Debug" + +# ADD CPP /W4 + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\Utils\common\eCosStd.cpp # End Source File # Begin Source File @@ -105,7 +122,7 @@ SOURCE=..\common\eCosTestMonitorFilter.c # End Source File # Begin Source File -SOURCE=..\common\eCosTestSerial.cpp +SOURCE=..\common\eCosTestPlatform.cpp # End Source File # Begin Source File @@ -113,10 +130,6 @@ SOURCE=..\common\eCosTestSerialFilter.cp # End Source File # Begin Source File -SOURCE=..\common\eCosTestSocket.cpp -# End Source File -# Begin Source File - SOURCE=..\common\eCosTestUtils.cpp # End Source File # Begin Source File @@ -137,7 +150,7 @@ SOURCE=..\common\ResetAttributes.cpp # End Source File # Begin Source File -SOURCE=..\..\Utils\win32\SubProcess.cpp +SOURCE=..\..\Utils\common\Subprocess.cpp # End Source File # Begin Source File @@ -153,6 +166,14 @@ SOURCE=..\..\Utils\common\Collections.h # End Source File # Begin Source File +SOURCE=..\..\Utils\common\eCosSerial.h +# End Source File +# Begin Source File + +SOURCE=..\..\Utils\common\eCosSocket.h +# End Source File +# Begin Source File + SOURCE=..\..\Utils\common\eCosStd.h # End Source File # Begin Source File @@ -169,7 +190,7 @@ SOURCE=..\common\eCosTestMonitorFilter.h # End Source File # Begin Source File -SOURCE=..\common\eCosTestSerial.h +SOURCE=..\common\eCosTestPlatform.h # End Source File # Begin Source File @@ -177,10 +198,6 @@ SOURCE=..\common\eCosTestSerialFilter.h # End Source File # Begin Source File -SOURCE=..\common\eCosTestSocket.h -# End Source File -# Begin Source File - SOURCE=..\common\eCosTestUtils.h # End Source File # Begin Source File @@ -201,7 +218,7 @@ SOURCE=..\common\ResetAttributes.h # End Source File # Begin Source File -SOURCE=..\..\Utils\win32\SubProcess.h +SOURCE=..\..\Utils\common\Subprocess.h # End Source File # Begin Source File diff --git a/host/tools/testtool/ChangeLog b/host/tools/testtool/ChangeLog --- a/host/tools/testtool/ChangeLog +++ b/host/tools/testtool/ChangeLog @@ -1,3 +1,23 @@ +2000-04-11 Simon FitzMaurice + * win32\ExecutionPage.cpp + win32\ExecutionPage.h + win32\LocalPropertiesDialog.cpp + win32\PlatformDialog.cpp + win32\PlatformDialog.h + win32\PlatformsDialog.cpp + win32\PlatformsDialog.h + win32\PropertiesDialog.cpp + win32\RemotePropertiesDialog.cpp + win32\RunTestsSheet.cpp + win32\RunTestsSheet.h + win32\SummaryPage.cpp + win32\TestTool.cpp + win32\TestTool.dsp + win32\TestTool.rc + win32\testtoolres.h + + General tidy-up. + 2000-04-05 John Dallaway * win32/TestTool.rc: diff --git a/host/tools/testtool/win32/ExecutionPage.cpp b/host/tools/testtool/win32/ExecutionPage.cpp --- a/host/tools/testtool/win32/ExecutionPage.cpp +++ b/host/tools/testtool/win32/ExecutionPage.cpp @@ -22,7 +22,7 @@ // ---------------------------------------------------------------------------- // //####COPYRIGHTEND#### - // ExecutionPage.cpp : implementation file +// ExecutionPage.cpp : implementation file // #include "stdafx.h" #include "ExecutionPage.h" @@ -43,13 +43,14 @@ const UINT arIds []={IDC_TT_SELECT_ALL,I IMPLEMENT_DYNCREATE(CExecutionPage, CeCosPropertyPage) CExecutionPage::CExecutionPage() : - CeCosPropertyPage(IDD_TT_EXECUTION_PAGE) + CeCosPropertyPage(IDD_TT_EXECUTION_PAGE), + m_strExtension(_T("*.exe")) { - GetCurrentDirectory(MAX_PATH,m_strFolder.GetBuffer(MAX_PATH)); - m_strFolder.ReleaseBuffer(); - //{{AFX_DATA_INIT(CExecutionPage) + GetCurrentDirectory(MAX_PATH,m_strFolder.GetBuffer(MAX_PATH)); + m_strFolder.ReleaseBuffer(); + //{{AFX_DATA_INIT(CExecutionPage) // NOTE: the ClassWizard will add member initialization here - //}}AFX_DATA_INIT + //}}AFX_DATA_INIT } CExecutionPage::~CExecutionPage() @@ -58,24 +59,24 @@ CExecutionPage::~CExecutionPage() void CExecutionPage::DoDataExchange(CDataExchange* pDX) { - CeCosPropertyPage::DoDataExchange(pDX); - //{{AFX_DATA_MAP(CExecutionPage) - DDX_Control(pDX, IDC_TT_RUNTESTS_LIST, m_List); - //}}AFX_DATA_MAP + CeCosPropertyPage::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CExecutionPage) + DDX_Control(pDX, IDC_TT_RUNTESTS_LIST, m_List); + //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CExecutionPage, CeCosPropertyPage) - //{{AFX_MSG_MAP(CExecutionPage) - ON_BN_CLICKED(IDC_TT_FOLDER, OnFolder) - ON_BN_CLICKED(IDC_TT_SELECT_ALL, OnSelectAll) - ON_BN_CLICKED(IDC_TT_UNSELECT_ALL, OnUnselectAll) - ON_BN_CLICKED(IDC_TT_ADD, OnAdd) - ON_BN_CLICKED(IDC_TT_REMOVE, OnRemove) - ON_WM_SIZE() - ON_MESSAGE(WM_KICKIDLE, OnKickIdle) - ON_WM_CHAR() - //}}AFX_MSG_MAP +//{{AFX_MSG_MAP(CExecutionPage) +ON_BN_CLICKED(IDC_TT_FOLDER, OnFolder) +ON_BN_CLICKED(IDC_TT_SELECT_ALL, OnSelectAll) +ON_BN_CLICKED(IDC_TT_UNSELECT_ALL, OnUnselectAll) +ON_BN_CLICKED(IDC_TT_ADD, OnAdd) +ON_BN_CLICKED(IDC_TT_REMOVE, OnRemove) +ON_WM_SIZE() +ON_MESSAGE(WM_KICKIDLE, OnKickIdle) +ON_WM_CHAR() +//}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// @@ -83,118 +84,122 @@ END_MESSAGE_MAP() CExecutionPage *CExecutionPage::pDlg=NULL; LRESULT CALLBACK CExecutionPage::WindowProcNew(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam) { - if (message == WM_COMMAND) { - switch(wParam){ - case MAKEWPARAM(IDC_TT_RECURSE,BN_CLICKED): - pDlg->m_bRecurse ^= 1; - pDlg->m_Button.SetCheck(pDlg->m_bRecurse); - return 0; - case MAKEWPARAM(IDC_TT_EXTENSION,EN_CHANGE): - pDlg->m_Combo.GetWindowText(pDlg->m_strExtension); - return 0; - default: - break; - } - } - return CallWindowProc(pDlg->m_wndProc, hwnd, message, wParam, lParam); + if (message == WM_COMMAND) { + switch(wParam){ + case MAKEWPARAM(IDC_TT_RECURSE,BN_CLICKED): + pDlg->m_bRecurse ^= 1; + pDlg->m_Button.SetCheck(pDlg->m_bRecurse); + return 0; + case MAKEWPARAM(IDC_TT_EXTENSION,EN_CHANGE): + { + CString str; + pDlg->m_Combo.GetWindowText(str); + pDlg->m_strExtension=(LPCTSTR)str; + } + return 0; + default: + break; + } + } + return CallWindowProc(pDlg->m_wndProc, hwnd, message, wParam, lParam); } - + int CALLBACK CExecutionPage::CBBrowseCallbackProc( HWND hwnd, - UINT uMsg, - LPARAM lParam, - LPARAM lpData - ) + UINT uMsg, + LPARAM lParam, + LPARAM lpData + ) { - pDlg=(CExecutionPage *)lpData; - switch(uMsg){ - case BFFM_INITIALIZED: - { - ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)(LPCTSTR)pDlg->m_strFolder); - CWnd *pWnd=CWnd::FromHandle(hwnd); - pWnd->SetWindowText(_T("Add Files from Folder")); - - // Get rect of IDCANCEL button to the right - CRect rect,rect1,rect2; - pWnd->GetDlgItem(IDCANCEL)->GetWindowRect(&rect1); - pWnd->GetWindowRect(&rect2); - int nDlgMargin=rect2.right-rect1.right; - int nButtonHeight=rect1.Height(); - rect.left=rect.top=nDlgMargin; - rect.right=rect.left+6*nButtonHeight; - rect.bottom=rect.top+(10*nButtonHeight)/14; - WPARAM wFont=(WPARAM)GetStockObject(DEFAULT_GUI_FONT); - pDlg->m_Button.CreateEx(0,_T("BUTTON"),NULL, WS_VISIBLE|WS_CHILD|BS_CHECKBOX, rect, pWnd, IDC_TT_RECURSE); - pDlg->m_Button.SetWindowText(_T("&Add from subfolders")); - pDlg->m_Button.SendMessage(WM_SETFONT, wFont, 0); - pDlg->m_Button.SetCheck(pDlg->m_bRecurse); - - rect.left=rect.right+(4*nButtonHeight)/14; - rect.right=rect.left+3*nButtonHeight; - rect.bottom+=2*GetSystemMetrics(SM_CYBORDER)+4; - pDlg->m_Static.Create(_T("Files of type:"),WS_VISIBLE|WS_CHILD|SS_LEFT, rect, pWnd); - pDlg->m_Static.SendMessage(WM_SETFONT, wFont, 0); - rect.bottom-=2*GetSystemMetrics(SM_CYBORDER)+4; - - rect.left=rect.right+(4*nButtonHeight)/14; - rect.right=rect.left+3*nButtonHeight; - //rect.bottom=rect.top+2*nButtonHeight; - rect.top=rect.bottom-(12*nButtonHeight)/14; - pDlg->m_Combo.CreateEx(WS_EX_CLIENTEDGE,_T("Edit"),NULL,WS_VISIBLE|WS_CHILD|WS_BORDER|ES_LEFT/*|CBS_DROPDOWN*/, rect, pWnd, IDC_TT_EXTENSION); - //pDlg->m_Combo.AddString(pDlg->m_strExtension); - //pDlg->m_Combo.SetCurSel(0); - pDlg->m_Combo.SetWindowText(pDlg->m_strExtension); - pDlg->m_Combo.SendMessage(WM_SETFONT, wFont, 0); - - pDlg->m_wndProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (long)WindowProcNew); - - } - case BFFM_SELCHANGED: - { - // Change the cwd such that if the New button is used, we know where we are to start from - ITEMIDLIST *iil=(ITEMIDLIST *)lParam; - CString strFolder; - SHGetPathFromIDList(iil,strFolder.GetBuffer(MAX_PATH)); - strFolder.ReleaseBuffer(); - SetCurrentDirectory(strFolder); - } - break; - default: - ; + pDlg=(CExecutionPage *)lpData; + switch(uMsg){ + case BFFM_INITIALIZED: + { + ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)(LPCTSTR)pDlg->m_strFolder); + CWnd *pWnd=CWnd::FromHandle(hwnd); + pWnd->SetWindowText(_T("Add Files from Folder")); + + // Get rect of IDCANCEL button to the right + CRect rect,rect1,rect2; + pWnd->GetDlgItem(IDCANCEL)->GetWindowRect(&rect1); + pWnd->GetWindowRect(&rect2); + int nDlgMargin=rect2.right-rect1.right; + int nButtonHeight=rect1.Height(); + rect.left=rect.top=nDlgMargin; + rect.right=rect.left+6*nButtonHeight; + rect.bottom=rect.top+(10*nButtonHeight)/14; + WPARAM wFont=(WPARAM)GetStockObject(DEFAULT_GUI_FONT); + pDlg->m_Button.CreateEx(0,_T("BUTTON"),NULL, WS_VISIBLE|WS_CHILD|BS_CHECKBOX, rect, pWnd, IDC_TT_RECURSE); + pDlg->m_Button.SetWindowText(_T("&Add from subfolders")); + pDlg->m_Button.SendMessage(WM_SETFONT, wFont, 0); + pDlg->m_Button.SetCheck(pDlg->m_bRecurse); + + rect.left=rect.right+(4*nButtonHeight)/14; + rect.right=rect.left+3*nButtonHeight; + rect.bottom+=2*GetSystemMetrics(SM_CYBORDER)+4; + pDlg->m_Static.Create(_T("Files of type:"),WS_VISIBLE|WS_CHILD|SS_LEFT, rect, pWnd); + pDlg->m_Static.SendMessage(WM_SETFONT, wFont, 0); + rect.bottom-=2*GetSystemMetrics(SM_CYBORDER)+4; + + rect.left=rect.right+(4*nButtonHeight)/14; + rect.right=rect.left+3*nButtonHeight; + //rect.bottom=rect.top+2*nButtonHeight; + rect.top=rect.bottom-(12*nButtonHeight)/14; + pDlg->m_Combo.CreateEx(WS_EX_CLIENTEDGE,_T("Edit"),NULL,WS_VISIBLE|WS_CHILD|WS_BORDER|ES_LEFT/*|CBS_DROPDOWN*/, rect, pWnd, IDC_TT_EXTENSION); + //pDlg->m_Combo.AddString(pDlg->m_strExtension); + //pDlg->m_Combo.SetCurSel(0); + pDlg->m_Combo.SetWindowText(pDlg->m_strExtension); + pDlg->m_Combo.SendMessage(WM_SETFONT, wFont, 0); + + pDlg->m_wndProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (long)WindowProcNew); + } - - return 0; + case BFFM_SELCHANGED: + { + // Change the cwd such that if the New button is used, we know where we are to start from + ITEMIDLIST *iil=(ITEMIDLIST *)lParam; + CString strFolder; + SHGetPathFromIDList(iil,strFolder.GetBuffer(MAX_PATH)); + strFolder.ReleaseBuffer(); + SetCurrentDirectory(strFolder); + } + break; + default: + ; + } + + return 0; } void CExecutionPage::OnFolder() { - - BROWSEINFO bi; - bi.hwndOwner = GetSafeHwnd(); - bi.pidlRoot = NULL; - bi.pszDisplayName = m_strFolder.GetBuffer(MAX_PATH); - bi.lpszTitle = _T(""); - bi.ulFlags = BIF_RETURNONLYFSDIRS|BIF_STATUSTEXT/*|0x0010 BIF_EDITBOX*/; - bi.lpfn = (BFFCALLBACK)CBBrowseCallbackProc; - bi.lParam = (LPARAM)this; - - bool bSaveRecurse=m_bRecurse; - LPITEMIDLIST iil = SHBrowseForFolder(&bi); - m_strFolder.ReleaseBuffer(); - if(iil){ - SHGetPathFromIDList(iil,m_strFolder.GetBuffer(MAX_PATH)); - m_strFolder.ReleaseBuffer(); - SetModified(); - FillListBox(m_strFolder); - } else { - m_bRecurse=bSaveRecurse; - } - + + BROWSEINFO bi; + bi.hwndOwner = GetSafeHwnd(); + bi.pidlRoot = NULL; + bi.pszDisplayName = m_strFolder.GetBuffer(MAX_PATH); + bi.lpszTitle = _T(""); + bi.ulFlags = BIF_RETURNONLYFSDIRS|BIF_STATUSTEXT/*|0x0010 BIF_EDITBOX*/; + bi.lpfn = (BFFCALLBACK)CBBrowseCallbackProc; + bi.lParam = (LPARAM)this; + + bool bSaveRecurse=m_bRecurse; + LPITEMIDLIST iil = SHBrowseForFolder(&bi); + m_strFolder.ReleaseBuffer(); + if(iil){ + SHGetPathFromIDList(iil,m_strFolder.GetBuffer(MAX_PATH)); + m_strFolder.ReleaseBuffer(); + SetModified(); + FillListBox(m_strFolder); + } else { + m_bRecurse=bSaveRecurse; + } + } /* void CExecutionPage::OnRefresh() { - FillListBox(m_strFolder); +FillListBox(m_strFolder); } */ @@ -240,21 +245,21 @@ void CExecutionPage::FillListBox(LPCTSTR void CExecutionPage::OnSelectAll() { - for(int i=0;i0){ - bool bPrev=false; - for(int i=0;i0 && bCheck!=bPrev){ - break; - } - bPrev=bCheck; - } + if(IsWindow(m_List.m_hWnd)){ + int n=m_List.GetCount(); + bool bSelectAll=false; + bool bUnSelectAll=false; + if(n>0){ + bool bPrev=false; + for(int i=0;iEnableWindow(bSelectAll); - GetDlgItem(IDC_TT_UNSELECT_ALL)->EnableWindow(bUnSelectAll); + if(i>0 && bCheck!=bPrev){ + break; + } + bPrev=bCheck; + } } - return 0; + GetDlgItem(IDC_TT_SELECT_ALL)->EnableWindow(bSelectAll); + GetDlgItem(IDC_TT_UNSELECT_ALL)->EnableWindow(bUnSelectAll); + } + return 0; } bool CExecutionPage::SomeTestsSelected() { - bool b=0; - if(IsWindow(m_List.m_hWnd)){ - for(int i=0;iEnableWindow(false); } CMapStringToPtr map; - for(unsigned int i=0;iPrefix(),this); } for(POSITION pos = map.GetStartPosition(); pos != NULL; ){ void *p; @@ -109,3 +115,10 @@ void CPlatformDialog::OnChangeNewPlatfor UpdateData(true); GetDlgItem(IDOK)->EnableWindow(!m_strPlatform.IsEmpty() && !m_strPrefix.IsEmpty()); } + +void CPlatformDialog::OnOK() +{ + UpdateData(TRUE); + m_strGDB.Replace(_T("\r\n"),_T(";")); + EndDialog(IDOK); +} diff --git a/host/tools/testtool/win32/PlatformDialog.h b/host/tools/testtool/win32/PlatformDialog.h --- a/host/tools/testtool/win32/PlatformDialog.h +++ b/host/tools/testtool/win32/PlatformDialog.h @@ -49,7 +49,9 @@ public: CString m_strPlatform; CString m_strPrefix; CString m_strGDB; - int m_nType; + CString m_strInferior; + CString m_strPrompt; + BOOL m_bServerSideGdb; //}}AFX_DATA @@ -68,6 +70,7 @@ protected: virtual BOOL OnInitDialog(); afx_msg void OnChangeNewPlatformPrefix(); afx_msg void OnChangeNewPlatform(); + virtual void OnOK(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; diff --git a/host/tools/testtool/win32/PlatformsDialog.cpp b/host/tools/testtool/win32/PlatformsDialog.cpp --- a/host/tools/testtool/win32/PlatformsDialog.cpp +++ b/host/tools/testtool/win32/PlatformsDialog.cpp @@ -87,17 +87,21 @@ BOOL CPlatformsDialog::OnInitDialog() m_List.InsertColumn(0,_T("Target")); m_List.InsertColumn(1,_T("Prefix")); - m_List.InsertColumn(2,_T("GDB commands")); - m_List.InsertColumn(3,_T("Type")); - for(unsigned int i=0;iEnableWindow(bSel); @@ -115,7 +119,7 @@ void CPlatformsDialog::OnAddPlatform() fi.flags=LVFI_STRING; fi.psz=dlg.m_strPlatform; if(-1==m_List.FindItem(&fi)){ - Add(CeCosTest::TargetInfo(dlg.m_strPlatform,dlg.m_strPrefix,dlg.m_nType,dlg.m_strGDB)); + Add(CeCosTestPlatform(dlg.m_strPlatform,dlg.m_strPrefix,dlg.m_strPrompt,dlg.m_strGDB,dlg.m_bServerSideGdb,dlg.m_strInferior)); } else { MessageBox(_T("That platform name is already in use.")); } @@ -136,15 +140,16 @@ void CPlatformsDialog::OnDeletePlatform( } } -void CPlatformsDialog::Add(const CeCosTest::TargetInfo &ti) +void CPlatformsDialog::Add(const CeCosTestPlatform &ti) { int i=m_List.GetItemCount(); - CeCosTest::TargetInfo *pti=new CeCosTest::TargetInfo(ti); - m_List.InsertItem(i,CeCosTest::Image(i)); - m_List.SetItemText(i,1,pti->Prefix()); - m_List.SetItemText(i,2,pti->GdbCmd()); - m_List.SetItemText(i,3,arpszTypes[pti->Type()]); - m_arTargetInfo.Add(pti); + m_List.InsertItem(i,ti.Name()); + m_List.SetItemText(i,1,ti.Prefix()); + m_List.SetItemText(i,2,ti.GdbCmds()); + m_List.SetItemText(i,3,ti.Inferior()); + m_List.SetItemText(i,4,ti.Prompt()); + m_List.SetItemText(i,5,ti.ServerSideGdb()?_T("y"):_T("n")); + m_arTargetInfo.Add(new CeCosTestPlatform(ti)); } void CPlatformsDialog::OnDblclkPlatformList(NMHDR*, LRESULT* pResult) @@ -158,18 +163,22 @@ void CPlatformsDialog::OnModifyPlatform( POSITION pos = m_List.GetFirstSelectedItemPosition(); if(pos){ int nIndex= m_List.GetNextSelectedItem(pos); - CeCosTest::TargetInfo *pti=Platform(nIndex); + CeCosTestPlatform *pti=Platform(nIndex); CPlatformDialog dlg; - dlg.m_strPlatform=pti->Image(); + dlg.m_strPlatform=pti->Name(); dlg.m_strPrefix=pti->Prefix(); - dlg.m_strGDB=pti->GdbCmd(); - dlg.m_nType=pti->Type(); + dlg.m_strGDB=pti->GdbCmds(); dlg.m_strCaption=_T("Modify"); + dlg.m_strPrompt=pti->Prompt(); + dlg.m_bServerSideGdb=pti->ServerSideGdb(); + dlg.m_strInferior=pti->Inferior(); if(IDCANCEL!=dlg.DoModal()){ - *pti=CeCosTest::TargetInfo(dlg.m_strPlatform,dlg.m_strPrefix,dlg.m_nType,dlg.m_strGDB); + *pti=CeCosTestPlatform(dlg.m_strPlatform,dlg.m_strPrefix,dlg.m_strPrompt,dlg.m_strGDB,dlg.m_bServerSideGdb,dlg.m_strInferior); m_List.SetItemText(nIndex,1,pti->Prefix()); - m_List.SetItemText(nIndex,2,pti->GdbCmd()); - m_List.SetItemText(nIndex,3,arpszTypes[pti->Type()]); + m_List.SetItemText(nIndex,2,pti->GdbCmds()); + m_List.SetItemText(nIndex,3,pti->Inferior()); + m_List.SetItemText(nIndex,4,pti->Prompt()); + m_List.SetItemText(nIndex,5,pti->ServerSideGdb()?_T("Y"):_T("N")); } } } diff --git a/host/tools/testtool/win32/PlatformsDialog.h b/host/tools/testtool/win32/PlatformsDialog.h --- a/host/tools/testtool/win32/PlatformsDialog.h +++ b/host/tools/testtool/win32/PlatformsDialog.h @@ -42,10 +42,10 @@ class CPlatformsDialog : public CeCosDia // Construction static const LPCTSTR arpszTypes[]; public: - CeCosTest::TargetInfo *Platform (int i) { return (CeCosTest::TargetInfo *)m_arTargetInfo[i]; } + CeCosTestPlatform *Platform (int i) { return (CeCosTestPlatform *)m_arTargetInfo[i]; } unsigned int PlatformCount() const { return m_arTargetInfo.GetSize(); } CPlatformsDialog(CWnd* pParent = NULL); // standard constructor - void Add(const CeCosTest::TargetInfo &ti); + void Add(const CeCosTestPlatform &ti); // Dialog Data //{{AFX_DATA(CPlatformsDialog) diff --git a/host/tools/testtool/win32/PropertiesDialog.cpp b/host/tools/testtool/win32/PropertiesDialog.cpp --- a/host/tools/testtool/win32/PropertiesDialog.cpp +++ b/host/tools/testtool/win32/PropertiesDialog.cpp @@ -26,8 +26,8 @@ // #include "stdafx.h" -#include "eCosTest.h" -#include "eCosTestSocket.h" +#include "eCosTestPlatform.h" +#include "eCosSocket.h" #include "PropertiesDialog.h" #include "LocalPropertiesDialog.h" #include "RemotePropertiesDialog.h" @@ -163,8 +163,8 @@ BOOL CPropertiesDialog::OnInitDialog() CeCosDialog::OnInitDialog(); CComboBox *pCombo=(CComboBox *)GetDlgItem(IDC_TT_PLATFORM); - for(unsigned int i=0;iAddString(CeCosTest::Image(i)); + for(unsigned int i=0;iAddString(CeCosTestPlatform::Get(i)->Name()); } UpdateData(false); @@ -189,22 +189,21 @@ void CPropertiesDialog::OnSelchangePlatf void CPropertiesDialog::SetButtons() { - CString strTarget; - GetDlgItemText(IDC_TT_PLATFORM,strTarget); - bool bSim=CeCosTest::IsSim(strTarget); - static const int arIDs[]={IDC_TT_DOWNLOADTIMEOUT,IDC_TT_SPIN4,IDC_TT_DOWNLOADTIMEOUT_COMBO}; - for(int i=0;iEnableWindow(!bSim); - } - GetDlgItem(IDC_TT_SETTINGS)->EnableWindow(!bSim || !((CButton *)GetDlgItem(IDC_TT_RADIO_LOCAL))->GetCheck()); - - bool b=(TIMEOUT_SPECIFIED==((CComboBox*)GetDlgItem(IDC_TT_TIMEOUT_COMBO))->GetCurSel()); - GetDlgItem(IDC_TT_TESTTIMEOUT)->EnableWindow(b); - GetDlgItem(IDC_TT_SPIN3)->EnableWindow(b); - - b=(TIMEOUT_SPECIFIED==((CComboBox*)GetDlgItem(IDC_TT_DOWNLOADTIMEOUT_COMBO))->GetCurSel()); - GetDlgItem(IDC_TT_DOWNLOADTIMEOUT)->EnableWindow(!bSim && b); - GetDlgItem(IDC_TT_SPIN4)->EnableWindow(!bSim && b); + CString strTarget; + GetDlgItemText(IDC_TT_PLATFORM,strTarget); + static const int arIDs[]={IDC_TT_DOWNLOADTIMEOUT,IDC_TT_SPIN4,IDC_TT_DOWNLOADTIMEOUT_COMBO}; + for(int i=0;iEnableWindow(true); + } + //GetDlgItem(IDC_TT_SETTINGS)->EnableWindow(!bSim || !((CButton *)GetDlgItem(IDC_TT_RADIO_LOCAL))->GetCheck()); + + bool b=(TIMEOUT_SPECIFIED==((CComboBox*)GetDlgItem(IDC_TT_TIMEOUT_COMBO))->GetCurSel()); + GetDlgItem(IDC_TT_TESTTIMEOUT)->EnableWindow(b); + GetDlgItem(IDC_TT_SPIN3)->EnableWindow(b); + + b=(TIMEOUT_SPECIFIED==((CComboBox*)GetDlgItem(IDC_TT_DOWNLOADTIMEOUT_COMBO))->GetCurSel()); + GetDlgItem(IDC_TT_DOWNLOADTIMEOUT)->EnableWindow(b); + GetDlgItem(IDC_TT_SPIN4)->EnableWindow(b); } void CPropertiesDialog::OnSettings() diff --git a/host/tools/testtool/win32/RemotePropertiesDialog.cpp b/host/tools/testtool/win32/RemotePropertiesDialog.cpp --- a/host/tools/testtool/win32/RemotePropertiesDialog.cpp +++ b/host/tools/testtool/win32/RemotePropertiesDialog.cpp @@ -27,7 +27,7 @@ #include "stdafx.h" #include "RemotePropertiesDialog.h" -#include "eCosTestSocket.h" +#include "eCosSocket.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -110,9 +110,9 @@ BOOL CRemotePropertiesDialog::OnInitDial void CRemotePropertiesDialog::OnOK() { UpdateData(); - if(m_bFarmed && !CeCosTestSocket::IsLegalHostPort(CeCosTestSocket::HostPort(m_strResourceHost,m_nResourcePort))){ + if(m_bFarmed && !CeCosSocket::IsLegalHostPort(CeCosSocket::HostPort(m_strResourceHost,m_nResourcePort))){ MessageBox(_T("Please provide a valid host/port combination for resource server")); - } else if (!m_bFarmed && !CeCosTestSocket::IsLegalHostPort(CeCosTestSocket::HostPort(m_strRemoteHost,m_nRemotePort))){ + } else if (!m_bFarmed && !CeCosSocket::IsLegalHostPort(CeCosSocket::HostPort(m_strRemoteHost,m_nRemotePort))){ MessageBox(_T("Please provide a valid host/port combination for remote execution")); } else { CeCosDialog::OnOK(); diff --git a/host/tools/testtool/win32/RunTestsSheet.cpp b/host/tools/testtool/win32/RunTestsSheet.cpp --- a/host/tools/testtool/win32/RunTestsSheet.cpp +++ b/host/tools/testtool/win32/RunTestsSheet.cpp @@ -28,6 +28,7 @@ #include "stdafx.h" #include "eCosTest.h" +#include "eCosThreadUtils.h" #include "eCosTrace.h" #include "PropertiesDialog.h" #include "ResetAttributes.h" @@ -63,9 +64,20 @@ CRunTestsSheet::CRunTestsSheet(LPCTSTR p m_bHideTarget(false), m_bHideRemoteControls(false), m_bModal(false), - m_prop(_T("Software\\Red Hat\\eCos\\RunTests"),HKEY_CURRENT_USER), m_ppSheet(ppSheet), - m_ep(CeCosTest::ExecutionParameters::RUN) + m_ep(CeCosTest::ExecutionParameters::RUN), + m_nTimeout(900), + m_nDownloadTimeout(120), + m_nTimeoutType(TIMEOUT_AUTOMATIC), + m_nDownloadTimeoutType(TIMEOUT_AUTOMATIC), + m_bSerial(true), + m_strPort(_T("COM1")), + m_nBaud(38400), + m_nLocalTCPIPPort(1), + m_nReset(RESET_MANUAL), + m_nResourcePort(1), + m_nRemotePort(1), + m_bFarmed(true) { InitializeCriticalSection(&m_CS); AddPage(&executionpage); @@ -106,29 +118,28 @@ END_MESSAGE_MAP() BOOL CRunTestsSheet::OnInitDialog() { if(!m_bHideTarget){ - m_prop.Add(_T("Platform"),(void *)&m_strTarget,GetFn,PutFn); + m_prop.Add(_T("Platform"),m_strTarget); } - m_prop.Add(_T("Active timeout"),m_nTimeout,900); - m_prop.Add(_T("Download timeout"),m_nDownloadTimeout,120); - m_prop.Add(_T("Active timeout type"),m_nTimeoutType,TIMEOUT_AUTOMATIC); - m_prop.Add(_T("Download timeout type"),m_nDownloadTimeoutType,TIMEOUT_AUTOMATIC); + m_prop.Add(_T("Active timeout"),m_nTimeout); + m_prop.Add(_T("Download timeout"),m_nDownloadTimeout); + m_prop.Add(_T("Active timeout type"),m_nTimeoutType); + m_prop.Add(_T("Download timeout type"),m_nDownloadTimeoutType); m_prop.Add(_T("Remote"),m_bRemote); - m_prop.Add(_T("Serial"),m_bSerial,true); - m_prop.Add(_T("Port"),(void *)&m_strPort,GetFn,PutFn,_T("COM1")); - m_prop.Add(_T("Baud"),m_nBaud,38400); - m_prop.Add(_T("Local TCPIP Host"),(void *)&m_strLocalTCPIPHost,GetFn,PutFn); - m_prop.Add(_T("Local TCPIP Port"),m_nLocalTCPIPPort,1); - m_prop.Add(_T("Reset Type"),m_nReset,RESET_MANUAL); - m_prop.Add(_T("Reset String"),(void *)&m_strReset,GetFn,PutFn); - m_prop.Add(_T("Resource Host"),(void *)&m_strResourceHost,GetFn,PutFn); - m_prop.Add(_T("Resource Port"),m_nResourcePort,1); - m_prop.Add(_T("Remote Host"),(void *)&m_strRemoteHost,GetFn,PutFn); - m_prop.Add(_T("Remote Port"),m_nRemotePort,1); + m_prop.Add(_T("Serial"),m_bSerial); + m_prop.Add(_T("Port"),m_strPort); + m_prop.Add(_T("Baud"),m_nBaud); + m_prop.Add(_T("Local TCPIP Host"),m_strLocalTCPIPHost); + m_prop.Add(_T("Local TCPIP Port"),m_nLocalTCPIPPort); + m_prop.Add(_T("Reset Type"),m_nReset); + m_prop.Add(_T("Reset String"),m_strReset); + m_prop.Add(_T("Resource Host"),m_strResourceHost); + m_prop.Add(_T("Resource Port"),m_nResourcePort); + m_prop.Add(_T("Remote Host"),m_strRemoteHost); + m_prop.Add(_T("Remote Port"),m_nRemotePort); m_prop.Add(_T("Recurse"),executionpage.m_bRecurse); //m_prop.Add(_T("Loadfromdir"),executionpage.m_strLoaddir); - m_prop.Add(_T("Farmed"),m_bFarmed,true); - m_prop.Add(_T("Extension"),(void *)&executionpage.m_strExtension,GetFn,PutFn,_T("*.exe")); - m_prop.SetDefaults(); + m_prop.Add(_T("Farmed"),m_bFarmed); + m_prop.Add(_T("Extension"),executionpage.m_strExtension); CeCosTrace::SetOutput(TestOutputCallback,this); CeCosTrace::SetError (TestOutputCallback,this); @@ -142,7 +153,7 @@ BOOL CRunTestsSheet::OnInitDialog() } GetWindowRect(m_rcPrev); #ifdef _DEBUG - CeCosTrace::EnableTracing(true); + CeCosTrace::EnableTracing(CeCosTrace::TRACE_LEVEL_TRACE); #endif CeCosTrace::SetInteractive(true); @@ -280,23 +291,21 @@ void CRunTestsSheet::OnRun() TIMEOUT_NONE==m_nTimeoutType?0x7fffffff:TIMEOUT_AUTOMATIC==m_nTimeoutType?0:1000*m_nTimeout, TIMEOUT_NONE==m_nDownloadTimeoutType?0x7fffffff:TIMEOUT_AUTOMATIC==m_nDownloadTimeoutType?0:1000*m_nDownloadTimeout); if(m_bRemote){ - CTestResource::SetResourceServer(m_strResourceHost,m_nResourcePort); - if(!CTestResource::LoadSocket()){ + CTestResource::SetResourceServer(CeCosSocket::HostPort(m_strResourceHost,m_nResourcePort)); + if(!CTestResource::Load()){ MessageBox(_T("Could not connect to resource server")); return; } } else { - if(CeCosTest::IsSim(m_ep.Target())){ - //for(int i=0;ipSheet->m_pResource->Reset(str); - if(CResetAttributes::RESET_OK==n){ - str+=_TCHAR('\n'); - if(CResetAttributes::IsValidReset((void *)(LPCTSTR )str)){ - str+=_T(">>> Reset ok\n"); - bOk=true; - } else { - str+=_T(">>> Could not reset target (no valid startup string seen)\n"); - } - } else { - String str; - str+=_T(">>> Could not reset target - X10 error - "); - str+=CResetAttributes::Image(n); - str+=_TCHAR('\n'); + if(CResetAttributes::RESET_OK!=n){ + str+=_T(">>> Could not reset target\n"); } - LPTSTR pszCopy=new TCHAR[1+str.GetLength()]; + str+=_TCHAR('\n'); + LPTSTR pszCopy=new TCHAR[1+str.size()]; _tcscpy(pszCopy,str); pInfo->pSheet->PostMessage(WM_TESTOUTPUT,(WPARAM)pszCopy,0); @@ -371,29 +370,25 @@ void CRunTestsSheet::SubmitTests() CeCosThreadUtils::RunThread(RunRemoteFunc,pInfo,RunCallback,_T("RunRemoteFunc")); } else { bool bRun=false; - if(CeCosTest::IsSim(m_ep.Target())){ - bRun=true; - } else { - switch((ResetType)m_nReset){ - case RESET_NONE: - bRun=true; - break; - case RESET_X10: - // Resetting can take a while, so spawn a thread - bRun=false; - { - DWORD dwID; - CloseHandle(CreateThread(0,0,X10ThreadFunc, pInfo, 0, &dwID)); - } - break; - case RESET_MANUAL: - bRun=(IDOK==MessageBox(_T("Press OK when target is reset - cancel to abort run"),NULL,MB_OKCANCEL)); - if(!bRun){ - m_nNextToSubmit=executionpage.SelectedTestCount(); - RunCallback(pInfo); - } - break; + switch((ResetType)m_nReset){ + case RESET_NONE: + bRun=true; + break; + case RESET_X10: + // Resetting can take a while, so spawn a thread + bRun=false; + { + DWORD dwID; + CloseHandle(CreateThread(0,0,X10ThreadFunc, pInfo, 0, &dwID)); } + break; + case RESET_MANUAL: + bRun=(IDOK==MessageBox(_T("Press OK when target is reset - cancel to abort run"),NULL,MB_OKCANCEL)); + if(!bRun){ + m_nNextToSubmit=executionpage.SelectedTestCount(); + RunCallback(pInfo); + } + break; } if(bRun){ CeCosThreadUtils::RunThread(RunLocalFunc,pInfo,RunCallback,_T("RunLocalFunc")); @@ -479,22 +474,22 @@ void CRunTestsSheet::OnProperties() dlg.m_strPort=m_strPort; dlg.m_bFarmed=m_bFarmed; if(IDOK==dlg.DoModal()){ - m_strTarget=dlg.m_strTarget; + m_strTarget=(LPCTSTR)dlg.m_strTarget; m_nTimeout=dlg.m_nTimeout; m_nDownloadTimeout=dlg.m_nDownloadTimeout; m_nTimeoutType=dlg.m_nTimeoutType; m_nDownloadTimeoutType=dlg.m_nDownloadTimeoutType; m_bRemote=dlg.m_bRemote; m_bSerial=dlg.m_bSerial; - m_strPort=dlg.m_strPort; + m_strPort=(LPCTSTR)dlg.m_strPort; m_nBaud=dlg.m_nBaud; - m_strLocalTCPIPHost=dlg.m_strLocalTCPIPHost; + m_strLocalTCPIPHost=(LPCTSTR)dlg.m_strLocalTCPIPHost; m_nLocalTCPIPPort=dlg.m_nLocalTCPIPPort; m_nReset=dlg.m_nReset; - m_strReset=dlg.m_strReset; - m_strResourceHost=dlg.m_strResourceHost; + m_strReset=(LPCTSTR)dlg.m_strReset; + m_strResourceHost=(LPCTSTR)dlg.m_strResourceHost; m_nResourcePort=dlg.m_nResourcePort; - m_strRemoteHost=dlg.m_strRemoteHost; + m_strRemoteHost=(LPCTSTR)dlg.m_strRemoteHost; m_nRemotePort=dlg.m_nRemotePort; m_bFarmed=dlg.m_bFarmed; if(m_pInitFunc){ diff --git a/host/tools/testtool/win32/RunTestsSheet.h b/host/tools/testtool/win32/RunTestsSheet.h --- a/host/tools/testtool/win32/RunTestsSheet.h +++ b/host/tools/testtool/win32/RunTestsSheet.h @@ -56,7 +56,7 @@ public: public: protected: CeCosTest::ExecutionParameters m_ep; - CString m_strTarget; + String m_strTarget; int m_nTimeout; int m_nDownloadTimeout; int m_nTimeoutType; @@ -64,12 +64,12 @@ protected: bool m_bRemote; bool m_bSerial; int m_nBaud; - CString m_strLocalTCPIPHost; + String m_strLocalTCPIPHost; int m_nLocalTCPIPPort; int m_nReset; - CString m_strResourceHost; + String m_strResourceHost; int m_nResourcePort; - CString m_strReset; + String m_strReset; static void CALLBACK RunLocalFunc(void *pParam); static void CALLBACK RunRemoteFunc(void *pParam); @@ -105,7 +105,7 @@ protected: bool m_bHideTarget; UINT m_nRemotePort; bool m_bFarmed; - CString m_strPort; + String m_strPort; int m_cyMin; int m_cxMin; CRect m_rcPrev,m_rcOffset; @@ -123,14 +123,12 @@ protected: public: void Populate (LPCTSTR pszFile,bool bSelect=true); void HideRemoteControls(); - CString m_strRemoteHost; + String m_strRemoteHost; private: - static LPCTSTR CALLBACK GetFn (void *pObj) { return (LPCTSTR)*(CString *)pObj; } - static void CALLBACK PutFn (void *pObj,LPCTSTR psz) { *(CString *)pObj=psz; } COutputPage outputpage; CSummaryPage summarypage; //{{AFX_MSG(CRunTestsSheet) - afx_msg void OnRun(); + afx_msg void OnRun(); afx_msg void OnProperties(); afx_msg void OnClose(); afx_msg LRESULT OnTestOutput(WPARAM wParam, LPARAM lParam); diff --git a/host/tools/testtool/win32/SummaryPage.cpp b/host/tools/testtool/win32/SummaryPage.cpp --- a/host/tools/testtool/win32/SummaryPage.cpp +++ b/host/tools/testtool/win32/SummaryPage.cpp @@ -80,32 +80,32 @@ END_MESSAGE_MAP() void CSummaryPage::AddResult(CeCosTest *pTest) { - CString strResult=pTest->ResultString(false); - int nLength=strResult.GetLength(); - CString arstr[8]; - CString strTime,strDate; - TRACE(_T("%s\n"),strResult); - // 1999-05-28 10:29:28 nan:0 TX39-jmr3904-sim tx39-jmr3904sim-libc10-signal2.exe Fail 0k/1108k D=0.0/0.0 Total=9.3 E=0.6/300.0 - _stscanf(strResult,_T("%s %s %s %s %s %s %s %s %s %s"),strDate.GetBuffer(1+nLength),strTime.GetBuffer(1+nLength),arstr[0].GetBuffer(1+nLength),arstr[1].GetBuffer(1+nLength),arstr[2].GetBuffer(1+nLength),arstr[3].GetBuffer(1+nLength),arstr[4].GetBuffer(1+nLength),arstr[5].GetBuffer(1+nLength),arstr[6].GetBuffer(1+nLength),arstr[7].GetBuffer(1+nLength)); - // Remove before '=' in time fields - for(int i=5;i<8;i++){ - TCHAR *pch=_tcschr(arstr[i],_TCHAR('=')); - if(pch){ - arstr[i]=pch+1; - } - } - - strDate.ReleaseBuffer(); - strTime.ReleaseBuffer(); - strDate+=_TCHAR(' '); - strDate+=strTime; - int nItem=m_List.GetItemCount(); - m_List.InsertItem(nItem,strDate); - m_List.SetItemData(nItem,nItem);// to support sorting - for(i=0;i<8;i++){ - m_List.SetItemText(nItem,1+i,arstr[i]); - arstr[i].ReleaseBuffer(); - } + const CString strResult((LPCTSTR)pTest->ResultString(false)); + int nLength=strResult.GetLength(); + CString arstr[8]; + CString strTime,strDate; + TRACE(_T("%s\n"),strResult); + // 1999-05-28 10:29:28 nan:0 TX39-jmr3904-sim tx39-jmr3904sim-libc10-signal2.exe Fail 0k/1108k D=0.0/0.0 Total=9.3 E=0.6/300.0 + _stscanf(strResult,_T("%s %s %s %s %s %s %s %s %s %s"),strDate.GetBuffer(1+nLength),strTime.GetBuffer(1+nLength),arstr[0].GetBuffer(1+nLength),arstr[1].GetBuffer(1+nLength),arstr[2].GetBuffer(1+nLength),arstr[3].GetBuffer(1+nLength),arstr[4].GetBuffer(1+nLength),arstr[5].GetBuffer(1+nLength),arstr[6].GetBuffer(1+nLength),arstr[7].GetBuffer(1+nLength)); + // Remove before '=' in time fields + for(int i=5;i<8;i++){ + TCHAR *pch=_tcschr(arstr[i],_TCHAR('=')); + if(pch){ + arstr[i]=pch+1; + } + } + + strDate.ReleaseBuffer(); + strTime.ReleaseBuffer(); + strDate+=_TCHAR(' '); + strDate+=strTime; + int nItem=m_List.GetItemCount(); + m_List.InsertItem(nItem,strDate); + m_List.SetItemData(nItem,nItem);// to support sorting + for(i=0;i<8;i++){ + m_List.SetItemText(nItem,1+i,arstr[i]); + arstr[i].ReleaseBuffer(); + } } BOOL CSummaryPage::OnInitDialog() diff --git a/host/tools/testtool/win32/TestTool.cpp b/host/tools/testtool/win32/TestTool.cpp --- a/host/tools/testtool/win32/TestTool.cpp +++ b/host/tools/testtool/win32/TestTool.cpp @@ -71,7 +71,8 @@ CRunTestsApp theApp; BOOL CRunTestsApp::InitInstance() { - CeCosTest::Init(); + CeCosSocket::Init(); + CeCosTestPlatform::Load(); CFileName strCSHFile; ::GetModuleFileName(::GetModuleHandle(NULL),strCSHFile.GetBuffer(1+MAX_PATH),MAX_PATH); strCSHFile.ReleaseBuffer(); @@ -123,7 +124,9 @@ BOOL CRunTestsApp::InitInstance() // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. - CeCosTest::Term(); + CeCosSocket::Term(); + CeCosTestPlatform::RemoveAllPlatforms(); + return FALSE; } @@ -131,10 +134,10 @@ void CALLBACK CRunTestsApp::InitFunc(CPr { static bool bFirstTime=true; if(bSave){ - pProp->Save(); + pProp->SaveToRegistry(HKEY_CURRENT_USER,_T("Software\\Red Hat\\eCos\\RunTests")); } else { pProp->LoadFromCommandString(GetCommandLine()); - pProp->Load(); + pProp->LoadFromRegistry(HKEY_CURRENT_USER,_T("Software\\Red Hat\\eCos\\RunTests")); } bFirstTime=false; } diff --git a/host/tools/testtool/win32/TestTool.dsp b/host/tools/testtool/win32/TestTool.dsp --- a/host/tools/testtool/win32/TestTool.dsp +++ b/host/tools/testtool/win32/TestTool.dsp @@ -128,6 +128,14 @@ SOURCE=..\..\Utils\win32\eCosPropertyShe # End Source File # Begin Source File +SOURCE=..\..\Utils\common\eCosSerial.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Utils\common\eCosSocket.cpp +# End Source File +# Begin Source File + SOURCE=..\..\Utils\common\eCosStd.cpp # End Source File # Begin Source File @@ -140,7 +148,7 @@ SOURCE=..\..\ecostest\common\eCosTestDow # End Source File # Begin Source File -SOURCE=..\..\ecostest\common\eCosTestSerial.cpp +SOURCE=..\..\ecostest\common\eCosTestPlatform.cpp # End Source File # Begin Source File @@ -148,10 +156,6 @@ SOURCE=..\..\ecostest\common\eCosTestSer # End Source File # Begin Source File -SOURCE=..\..\ecostest\common\eCosTestSocket.cpp -# End Source File -# Begin Source File - SOURCE=..\..\ecostest\common\eCosTestUtils.cpp # End Source File # Begin Source File @@ -216,7 +220,7 @@ SOURCE=.\StdAfx.cpp # End Source File # Begin Source File -SOURCE=..\..\Utils\win32\SubProcess.cpp +SOURCE=..\..\Utils\common\Subprocess.cpp # End Source File # Begin Source File @@ -289,6 +293,14 @@ SOURCE=..\..\Utils\win32\eCosPropertyShe # End Source File # Begin Source File +SOURCE=..\..\Utils\common\eCosSerial.h +# End Source File +# Begin Source File + +SOURCE=..\..\Utils\common\eCosSocket.h +# End Source File +# Begin Source File + SOURCE=..\..\Utils\common\eCosStd.h # End Source File # Begin Source File @@ -301,18 +313,10 @@ SOURCE=..\..\ecostest\common\eCosTestDow # End Source File # Begin Source File -SOURCE=..\..\ecostest\common\eCosTestSerial.h -# End Source File -# Begin Source File - SOURCE=..\..\ecostest\common\eCosTestSerialFilter.h # End Source File # Begin Source File -SOURCE=..\..\ecostest\common\eCosTestSocket.h -# End Source File -# Begin Source File - SOURCE=..\..\ecostest\common\eCosTestStd.h # End Source File # Begin Source File @@ -389,7 +393,7 @@ SOURCE=.\StdAfx.h # End Source File # Begin Source File -SOURCE=..\..\Utils\win32\SubProcess.h +SOURCE=..\..\Utils\common\Subprocess.h # End Source File # Begin Source File diff --git a/host/tools/testtool/win32/TestTool.rc b/host/tools/testtool/win32/TestTool.rc --- a/host/tools/testtool/win32/TestTool.rc +++ b/host/tools/testtool/win32/TestTool.rc @@ -214,23 +214,27 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,112,48,50,14 END -IDD_TT_PLATFORM DIALOG DISCARDABLE 0, 0, 226, 106 +IDD_TT_PLATFORM DIALOG DISCARDABLE 0, 0, 231, 214 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "New Platform" FONT 8, "MS Sans Serif" BEGIN - LTEXT "Platform &name:",IDC_STATIC,7,10,48,8 - LTEXT "Command &prefix:",IDC_STATIC,7,30,53,8 - LTEXT "Platform &type:",IDC_STATIC,7,48,44,8 - COMBOBOX IDC_TYPE_COMBO,76,45,143,55,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Arguments for &GDB:",IDC_STATIC,7,67,64,8 - EDITTEXT IDC_TT_NEW_PLATFORM_GDB,76,63,143,14,ES_AUTOHSCROLL - DEFPUSHBUTTON "OK",IDOK,115,85,50,14 - PUSHBUTTON "Cancel",IDCANCEL,169,85,50,14 - EDITTEXT IDC_TT_NEW_PLATFORM,76,7,143,14,ES_AUTOHSCROLL - COMBOBOX IDC_TT_NEW_PLATFORM_PREFIX,76,25,143,74,CBS_DROPDOWN | + LTEXT "Platform &name:",IDC_STATIC,7,7,48,8 + LTEXT "Command &prefix:",IDC_STATIC,7,27,53,8 + LTEXT "Arguments for &GDB:",IDC_STATIC,7,45,64,8 + EDITTEXT IDC_TT_NEW_PLATFORM_GDB,81,45,143,70,ES_MULTILINE | + WS_VSCROLL | WS_HSCROLL + DEFPUSHBUTTON "OK",IDOK,115,193,50,14 + PUSHBUTTON "Cancel",IDCANCEL,174,193,50,14 + EDITTEXT IDC_TT_NEW_PLATFORM,81,7,143,14,ES_AUTOHSCROLL + COMBOBOX IDC_TT_NEW_PLATFORM_PREFIX,81,27,143,74,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Inferior:",IDC_STATIC,7,121,24,8 + EDITTEXT IDC_INFERIOR,81,121,143,14,ES_AUTOHSCROLL + LTEXT "Prompt:",IDC_STATIC,7,141,25,8 + EDITTEXT IDC_PROMPT,81,141,143,14,ES_AUTOHSCROLL + CONTROL "Server-side GDB",IDC_SERVER_SIDE_GDB,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,81,161,69,10 END IDD_TT_NEW_PLATFORM DIALOG DISCARDABLE 0, 0, 168, 50 @@ -323,24 +327,6 @@ 0x6544, 0x6166, 0x6c75, 0x0074, 0 END -IDD_TT_PLATFORM DLGINIT -BEGIN - IDC_TYPE_COMBO, 0x403, 33, 0 -0x6148, 0x6472, 0x6177, 0x6572, 0x7720, 0x7469, 0x2068, 0x7262, 0x6165, -0x706b, 0x696f, 0x746e, 0x7320, 0x7075, 0x6f70, 0x7472, "\000" - IDC_TYPE_COMBO, 0x403, 10, 0 -0x6953, 0x756d, 0x616c, 0x6f74, 0x0072, - IDC_TYPE_COMBO, 0x403, 17, 0 -0x7953, 0x746e, 0x6568, 0x6974, 0x2063, 0x6174, 0x6772, 0x7465, "\000" - IDC_TYPE_COMBO, 0x403, 36, 0 -0x6148, 0x6472, 0x6177, 0x6572, 0x7720, 0x7469, 0x6f68, 0x7475, 0x6220, -0x6572, 0x6b61, 0x6f70, 0x6e69, 0x2074, 0x7573, 0x7070, 0x726f, 0x0074, - - IDC_TYPE_COMBO, 0x403, 17, 0 -0x6552, 0x6f6d, 0x6574, 0x7320, 0x6d69, 0x6c75, 0x7461, 0x726f, "\000" - 0 -END - ///////////////////////////////////////////////////////////////////////////// // @@ -412,9 +398,9 @@ BEGIN IDD_TT_PLATFORM, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 219 + RIGHTMARGIN, 224 TOPMARGIN, 7 - BOTTOMMARGIN, 99 + BOTTOMMARGIN, 207 END IDD_TT_NEW_PLATFORM, DIALOG @@ -491,7 +477,6 @@ END STRINGTABLE DISCARDABLE BEGIN IDC_TT_NEW_PLATFORM_GDB "Specifies any additional arguments to be used when invoking gdb." - IDC_TYPE_COMBO "Specifies the type of the platform - for example whether hardware or simulator, whether breakpoints are supported. The information is used to drive gdb when running executables." IDC_TT_NEW_PLATFORM "Specifies the name of the platform. Platform names are arbitrary strings, but must be unique for a given user." IDC_TT_DELETE_PLATFORM "Removes the currently selected platform." IDC_TT_ADD_PLATFORM "Adds a new platform." diff --git a/host/tools/testtool/win32/testtoolres.h b/host/tools/testtool/win32/testtoolres.h --- a/host/tools/testtool/win32/testtoolres.h +++ b/host/tools/testtool/win32/testtoolres.h @@ -66,7 +66,6 @@ #define IDD_TT_NEW_PLATFORM 24094 #define IDD_TT_PLATFORMS_DIALOG 24095 #define IDC_TT_NEW_PLATFORM_GDB 24096 -#define IDC_TYPE_COMBO 24097 #define IDC_TT_NEW_PLATFORM 24098 #define IDC_TT_DELETE_PLATFORM 24099 #define IDC_TT_ADD_PLATFORM 24100 @@ -74,6 +73,9 @@ #define IDC_TT_MODIFY_PLATFORM 24104 #define IDC_TT_RESETSTRING 24107 #define IDC_EDIT1 24108 +#define IDC_INFERIOR 24108 +#define IDC_PROMPT 24109 +#define IDC_SERVER_SIDE_GDB 24110 #define ID_TT_EDIT_SAVE 54000 // Next default values for new objects @@ -83,7 +85,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 24097 #define _APS_NEXT_COMMAND_VALUE 54001 -#define _APS_NEXT_CONTROL_VALUE 24109 +#define _APS_NEXT_CONTROL_VALUE 24111 #define _APS_NEXT_SYMED_VALUE 24092 #endif #endif diff --git a/packages/ChangeLog b/packages/ChangeLog --- a/packages/ChangeLog +++ b/packages/ChangeLog @@ -1,3 +1,51 @@ +2000-04-11 Hugo Tyson + + * ecos.db: CYGPKG_IO_SERIAL should not be "hardware" now that it + lives in templates rather than targets. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + 2000-04-05 Jesper Skov * ecos.db: Wallclock moved. diff --git a/packages/NEWS b/packages/NEWS --- a/packages/NEWS +++ b/packages/NEWS @@ -1,3 +1,8 @@ +* SH HAL + Now provides ROMRAM startup type, copying code and data to RAM before + executing, improving performance at cost of memory. +* IO serial drivers reworked by separating into distinct platform + packages, making it simpler to implement new drivers. * WallClock reworked, making it simpler to implement new drivers. New drivers o SH3 RTC module diff --git a/packages/compat/uitron/current/cdl/uitron.cdl b/packages/compat/uitron/current/cdl/uitron.cdl --- a/packages/compat/uitron/current/cdl/uitron.cdl +++ b/packages/compat/uitron/current/cdl/uitron.cdl @@ -400,7 +400,7 @@ cdl_package CYGPKG_UITRON { } cdl_option CYGPKG_UITRON_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/devs/eth/arm/ebsa285/current/ChangeLog b/packages/devs/eth/arm/ebsa285/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/eth/arm/ebsa285/current/ChangeLog @@ -0,0 +1,127 @@ +2000-04-13 Hugo Tyson + + * src/if_ebsa285.c: Attribution to Ron Spence, Pacific Softworks + added as a contributor. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-03-29 Hugo Tyson + + * src/if_ebsa285.c (i82559_recv): Be happy with NULLs in the + SGlist; it means the caller is out of memory so drop the packet on + the floor. Also remove a completely redundant test. + +2000-03-06 Hugo Tyson + + * src/if_ebsa285.c (i82559_can_send): Update net driver to new + interface style. This is incomplete wrt promiscuous mode, but + that's probably about all. + +2000-02-14 Gary Thomas + + * cdl/ebsa285_eth_drivers.cdl: Update CDL to indicate multiple + interface support. + +2000-02-14 Hugo Tyson + + * src/if_ebsa285.c (pci_init_find_82559s): Tidy comments somewhat + and set debug and stats collecting defines to most friendly + settings. + +2000-02-10 Hugo Tyson + + * src/if_ebsa285.c (PacketRxReady): Fix bug; current descriptor + was not being write back for the callback to use. Hence asserts + on state of rfd were firing in busy times - that leading rfd had + already been drained. + + Also rationalized meaning of DEBUG printy symbols a bit - it's now + chatty during startup/foreground manipulations but not in any + performance related activities ie. rx or tx. + +2000-02-09 John Dallaway + + * cdl/ebsa285_eth_drivers.cdl: + + Reparent under CYGPKG_NET_ETH_DRIVERS and tidy display strings. + +2000-02-08 Hugo Tyson + + * src/if_ebsa285.c: New File. + * cdl/ebsa285_eth_drivers.cdl: New File. + + Initial Checkin of EBSA285 Ethernet driver. + + It's one monolithic file at present, and should be split up into a + more generic Intel 82559 driver plus platform-specific parts (PCI + et al) plus eCos/Red-Hat-BSD-stack parts. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== + + + diff --git a/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl b/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl @@ -0,0 +1,80 @@ +# ==================================================================== +# +# ebsa285_eth_drivers.cdl +# +# Ethernet drivers +# Intel EBSA285 and PRO/100+ platform specific support +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): hmt +# Original data: hmt +# Contributors: gthomas +# Date: 2000-02-01 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + +cdl_package CYGPKG_DEVS_ETH_ARM_EBSA285 { + display "Intel EBSA285 with PRO/100+ ethernet driver" + + parent CYGPKG_NET_ETH_DRIVERS + active_if CYGPKG_NET_ETH_DRIVERS + active_if CYGPKG_HAL_ARM_EBSA285 + + implements CYGHWR_NET_DRIVER_ETH0 + implements CYGHWR_NET_DRIVER_ETH1 + # yes, there should be two of these "implement"s + implements CYGHWR_NET_DRIVERS + implements CYGHWR_NET_DRIVERS + include_dir . +# include_files ; # none _exported_ whatsoever + description "Ethernet driver for Intel EBSA285 with PRO/100+ boards." + compile -library=libextras.a if_ebsa285.c + + cdl_component CYGPKG_DEVS_ETH_ARM_EBSA285_OPTIONS { + display "Intel EBSA285 with PRO/100+ ethernet driver build options" + flavor none + no_define + + cdl_option CYGPKG_DEVS_ETH_ARM_EBSA285_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "-D_KERNEL -D__ECOS" } + description " + This option modifies the set of compiler flags for + building the Intel EBSA285 with PRO/100+ ethernet driver + package. These flags are used in addition to the set of + global flags." + } + } +} + +# EOF ebsa285_eth_drivers.cdl diff --git a/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c new file mode 100644 --- /dev/null +++ b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c @@ -0,0 +1,2370 @@ +//========================================================================== +// +// if_ebsa285.c +// +// Ethernet drivers +// Intel EBSA285 and PRO/100+ platform specific support +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): hmt, gthomas +// Contributors: Ron Spence, Pacific Softworks +// Date: 2000-02-01 +// Purpose: +// Description: hardware driver for 82559 Intel PRO/100+ ethernet and +// Intel StrongARM EBSA-285 development boards +// +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CYGPKG_IO_PCI +#include +#else +#error "Need PCI package here" +#endif + +// ------------------------------------------------------------------------ + +#define nDEBUG_82559 +#define DEBUG + +#define nKEEP_STATISTICS +#define nDISPLAY_STATISTICS +#define nDISPLAY_82559_STATISTICS + + +#define os_printf diag_printf +#define db_printf diag_printf + +// ------------------------------------------------------------------------ +// I/O access macros as inlines for type safety + +static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address) +{ *((cyg_uint8 *)io_address) = value; } + +static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address) +{ *((cyg_uint16 *)io_address) = value; } + +static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address) +{ *((cyg_uint32 *)io_address) = value; } + +static inline cyg_uint8 INB(cyg_uint32 io_address) +{ return *((cyg_uint8 *)io_address); } + +static inline cyg_uint16 INW(cyg_uint32 io_address) +{ return *((cyg_uint16 *)io_address); } + +static inline cyg_uint32 INL(cyg_uint32 io_address) +{ return *((cyg_uint32 *)io_address); } + +#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_)) +static inline cyg_uint32 virt_to_bus(cyg_uint32 p_memory) +{ return (p_memory - CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE); } + +#define BUS_TO_VIRT( _x_ ) bus_to_virt((cyg_uint32)(_x_)) +static inline cyg_uint32 bus_to_virt(cyg_uint32 p_memory) +{ return (p_memory + CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE); } + + +// ------------------------------------------------------------------------ +// +// 82559 REGISTER OFFSETS (I/O SPACE) +// +// ------------------------------------------------------------------------ +#define SCBStatus 0 // Rx/Command Unit command and status. +#define SCBCmd 2 // Rx/Command Unit command and status. +#define SCBPointer 4 // General purpose pointer. +#define SCBPort 8 // Misc. commands and operands. +#define SCBflash 12 // Flash memory control. +#define SCBeeprom 14 // EEPROM memory control. +#define SCBCtrlMDI 16 // MDI interface control. +#define SCBEarlyRx 20 // Early receive byte count. +#define SCBGenControl 28 // 82559 General Control Register +#define SCBGenStatus 29 // 82559 General Status register + + +// ------------------------------------------------------------------------ +// +// 82559 SCB STATUS WORD DEFNITIONS +// +// ------------------------------------------------------------------------ +#define SCB_STATUS_CX 0x8000 // CU finished command (transmit) +#define SCB_STATUS_FR 0x4000 // frame received +#define SCB_STATUS_CNA 0x2000 // CU left active state +#define SCB_STATUS_RNR 0x1000 // receiver left ready state +#define SCB_STATUS_MDI 0x0800 // MDI read/write cycle done +#define SCB_STATUS_SWI 0x0400 // software generated interrupt +#define SCB_STATUS_FCP 0x0100 // flow control pause interrupt + + +// ------------------------------------------------------------------------ +// +// 82559 PORT INTERFACE COMMANDS +// +// ------------------------------------------------------------------------ +#define I82559_RESET 0x00000000 // software reset +#define I82559_SELFTEST 0x00000001 // 82559 selftest command +#define I82559_SELECTIVE_RESET 0x00000002 +#define I82559_DUMP 0x00000003 +#define I82559_DUMP_WAKEUP 0x00000007 + + + +// ------------------------------------------------------------------------ +// +// 82559 GENERAL STATUS REGISTER +// +// ------------------------------------------------------------------------ +#define GEN_STATUS_FDX 0x04 // 1 = full duplex, 0 = half +#define GEN_STATUS_100MBPS 0x02 // 1 = 100 Mbps, 0 = 10 Mbps +#define GEN_STATUS_LINK 0x01 // 1 = link up, 0 = link down + + +// ------------------------------------------------------------------------ +// +// 82559 EEPROM INTERFACE +// +// ------------------------------------------------------------------------ +// EEPROM_Ctrl bits. +#define EE_SHIFT_CLK 0x01 // EEPROM shift clock. +#define EE_CS 0x02 // EEPROM chip select. +#define EE_DATA_WRITE 0x04 // EEPROM chip data in. +#define EE_WRITE_0 0x01 +#define EE_WRITE_1 0x05 +#define EE_DATA_READ 0x08 // EEPROM chip data out. +#define EE_ENB (0x4800 | EE_CS) + +// Delay between EEPROM clock transitions. +#define eeprom_delay(usec) udelay(usec); + +// The EEPROM commands include the always-set leading bit. +// (and require the local variable "addr_len", usually 6 or 8) +#define EE_WRITE_CMD (5 << addr_len) +#define EE_READ_CMD (6 << addr_len) +#define EE_ERASE_CMD (7 << addr_len) +#define EE_WRITE_EN_CMD (19 << (addr_len-2)) + + +// ------------------------------------------------------------------------ +// +// SYSTEM CONTROL BLOCK COMMANDS +// +// ------------------------------------------------------------------------ +// CU COMMANDS +#define CU_NOP 0x0000 +#define CU_START 0x0010 +#define CU_RESUME 0x0020 +#define CU_STATSADDR 0x0040 // Load Dump Statistics ctrs addr +#define CU_SHOWSTATS 0x0050 // Dump statistics counters. +#define CU_CMD_BASE 0x0060 // Base address to add to CU commands +#define CU_DUMPSTATS 0x0070 // Dump then reset stats counters. + +// RUC COMMANDS +#define RUC_NOP 0x0000 +#define RUC_START 0x0001 +#define RUC_RESUME 0x0002 +#define RUC_ABORT 0x0004 +#define RUC_ADDR_LOAD 0x0006 +#define RUC_RESUMENR 0x0007 + +#define SCB_M 0x0100 // 0 = enable interrupt, 1 = disable +#define SCB_SI 0x0200 // 1 - cause device to interrupt + +#define CU_STATUS_MASK 0x00C0 +#define RU_STATUS_MASK 0x003C + +#define CUC_ADDR_LOAD 0x0060 +#define CUC_START 0x0010 + +#define MAX_MEM_RESERVED_IOCTL 1000 + +// We use this as a templete when writing a new MAC address into the +// eeproms. The MAC address in the first few bytes is over written +// with the correct MAC address and then the whole lot is programmed +// into the serial EEPROM. The checksum is calculated on the fly and +// sent instead of the last two bytes. + +static char eeprom_burn[126] = { + 0x00, 0x90, 0x27, 0x8c, 0x57, 0x82, 0x03, 0x02, 0x00, 0x00, 0x01, + 0x02, 0x01, 0x47, 0x00, 0x00, 0x13, 0x72, 0x06, 0x83, 0xa2, 0x40, + 0x0c, 0x00, 0x86, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + + +// ------------------------------------------------------------------------ +// +// RECEIVE FRAME DESCRIPTORS +// +// ------------------------------------------------------------------------ +typedef struct rfd { + volatile cyg_uint32 status; // result of receive operation + volatile cyg_uint32 link; // offset from RU base to next RFD + volatile cyg_uint32 rdb_address; // pointer to Rx data buffer + volatile cyg_uint32 count:14, // number of bytes received + + f:1, // + EOF & F flags + eof:1, + size:16; // size of the data buffer + volatile cyg_uint8 buffer[0]; // data buffer (simple mode) +} RFD; + +#define RFD_STATUS_EL 0x80000000 // 1=last RFD in RFA +#define RFD_STATUS_S 0x40000000 // 1=suspend RU after receiving frame +#define RFD_STATUS_H 0x00100000 // 1=RFD is a header RFD +#define RFD_STATUS_SF 0x00080000 // 0=simplified, 1=flexible mode +#define RFD_STATUS_C 0x00008000 // completion of received frame +#define RFD_STATUS_OK 0x00002000 // frame received with no errors + +#define RFD_RX_CRC 0x00000800 // crc error +#define RFD_RX_ALIGNMENT 0x00000400 // alignment error +#define RFD_RX_RESOURCE 0x00000200 // out of space, no resources +#define RFD_RX_DMA_OVER 0x00000100 // DMA overrun +#define RFD_RX_SHORT 0x00000080 // short frame error +#define RFD_RX_LENGTH 0x00000020 // +#define RFD_RX_ERROR 0x00000010 // receive error +#define RFD_RX_NO_ADR_MATCH 0x00000004 // no address match +#define RFD_RX_IA_MATCH 0x00000002 // individual address does not match +#define RFD_RX_TCO 0x00000001 // TCO indication + + +typedef struct { + volatile cyg_uint32 count:14, // bytes used in buffer + f:1, // buffer has been used (filled) + eof:1; // last receive buffer in frame + volatile cyg_uint32 next_rbd; // next RBD (RU base relative) + volatile cyg_uint32 buffer_address; // address of receive data buffer + volatile cyg_uint32 size:15, // size of the associated buffer + el:1; // buffer of this RBD is last +} RBD; + + +// ------------------------------------------------------------------------ +// +// TRANSMIT FRAME DESCRIPTORS +// +// ------------------------------------------------------------------------ +typedef struct { + volatile cyg_uint32 status:16, // result of transmit operation + command:16; // transmit command + volatile cyg_uint32 link; // offset from RU base to next RFD + volatile cyg_uint32 tbd_address; // pointer to Rx data buffer + volatile cyg_uint32 count:15, // number of bytes in transmit buffer + eof:1, + tx_threshold:8, + tbd_number:8; + volatile cyg_uint8 buffer[0]; // data buffer (simple mode) +} TxCB; + + +#define TxCB_CMD_TRANSMIT 0x0004 // transmit command +#define TxCB_CMD_SF 0x0008 // 0=simplified, 1=flexible mode +#define TxCB_CMD_NC 0x0010 // 0=CRC insert by controller +#define TxCB_CMD_I 0x2000 // generate interrupt on completion +#define TxCB_CMD_S 0x4000 // suspend on completion +#define TxCB_CMD_EL 0x8000 // last command block in CBL + + +// ------------------------------------------------------------------------ +// +// STRUCTURES ADDED FOR PROMISCUOUS MODE +// +// ------------------------------------------------------------------------ +typedef struct { + cyg_uint32 cb_status_word:13, + cb_ok:1, + cb_dc:1, + cb_complete:1, + cb_cmd:3, + cb_cmd_word:10, + cb_int:1, + cb_suspend:1, + cb_el:1; + cyg_uint32 cb_link_offset; +} CB_STRUCT; + + +typedef struct { + CB_STRUCT cb_entry; + cyg_uint8 config_bytes[24]; +} CONFIG_CMD_STRUCT; + +// ------------------------------------------------------------------------ +// +// STATISTICAL COUNTER STRUCTURE +// +// ------------------------------------------------------------------------ +#ifdef KEEP_STATISTICS +typedef struct { + cyg_uint32 tx_good; + cyg_uint32 tx_max_collisions; + cyg_uint32 tx_late_collisions; + cyg_uint32 tx_underrun; + cyg_uint32 tx_carrier_loss; + cyg_uint32 tx_deferred; + cyg_uint32 tx_single_collisions; + cyg_uint32 tx_mult_collisions; + cyg_uint32 tx_total_collisions; + cyg_uint32 rx_good; + cyg_uint32 rx_crc_errors; + cyg_uint32 rx_align_errors; + cyg_uint32 rx_resource_errors; + cyg_uint32 rx_overrun_errors; + cyg_uint32 rx_collisions; + cyg_uint32 rx_short_frames; + cyg_uint32 done; +} I82559_COUNTERS; + + +typedef struct { + cyg_uint32 rx_count; + cyg_uint32 rx_deliver; + cyg_uint32 rx_resource; + cyg_uint32 rx_restart; + cyg_uint32 tx_count; + cyg_uint32 tx_complete; + cyg_uint32 tx_dropped; +} STATISTICS; + + +STATISTICS statistics[2]; +I82559_COUNTERS i82559_counters[2]; + +#endif // KEEP_STATISTICS + +// ------------------------------------------------------------------------ + +#define MAX_RX_PACKET_SIZE 1536 // maximum Rx packet size +#define MAX_TX_PACKET_SIZE 1536 // maximum Tx packet size + +#ifndef MAX_RX_DESCRIPTORS +#define MAX_RX_DESCRIPTORS 128 // number of Rx descriptors +#endif +#ifndef MAX_TX_DESCRIPTORS +#define MAX_TX_DESCRIPTORS 128 // number of Tx descriptors +#endif + + + +typedef struct i82559 { + cyg_uint8 // (split up for atomic byte access) + found:1, // was hardware discovered? + mac_addr_ok:1, // can we bring up? + active:1, // has this if been brung up? + spare1:5; + cyg_uint8 + out_of_resources:1, // need to restart rx engine. + spare2:7; + cyg_uint8 + tx_in_progress:1, // transmit in progress flag + tx_queue_full:1, // all Tx descriptors used flag + spare3:6; + cyg_uint8 index; // 0 or 1 or whatever + cyg_uint32 devid; // PCI device id + cyg_uint32 memory_address; // PCI memory address + cyg_uint32 io_address; // memory mapped I/O address + cyg_uint8 mac_address[6]; // mac (hardware) address + void *ndp; // Network Device Pointer + + int next_rx_descriptor; // descriptor index for RFDs + RFD *rx_ring[MAX_RX_DESCRIPTORS]; // location of Rx descriptors + + int tx_descriptor_add; // descriptor index for additions + int tx_descriptor_remove; // descriptor index for removals + TxCB *tx_ring[MAX_TX_DESCRIPTORS]; // location of Tx descriptors + unsigned long tx_keys[MAX_TX_DESCRIPTORS]; + // keys for tx q management + + // Interrupt handling stuff + cyg_vector_t vector; // interrupt vector + cyg_handle_t interrupt_handle; // handle for int.handler + cyg_interrupt interrupt_object; + +#ifdef KEEP_STATISTICS + void *p_statistics; // pointer to statistical counters +#endif + +} I82559; + + +// This is encapsulated here so that a change to > 2 interfaces can +// easily be accommodated. + +#define IF_BAD_82559( _p_ ) \ + CYG_ASSERT( (&i82559[0] == (_p_)) || (&i82559[1] == (_p_)), \ + "Bad pointer-to-i82559" ); \ + if ( (&i82559[0] != (_p_)) && (&i82559[1] != (_p_)) ) + +// ------------------------------------------------------------------------ +// Instantiate the interfaces that we have: + +#define MAX_82559 2 // number of interfaces + +I82559 i82559[MAX_82559]; // i82559 device info. structure + +// eth0 + +ETH_DRV_SC(ebsa285_sc0, + &i82559[0], // Driver specific data + "eth0", // Name for this interface + i82559_start, + i82559_stop, + i82559_ioctl, + i82559_can_send, + i82559_send, + i82559_recv); + +NETDEVTAB_ENTRY(ebsa285_netdev0, + "ebsa285-0", + ebsa285_i82559_init, + &ebsa285_sc0); + +#if 1 + +// eth1 + +ETH_DRV_SC(ebsa285_sc1, + &i82559[1], // Driver specific data + "eth1", // Name for this interface + i82559_start, + i82559_stop, + i82559_ioctl, + i82559_can_send, + i82559_send, + i82559_recv); + +NETDEVTAB_ENTRY(ebsa285_netdev1, + "ebsa285-1", + ebsa285_i82559_init, + &ebsa285_sc1); + +#else +int ebsa285_netdev1 = -1; // for asserts about valid addresses +int ebsa285_sc1 = -1; +#endif // eth1 is included + +// This is in a macro so that if more devices arrive it can easily be changed +#define CHECK_NDP_SC_LINK() CYG_MACRO_START \ + CYG_ASSERT( ((void *)ndp == (void *)&ebsa285_netdev0) || \ + ((void *)ndp == (void *)&ebsa285_netdev1), "Bad ndp" ); \ + CYG_ASSERT( ((void *)sc == (void *)&ebsa285_sc0) || \ + ((void *)sc == (void *)&ebsa285_sc1), "Bad sc" ); \ + CYG_ASSERT( (void *)p_i82559 == sc->driver_private, "sc pointer bad" );\ +CYG_MACRO_END + +// ------------------------------------------------------------------------ +// +// Communications from ISR to DSR +// +// ------------------------------------------------------------------------ + +#define PACKET_RX 1 +#define PACKET_TX 2 + +typedef struct { + cyg_uint32 request; + void *p; + unsigned long key; +} I82559_QUEUE; + +// 82559 thread request queue +#define I82559_QUEUE_SIZE \ + ((MAX_RX_DESCRIPTORS + MAX_TX_DESCRIPTORS) * MAX_82559) + +I82559_QUEUE i82559_queue[I82559_QUEUE_SIZE]; +int i82559_q_in; // queue insertion index +int i82559_q_out; // queue removal index +int i82559_q_full; // queue full flag + + +// ------------------------------------------------------------------------ +// +// Managing the memory that is windowed onto the PCI bus +// +// ------------------------------------------------------------------------ + +static cyg_uint32 i82559_heap_size; +static cyg_uint8 *i82559_heap_base; +static cyg_uint8 *i82559_heap_free; + +static void *mem_reserved_ioctl = (void*)0; +// uncacheable memory reserved for ioctl calls + +// ------------------------------------------------------------------------ +// +// FUNCTION PROTOTYPES +// +// ------------------------------------------------------------------------ + +static int pci_init_find_82559s(void); + +static void i82559_reset(struct i82559* p_i82559); + +static void InitRxRing(struct i82559* p_i82559); +static void ResetRxRing(struct i82559* p_i82559); +static void PacketRxReady(struct i82559* p_i82559); +static void InitTxRing(struct i82559* p_i82559); +static void ResetTxRing(struct i82559* p_i82559); + +static int write_enable_eeprom(long , int ); +static void program_eeprom(cyg_uint32 , cyg_uint32 , cyg_uint8 * ); + +static int eth_set_promiscuous_mode(struct i82559* p_i82559); + +// ------------------------------------------------------------------------ +// utility that is used in statistics routine +// ------------------------------------------------------------------------ +static inline void wait_for_cmd_done(long scb_ioaddr) +{ + int wait = 10000; + do /* nothing */ ; + while( INB(scb_ioaddr) && --wait >= 0); +} + +static inline void Mask82559Interrupt(struct i82559* p_i82559) +{ + cyg_drv_interrupt_mask(p_i82559->vector); + cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_PCI_IRQ); +} + +static inline void UnMask82559Interrupt(struct i82559* p_i82559) +{ + cyg_drv_interrupt_unmask(p_i82559->vector); + cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_PCI_IRQ); +} + + +static void udelay(int delay) +{ + int i; + // the loop is going to take 3 ticks. At 228 MHz, to give uS, multiply + // by 228/3 = 76 near enough. No volatile is needed on i; gcc recognizes + // delay loops and does NOT elide them. + for ( i = 76 * delay; i ; i--) + ; +} + +// ------------------------------------------------------------------------ +// +// +// CODE FOR DEBUGGING PURPOSES ONLY +// +// +// ------------------------------------------------------------------------ +void dump_txcb(TxCB *p_txcb) +{ + os_printf("TxCB @ %x\n", (int)p_txcb); + os_printf("status = %04X ", p_txcb->status); + os_printf("command = %04X ", p_txcb->command); + os_printf("link = %08X ", p_txcb->link); + os_printf("tbd = %08X ", p_txcb->tbd_address); + os_printf("count = %d ", p_txcb->count); + os_printf("eof = %x ", p_txcb->eof); + os_printf("threshold = %d ", p_txcb->tx_threshold); + os_printf("tbd number = %d\n", p_txcb->tbd_number); +} + + +// This is intended to be the body of a THREAD that prints stuff every 10 +// seconds or so: +#ifdef KEEP_STATISTICS +#ifdef DISPLAY_STATISTICS +void DisplayStatistics(void) +{ + int i; + I82559_COUNTERS *p_statistics; + cyg_uint32 *p_counter; + cyg_uint32 *p_register; + int reg_count; + int status; + + while ( 1 ) { +#ifdef DISPLAY_82559_STATISTICS + for ( i = 0; i < 2; i ++ ) { + p_statistics = (I82559_COUNTERS *)i82559[i].p_statistics; + if ( (p_statistics->done & 0xFFFF) == 0xA007 ) { + p_counter = (cyg_uint32 *)&i82559_counters[i]; + p_register = (cyg_uint32 *)&p_statistics->tx_good; + for ( reg_count = 20; reg_count != 0; reg_count--) { + *p_counter += *p_register; + p_counter++; + p_register++; + } + p_statistics->done = 0; + // make sure no command operating + wait_for_cmd_done(i82559[i].io_address + SCBCmd); + // start register dump + OUTW(CU_DUMPSTATS, i82559[i].io_address + SCBCmd); + } + } +#endif + os_printf("\nRx\nPackets = %d %d\n", + statistics[0].rx_count, statistics[1].rx_count); + os_printf("Deliver %d %d\n", + statistics[0].rx_deliver, statistics[1].rx_deliver); + os_printf("Resource %d %d\n", + statistics[0].rx_resource, statistics[1].rx_resource); + os_printf("Restart %d %d\n", + statistics[0].rx_restart, statistics[1].rx_restart); + +#ifdef DISPLAY_82559_STATISTICS + os_printf("Count %d %d\n", + i82559_counters[0].rx_good, i82559_counters[1].rx_good); + os_printf("CRC %d %d\n", + i82559_counters[0].rx_crc_errors, i82559_counters[1].rx_crc_errors); + os_printf("Align %d %d\n", + i82559_counters[0].rx_align_errors, i82559_counters[1].rx_align_errors); + os_printf("Resource %d %d\n", + i82559_counters[0].rx_resource_errors, i82559_counters[1].rx_resource_errors); + os_printf("Overrun %d %d\n", + i82559_counters[0].rx_overrun_errors, i82559_counters[1].rx_overrun_errors); + os_printf("Collision %d %d\n", + i82559_counters[0].rx_collisions, i82559_counters[1].rx_collisions); + os_printf("Short %d %d\n", + i82559_counters[0].rx_short_frames, i82559_counters[1].rx_short_frames); +#endif + os_printf("\nTx\nPackets = %d %d\n", + statistics[0].tx_count, statistics[1].tx_count); + os_printf("Complete %d %d\n", + statistics[0].tx_complete, statistics[1].tx_complete); + os_printf("Dropped %d %d\n", + statistics[0].tx_dropped, statistics[1].tx_dropped); + os_printf("Count %d %d\n", + i82559_counters[0].tx_good, i82559_counters[1].tx_good); +#ifdef DISPLAY_82559_STATISTICS + os_printf("Collision %d %d\n", + i82559_counters[0].tx_max_collisions,i82559_counters[1].tx_max_collisions); + os_printf("Late Col. %d %d\n", + i82559_counters[0].tx_late_collisions,i82559_counters[1].tx_late_collisions); + os_printf("Underrun %d %d\n", + i82559_counters[0].tx_underrun,i82559_counters[1].tx_underrun); + os_printf("Carrier %d %d\n", + i82559_counters[0].tx_carrier_loss,i82559_counters[1].tx_carrier_loss); + os_printf("Deferred %d %d\n", + i82559_counters[0].tx_deferred, i82559_counters[1].tx_deferred); + os_printf("1 Col %d %d\n", + i82559_counters[0].tx_single_collisions, i82559_counters[0].tx_single_collisions); + os_printf("Mult. Col %d %d\n", + i82559_counters[0].tx_mult_collisions, i82559_counters[0].tx_mult_collisions); + os_printf("Total Col %d %d\n", + i82559_counters[0].tx_total_collisions, i82559_counters[0].tx_total_collisions); +#endif + status = INB(i82559[0].io_address + SCBGenStatus); + os_printf("Interface 0 Link = %s, %s Mbps, %s Duplex\n", + status & GEN_STATUS_LINK ? "Up" : "Down", + status & GEN_STATUS_100MBPS ? "100" : "10", + status & GEN_STATUS_FDX ? "Full" : "Half"); + + status = INB(i82559[1].io_address + SCBGenStatus); + os_printf("Interface 1 Link = %s, %s Mbps, %s Duplex\n", + status & GEN_STATUS_LINK ? "Up" : "Down", + status & GEN_STATUS_100MBPS ? "100" : "10", + status & GEN_STATUS_FDX ? "Full" : "Half"); + + cyg_thread_delay(1000); + } +} +#endif // DISPLAY_STATISTICS +#endif // KEEP_STATISTICS + +void dump_rfd(RFD *p_rfd, int anyway ) +{ + if ( (0 != p_rfd->status) || anyway ) { + os_printf("RFD @ %x = ", (int)p_rfd); + os_printf("status = %x ", p_rfd->status); + os_printf("link = %x ", p_rfd->link); +// os_printf("rdb_address = %x ", p_rfd->rdb_address); + os_printf("count = %x ", p_rfd->count); + os_printf("f = %x ", p_rfd->f); + os_printf("eof = %x ", p_rfd->eof); + os_printf("size = %x\n", p_rfd->size); + os_printf("[%04x %04x %04x] ", + *((cyg_uint16 *)(&(p_rfd->buffer[0]))), + *((cyg_uint16 *)(&(p_rfd->buffer[2]))), + *((cyg_uint16 *)(&(p_rfd->buffer[4]))) ); + os_printf("[%04x %04x %04x] %04x : ", + *((cyg_uint16 *)(&(p_rfd->buffer[6]))), + *((cyg_uint16 *)(&(p_rfd->buffer[8]))), + *((cyg_uint16 *)(&(p_rfd->buffer[10]))), + *((cyg_uint16 *)(&(p_rfd->buffer[12]))) ); + os_printf("(%04x %04x %04x %04x) ", + *((cyg_uint16 *)(&(p_rfd->buffer[14]))), + *((cyg_uint16 *)(&(p_rfd->buffer[16]))), + *((cyg_uint16 *)(&(p_rfd->buffer[18]))), + *((cyg_uint16 *)(&(p_rfd->buffer[20]))) ); + os_printf("[%04x %04x %04x] ", + *((cyg_uint16 *)(&(p_rfd->buffer[22]))), + *((cyg_uint16 *)(&(p_rfd->buffer[24]))), + *((cyg_uint16 *)(&(p_rfd->buffer[26]))) ); + os_printf("%d.%d.%d.%d ", + *((cyg_uint8 *)(&(p_rfd->buffer[28]))), + *((cyg_uint8 *)(&(p_rfd->buffer[29]))), + *((cyg_uint8 *)(&(p_rfd->buffer[30]))), + *((cyg_uint8 *)(&(p_rfd->buffer[31]))) ); + os_printf("[%04x %04x %04x] ", + *((cyg_uint16 *)(&(p_rfd->buffer[32]))), + *((cyg_uint16 *)(&(p_rfd->buffer[34]))), + *((cyg_uint16 *)(&(p_rfd->buffer[36]))) ); + os_printf("%d.%d.%d.%d ...\n", + *((cyg_uint8 *)(&(p_rfd->buffer[38]))), + *((cyg_uint8 *)(&(p_rfd->buffer[39]))), + *((cyg_uint8 *)(&(p_rfd->buffer[40]))), + *((cyg_uint8 *)(&(p_rfd->buffer[41]))) ); + } +} + +void dump_all_rfds( int intf ) +{ + struct i82559* p_i82559 = &i82559[intf]; + int i, j; + j = p_i82559->next_rx_descriptor; + os_printf("rx descriptors for interface %d (eth%d):\n", intf, intf ); + for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) + dump_rfd( p_i82559->rx_ring[i], (i > (j-3) && (i <= j)) ); + os_printf("next rx descriptor = %x\n\n", j); +} + + +void dump_packet(cyg_uint8 *p_buffer, int length) +{ + int count; + + count = 0; + while ( length > 0 ) { + if ( count == 0 ) + os_printf("\n"); + count = (count + 1) & 0x0F; + os_printf("%02X ", *p_buffer++); + length--; + } + os_printf("\n"); +} + + + +// ------------------------------------------------------------------------ +// Memory management +// +// Simply carve off from the front of the PCI mapped window into real memory + +static void *pciwindow_mem_alloc(int size) +{ + void *p_memory; + + CYG_ASSERT( + (CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE <= (int)i82559_heap_free) + && + ((CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE + + CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE) > (int)i82559_heap_free) + && + (0 < i82559_heap_size) + && + (CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE >= i82559_heap_size) + && + (CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE == (int)i82559_heap_base), + "Heap variables corrupted" ); + + p_memory = (void *)0; + size = (size + 3) & ~3; + if ( (i82559_heap_free+size) < (i82559_heap_base+i82559_heap_size) ) { + cyg_uint32 *p; + p_memory = (void *)i82559_heap_free; + i82559_heap_free += size; + for ( p = (cyg_uint32 *)p_memory; size > 0; size -= 4 ) + *p++ = 0; + } + + return p_memory; +} + + + +// ------------------------------------------------------------------------ +// +// READ EEPROM +// +// ------------------------------------------------------------------------ +static int read_eeprom(long ioaddr, int location, int addr_len) +{ + unsigned short retval = 0; + int ee_addr = ioaddr + SCBeeprom; + int read_cmd = location | EE_READ_CMD; + int i; + + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(1); + OUTW(EE_ENB, ee_addr); + eeprom_delay(1); + + // Shift the read command bits out. + for (i = 12; i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + OUTW(EE_ENB | dataval, ee_addr); + eeprom_delay(1); + OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(1); + } + OUTW(EE_ENB, ee_addr); + eeprom_delay(1); + + for (i = 15; i >= 0; i--) { + OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr); + eeprom_delay(1); + retval = (retval << 1) | ((INW(ee_addr) & EE_DATA_READ) ? 1 : 0); + OUTW(EE_ENB, ee_addr); + eeprom_delay(1); + } + + // Terminate the EEPROM access. + OUTW(EE_ENB & ~EE_CS, ee_addr); + return retval; +} + + +// ------------------------------------------------------------------------ +// +// NETWORK INTERFACE INITIALIZATION +// +// Function : Init82559 +// +// Description : +// This routine resets, configures, and initializes the chip. +// It also clears the ethernet statistics structure, and selects +// which statistics are supported by this driver. +// +// ------------------------------------------------------------------------ +static bool +ebsa285_i82559_init(struct cyg_netdevtab_entry * ndp) +{ + static int initialized = 0; // only probe PCI et al *once* + + struct eth_drv_sc *sc; + cyg_uint32 selftest; + volatile cyg_uint32 *p_selftest; + cyg_uint32 ioaddr; + cyg_uint16 checksum; + int count; + int i; + int addr_length; + cyg_uint8 mac_address[6]; + struct i82559 *p_i82559; + +#ifdef DEBUG + db_printf("ebsa285_i82559_init\n"); +#endif + + sc = (struct eth_drv_sc *)(ndp->device_instance); + p_i82559 = (struct i82559 *)(sc->driver_private); + + IF_BAD_82559( p_i82559 ) { + os_printf( "Bad device private pointer %x\n", sc->driver_private ); + return 0; + } + + CHECK_NDP_SC_LINK(); + + if ( 0 == initialized++ ) { + // then this is the first time ever: + if ( ! pci_init_find_82559s() ) { + os_printf( "pci_init_find_82559s failed" ); + return 0; + } + } + + if ( ! p_i82559->found ) // no device on PCI bus + return (0); + + ioaddr = p_i82559->io_address; // get I/O address for 82559 + +#ifdef DEBUG + os_printf("Init82559 %d @ %x\n82559 Self Test\n", + p_i82559->index, (int)ndp); +#endif + + Mask82559Interrupt(p_i82559); + + wait_for_cmd_done(ioaddr + SCBCmd); // make sure no command operating + + i82559_reset(p_i82559); + + // Perform a system self-test. (get enough mem to round address) + if ( (selftest = (cyg_uint32)pciwindow_mem_alloc(32) ) == 0) + return (0); + p_selftest = (cyg_uint32 *) ((selftest + 15) & ~0xf); + p_selftest[0] = p_selftest[1] = -1; + + OUTL( (VIRT_TO_BUS(p_selftest)) | I82559_SELFTEST, ioaddr + SCBPort); + count = 0x7FFFF; // Timeout for self-test. + do { + udelay(10); + } while ( (p_selftest[1] == -1) && (--count >= 0) ); + + UnMask82559Interrupt(p_i82559); + + if (count < 0) { + // Test timed out. + os_printf("Self test failed\n"); + return (0); + } +#ifdef DEBUG + os_printf(" General self-test: %s.\n" + " Serial sub-system self-test: %s.\n" + " Internal registers self-test: %s.\n" + " ROM checksum self-test: %s (%08X).\n", + p_selftest[1] & 0x1000 ? "failed" : "passed", + p_selftest[1] & 0x0020 ? "failed" : "passed", + p_selftest[1] & 0x0008 ? "failed" : "passed", + p_selftest[1] & 0x0004 ? "failed" : "passed", + p_selftest[0]); +#endif + + // read eeprom and get 82559's mac address + addr_length = (read_eeprom(ioaddr, 0, 6) == 0xffff) ? 8 : 6; + // (this is the length of the *EEPROM*s address, not MAC address) + + for (checksum = 0, i = 0, count = 0; count < 64; count++) { + cyg_uint16 value; + // read word from eeprom + value = read_eeprom(ioaddr, count, addr_length); + checksum += value; + if (count < 3) { + mac_address[i++] = value & 0xFF; + mac_address[i++] = (value >> 8) & 0xFF; + } + } + + // If the EEPROM checksum is wrong, the MAC address read from the + // EEPROM is probably wrong as well. In that case, we don't set + // mac_addr_ok, but continue the initialization. If then somebody calls + // i82559_start without calling eth_set_mac_address() first, we refuse + // to bring up the interface, because running with an invalid MAC + // address is not a very brilliant idea. + + if ((checksum & 0xFFFF) != 0xBABA) { + // selftest verified checksum, verify again + os_printf( "Warning: Invalid EEPROM checksum %04X for device %d\n", + checksum, p_i82559->index); + } else { + p_i82559->mac_addr_ok = 1; + } +#ifdef DEBUG + os_printf("Valid EEPROM checksum\n"); + os_printf("MAC Address = %02X %02X %02X %02X %02X %02X\n", + mac_address[0], mac_address[1], mac_address[2], mac_address[3], + mac_address[4], mac_address[5]); +#endif + + // record the MAC address in the device structure + p_i82559->mac_address[0] = mac_address[0]; + p_i82559->mac_address[1] = mac_address[1]; + p_i82559->mac_address[2] = mac_address[2]; + p_i82559->mac_address[3] = mac_address[3]; + p_i82559->mac_address[4] = mac_address[4]; + p_i82559->mac_address[5] = mac_address[5]; + + // and record the net dev pointer + p_i82559->ndp = (void *)ndp; + + InitRxRing(p_i82559); + InitTxRing(p_i82559); + + // Initialize upper level driver + if ( p_i82559->mac_addr_ok ) + eth_drv_init(sc, &(p_i82559->mac_address[0]) ); + else + eth_drv_init(sc, 0 ); + + return (1); +} + + + +// ------------------------------------------------------------------------ +// +// Function : i82559_start +// +// ------------------------------------------------------------------------ +static void i82559_start( struct eth_drv_sc *sc, + unsigned char *enaddr, int flags ) +{ + struct i82559 *p_i82559; + cyg_uint32 ioaddr; +#ifdef KEEP_STATISTICS + void *p_statistics; +#endif + + p_i82559 = (struct i82559 *)sc->driver_private; + + IF_BAD_82559( p_i82559 ) { + os_printf( "i82559_start: Bad device pointer %x\n", p_i82559 ); + return; + } + + if ( ! p_i82559->mac_addr_ok ) { + os_printf("i82559_start %d: invalid MAC address, " + "can't bring up interface\n", + p_i82559->index ); + return; + } + + if ( p_i82559->active ) + i82559_stop( sc ); + + ioaddr = p_i82559->io_address; // get 82559's I/O address + +#ifdef KEEP_STATISTICS +#ifdef DISPLAY_82559_STATISTICS + p_i82559->p_statistics = + p_statistics = pciwindow_mem_alloc(sizeof(I82559_COUNTERS)); + memset(p_statistics, 0xFFFFFFFF, sizeof(I82559_COUNTERS)); + wait_for_cmd_done(ioaddr + SCBCmd); // make sure no command operating + // set statistics dump address + OUTL(VIRT_TO_BUS(p_statistics), ioaddr + SCBPointer); + OUTW(SCB_M | CU_STATSADDR, ioaddr + SCBCmd); + + wait_for_cmd_done(ioaddr + SCBCmd); // make sure no command operating + OUTW(SCB_M | CU_DUMPSTATS, ioaddr + SCBCmd); // start register dump +#endif +#endif + + wait_for_cmd_done(ioaddr + SCBCmd); // make sure no command operating + + OUTL(0, ioaddr + SCBPointer); // load ru base address = 0 + OUTW(SCB_M | RUC_ADDR_LOAD, ioaddr + SCBCmd); + + wait_for_cmd_done(ioaddr + SCBCmd); // wait for SCB command complete + // load pointer to Rx Ring + OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]), ioaddr + SCBPointer); + OUTW(RUC_START, ioaddr + SCBCmd); + + p_i82559->out_of_resources = 0; + p_i82559->active = 1; + + if ( 0 +#ifdef ETH_DRV_FLAGS_PROMISC_MODE + != (flags & ETH_DRV_FLAGS_PROMISC_MODE) +#endif + ) { + eth_set_promiscuous_mode(p_i82559); + } +#ifdef DEBUG + { + int status; + status = INB(ioaddr + SCBGenStatus); + os_printf("i82559_start %d flg %x Link = %s, %s Mbps, %s Duplex\n", + p_i82559->index, + *(int *)p_i82559, + status & GEN_STATUS_LINK ? "Up" : "Down", + status & GEN_STATUS_100MBPS ? "100" : "10", + status & GEN_STATUS_FDX ? "Full" : "Half"); + } +#endif +} + + +// ------------------------------------------------------------------------ +// +// Function : BringDown82559 +// +// ------------------------------------------------------------------------ + +static void i82559_stop( struct eth_drv_sc *sc ) +{ + struct i82559 *p_i82559; + + p_i82559 = (struct i82559 *)sc->driver_private; + + IF_BAD_82559( p_i82559 ) { + os_printf( "i82559_stop: Bad device pointer %x\n", p_i82559 ); + return; + } + +#ifdef DEBUG + os_printf("i82559_stop %d flg %x\n", p_i82559->index, *(int *)p_i82559 ); +#endif + + i82559_reset(p_i82559); // that should stop it + p_i82559->active = 0; // and stop people tormenting it + + ResetRxRing( p_i82559 ); + ResetTxRing( p_i82559 ); +} + + +// ------------------------------------------------------------------------ +// +// Function : InitRxRing +// +// ------------------------------------------------------------------------ +static void InitRxRing(struct i82559* p_i82559) +{ + int i; + RFD *rfd; + RFD *p_rfd = 0; +#ifdef DEBUG_82559 + os_printf("InitRxRing %d\n", p_i82559->index); +#endif + for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) { + rfd = (RFD *)pciwindow_mem_alloc(sizeof(RFD) + MAX_RX_PACKET_SIZE); + p_i82559->rx_ring[i] = rfd; + if ( i ) + p_rfd->link = VIRT_TO_BUS(rfd); + p_rfd = (RFD *)rfd; + } + // link last RFD to first: + p_rfd->link = VIRT_TO_BUS(p_i82559->rx_ring[0]); + + ResetRxRing( p_i82559 ); +} + +// ------------------------------------------------------------------------ +// +// Function : ResetRxRing +// +// ------------------------------------------------------------------------ +static void ResetRxRing(struct i82559* p_i82559) +{ + RFD *p_rfd; + int i; +#ifdef DEBUG_82559 + os_printf("ResetRxRing %d\n", p_i82559->index); +#endif + for ( i = 0; i < MAX_RX_DESCRIPTORS; i++ ) { + p_rfd = p_i82559->rx_ring[i]; + CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" ); + CYG_ASSERT( (cyg_uint8 *)p_rfd < i82559_heap_free, "rfd over" ); + CYG_ASSERT( p_i82559->rx_ring[ + ( i ? (i-1) : (MAX_RX_DESCRIPTORS-1) ) + ]->link == VIRT_TO_BUS(p_rfd), "rfd linked list broken" ); + p_rfd->status = 0; + p_rfd->count = 0; + p_rfd->f = 0; + p_rfd->eof = 0; + p_rfd->rdb_address = 0xFFFFFFFF; + p_rfd->size = MAX_RX_PACKET_SIZE; + } + p_i82559->next_rx_descriptor = 0; +} + +// ------------------------------------------------------------------------ +// +// Function : PacketRx +// +// ------------------------------------------------------------------------ +static void PacketRxReady(struct i82559* p_i82559) +{ + struct cyg_netdevtab_entry *ndp; + struct eth_drv_sc *sc; + RFD *p_rfd; + int next_descriptor; + int length; + + ndp = (struct cyg_netdevtab_entry *)(p_i82559->ndp); + sc = (struct eth_drv_sc *)(ndp->device_instance); + + CHECK_NDP_SC_LINK(); + + next_descriptor = p_i82559->next_rx_descriptor; + p_rfd = p_i82559->rx_ring[next_descriptor]; + + CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" ); + CYG_ASSERT( (cyg_uint8 *)p_rfd < i82559_heap_free, "rfd over" ); + + while ( p_rfd->status & RFD_STATUS_C ) { + p_rfd->status |= RFD_STATUS_EL; + length = p_rfd->count; + +#ifdef DEBUG_82559 + os_printf( "Device %d (eth%d), rx descriptor %d:\n", + p_i82559->index, p_i82559->index, next_descriptor ); +// dump_rfd( p_rfd, 1 ); +#endif + + // Offer the data to the network stack + p_i82559->next_rx_descriptor = next_descriptor; + eth_drv_recv( sc, length ); + + p_rfd->count = 0; + p_rfd->f = 0; + p_rfd->eof = 0; + p_rfd->status = 0; +#ifdef KEEP_STATISTICS + statistics[p_i82559->index].rx_deliver++; +#endif + if (++next_descriptor >= MAX_RX_DESCRIPTORS) + next_descriptor = 0; + p_rfd = p_i82559->rx_ring[next_descriptor]; + + CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" ); + CYG_ASSERT( (cyg_uint8 *)p_rfd < i82559_heap_free, "rfd over" ); + } + + if ( p_i82559->out_of_resources ) { // out of Rx resources ? + if ( ! (p_rfd->status & RFD_STATUS_C) ) { // all buffers processed ? + cyg_uint32 ioaddr; + // yes, restart RU +#ifdef KEEP_STATISTICS + statistics[p_i82559->index].rx_restart++; +#endif + next_descriptor = 0; // re-initialize next desc. + p_i82559->out_of_resources = 0; // clear out of resource flag + ioaddr = p_i82559->io_address; // get I/O address + + // wait for SCB command complete + wait_for_cmd_done(ioaddr + SCBCmd); + OUTW(RUC_ABORT, ioaddr + SCBCmd); + + // make sure no command operating + wait_for_cmd_done(ioaddr + SCBCmd); + + OUTL(0, ioaddr + SCBPointer); // load ru base address = 0 + OUTW(SCB_M | RUC_ADDR_LOAD, ioaddr + SCBCmd); + + // wait for SCB command complete + wait_for_cmd_done(ioaddr + SCBCmd); + // load pointer to Rx Ring + OUTL(VIRT_TO_BUS(p_i82559->rx_ring[0]), + ioaddr + SCBPointer); + OUTW(RUC_START, ioaddr + SCBCmd); + } + } + p_i82559->next_rx_descriptor = next_descriptor; +} + +// and the callback function + +static void i82559_recv( struct eth_drv_sc *sc, + struct eth_drv_sg *sg_list, int sg_len ) +{ + struct i82559 *p_i82559; + RFD *p_rfd; + int next_descriptor; + int total_len; + struct eth_drv_sg *last_sg; + volatile cyg_uint8 *from_p; + + p_i82559 = (struct i82559 *)sc->driver_private; + + IF_BAD_82559( p_i82559 ) { + os_printf( "i82559_recv: Bad device pointer %x\n", p_i82559 ); + return; + } + + next_descriptor = p_i82559->next_rx_descriptor; + p_rfd = p_i82559->rx_ring[next_descriptor]; + + CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" ); + CYG_ASSERT( (cyg_uint8 *)p_rfd < i82559_heap_free, "rfd over" ); + + CYG_ASSERT( p_rfd->status & RFD_STATUS_C, "No complete frame" ); + CYG_ASSERT( p_rfd->status & RFD_STATUS_EL, "No marked frame" ); + + if ( 0 == (p_rfd->status & RFD_STATUS_C) ) + return; + + total_len = p_rfd->count; + +#ifdef DEBUG_82559 + os_printf("Rx %d %x (status %x): %d sg's, %d bytes\n", + p_i82559->index, (int)priv, p_rfd->status, sg_len, total_len); +#endif + + // Copy the data to the network stack + from_p = &p_rfd->buffer[0]; + + // check we have memory to copy into; we would be called even if + // caller was out of memory in order to maintain our state. + if ( 0 == sg_len || 0 == sg_list ) + return; // caller was out of mbufs + + CYG_ASSERT( 0 < sg_len, "sg_len underflow" ); + CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" ); + + for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) { + cyg_uint8 *to_p; + int l; + + to_p = (cyg_uint8 *)(sg_list->buf); + l = sg_list->len; + + if ( 0 == l || 0 == to_p ) + return; // caller was out of mbufs + + if ( l > total_len ) + l = total_len; + + memcpy( to_p, (unsigned char *)from_p, l ); + from_p += l; + total_len -= l; + } + + CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" ); + CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" ); + CYG_ASSERT( &p_rfd->buffer[0] < from_p, "from_p wild in rx" ); + CYG_ASSERT( &p_rfd->buffer[0] + MAX_RX_PACKET_SIZE >= from_p, + "from_p overflow in rx" ); +} + + +// ------------------------------------------------------------------------ +// +// Function : InitTxRing +// +// ------------------------------------------------------------------------ +static void InitTxRing(struct i82559* p_i82559) +{ + int i; + cyg_uint32 ioaddr; + +#ifdef DEBUG_82559 + os_printf("InitTxRing %d\n", p_i82559->index); +#endif + ioaddr = p_i82559->io_address; + for ( i = 0; i < MAX_TX_DESCRIPTORS; i++) { + p_i82559->tx_ring[i] = (TxCB *)pciwindow_mem_alloc( + sizeof(TxCB) + MAX_TX_PACKET_SIZE); + p_i82559->tx_keys[i] = 0; + } + + ResetTxRing(p_i82559); +} + +// ------------------------------------------------------------------------ +// +// Function : ResetTxRing +// +// ------------------------------------------------------------------------ +static void ResetTxRing(struct i82559* p_i82559) +{ + int i; + cyg_uint32 ioaddr; + +#ifdef DEBUG_82559 + os_printf("ResetTxRing %d\n", p_i82559->index); +#endif + ioaddr = p_i82559->io_address; + p_i82559->tx_descriptor_add = + p_i82559->tx_descriptor_remove = 0; + p_i82559->tx_in_progress = + p_i82559->tx_queue_full = 0; + + for ( i = 0; i < MAX_TX_DESCRIPTORS; i++) { + TxCB *p_txcb = p_i82559->tx_ring[i]; + CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" ); + CYG_ASSERT( (cyg_uint8 *)p_txcb < i82559_heap_free, "txcb over" ); + + p_txcb->status = 0; + p_txcb->command = 0; + p_txcb->link = VIRT_TO_BUS((cyg_uint32)p_txcb); + p_txcb->tbd_address = 0xFFFFFFFF; + p_txcb->tbd_number = 0; + p_txcb->tx_threshold = 16; + p_txcb->eof = 1; + p_txcb->count = 0; + p_i82559->tx_keys[i] = 0; + } + + wait_for_cmd_done(ioaddr + SCBCmd); + OUTL(0, ioaddr + SCBPointer); + OUTW(CU_CMD_BASE, ioaddr + SCBCmd); +} + + + +// ------------------------------------------------------------------------ +// +// Function : i82559_can_send +// +// ------------------------------------------------------------------------ + +static int +i82559_can_send(struct eth_drv_sc *sc) +{ +// return 1; + + struct i82559 *p_i82559; + + p_i82559 = (struct i82559 *)sc->driver_private; + + IF_BAD_82559( p_i82559 ) { + os_printf( "i82559_send: Bad device pointer %x\n", p_i82559 ); + return 0; + } + + return ! p_i82559->tx_queue_full; +} + +// ------------------------------------------------------------------------ +// +// Function : i82559_send +// +// ------------------------------------------------------------------------ + +static void +i82559_send(struct eth_drv_sc *sc, + struct eth_drv_sg *sg_list, int sg_len, int total_len, + unsigned long key) +{ + struct i82559 *p_i82559; + int tx_descriptor_add; + TxCB *p_txcb; + cyg_uint32 ioaddr; + + p_i82559 = (struct i82559 *)sc->driver_private; + + IF_BAD_82559( p_i82559 ) { + os_printf( "i82559_send: Bad device pointer %x\n", p_i82559 ); + return; + } + +#ifdef DEBUG_82559 + os_printf("Tx %d %x: %d sg's, %d bytes, KEY %x\n", + p_i82559->index, (int)priv, sg_len, total_len, key ); +#endif + + if ( ! p_i82559->active ) + return; // device inactive, no return +#ifdef KEEP_STATISTICS + statistics[p_i82559->index].tx_count++; +#endif + ioaddr = p_i82559->io_address; // get device I/O address + + if ( p_i82559->tx_queue_full ) { +#ifdef KEEP_STATISTICS + statistics[p_i82559->index].tx_dropped++ +#endif + os_printf( "i82559_send: Queue full, device %x, key %x\n", + p_i82559, key ); + } + else { + struct eth_drv_sg *last_sg; + volatile cyg_uint8 *to_p; + + tx_descriptor_add = p_i82559->tx_descriptor_add; + + p_i82559->tx_keys[tx_descriptor_add] = key; + + p_txcb = p_i82559->tx_ring[tx_descriptor_add]; + + CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" ); + CYG_ASSERT( (cyg_uint8 *)p_txcb < i82559_heap_free, "txcb over" ); + + p_txcb->status = 0; + p_txcb->command = TxCB_CMD_TRANSMIT | TxCB_CMD_S + | TxCB_CMD_I | TxCB_CMD_EL; + p_txcb->link = VIRT_TO_BUS((cyg_uint32)p_txcb); + p_txcb->tbd_address = 0xFFFFFFFF; + p_txcb->tbd_number = 0; + p_txcb->tx_threshold = 16; + p_txcb->eof = 1; + p_txcb->count = total_len; + + // Copy from the sglist into the txcb + to_p = &p_txcb->buffer[0]; + + CYG_ASSERT( 0 < sg_len, "sg_len underflow" ); + CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" ); + + for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) { + cyg_uint8 *from_p; + int l; + + from_p = (cyg_uint8 *)(sg_list->buf); + l = sg_list->len; + + if ( l > total_len ) + l = total_len; + + memcpy( (unsigned char *)to_p, from_p, l ); + to_p += l; + total_len -= l; + + if ( 0 > total_len ) + break; // Should exit via sg_last normally + } + + CYG_ASSERT( 0 == total_len, "length mismatch in tx" ); + CYG_ASSERT( last_sg == sg_list, "sg count mismatch in tx" ); + CYG_ASSERT( &p_txcb->buffer[0] < to_p, "to_p wild in tx" ); + CYG_ASSERT( &p_txcb->buffer[0] + MAX_TX_PACKET_SIZE >= to_p, + "to_p overflow in tx" ); + + if ( ++tx_descriptor_add >= MAX_TX_DESCRIPTORS) + tx_descriptor_add = 0; + + // no more interrupts until started + Mask82559Interrupt(p_i82559); + + p_i82559->tx_descriptor_add = tx_descriptor_add; + + if ( p_i82559->tx_descriptor_remove == tx_descriptor_add ) + p_i82559->tx_queue_full = 1; + + if ( ! p_i82559->tx_in_progress ) { // if no Tx operation running +#ifdef DEBUG_82559 + os_printf("Tx %d %x: Starting Engines, KEY %x\n", + p_i82559->index, (int)priv, key ); +#endif + // flag start of Tx operation + p_i82559->tx_in_progress = 1; + // make sure no command operating + wait_for_cmd_done(ioaddr + SCBCmd); + // start Tx operation + OUTL(VIRT_TO_BUS(p_txcb), ioaddr + SCBPointer); + OUTW(CU_START, ioaddr + SCBCmd); + } + UnMask82559Interrupt(p_i82559); // Allow this device to interrupt + } + +} + + + +// ------------------------------------------------------------------------ +// +// Function : TxComplete +// +// ------------------------------------------------------------------------ +static unsigned long TxComplete(struct i82559* p_i82559) +{ + int tx_descriptor_remove; + cyg_uint32 ioaddr; + TxCB *p_txcb; + unsigned long key; + + tx_descriptor_remove = p_i82559->tx_descriptor_remove; + + CYG_ASSERT( p_i82559->tx_in_progress, "Tx not in progress but Tx intr" ); + + key = p_i82559->tx_keys[tx_descriptor_remove]; + if ( ++tx_descriptor_remove >= MAX_TX_DESCRIPTORS ) + tx_descriptor_remove = 0; + p_i82559->tx_descriptor_remove = tx_descriptor_remove; + p_i82559->tx_queue_full = 0; + if ( p_i82559->tx_descriptor_add != tx_descriptor_remove ) { + // get device I/O address + ioaddr = p_i82559->io_address; + p_txcb = p_i82559->tx_ring[tx_descriptor_remove]; + CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" ); + CYG_ASSERT( (cyg_uint8 *)p_txcb < i82559_heap_free, "txcb over" ); + // make sure no command operating + wait_for_cmd_done(ioaddr + SCBCmd); + // start Tx operation + OUTL(VIRT_TO_BUS(p_txcb), ioaddr + SCBPointer); + OUTW(CU_START, ioaddr + SCBCmd); + } + else + p_i82559->tx_in_progress = 0; + + return key; +} + +// ------------------------------------------------------------------------ + +static void +PacketTxDone(struct i82559* p_i82559, unsigned long key) +{ + struct cyg_netdevtab_entry *ndp; + struct eth_drv_sc *sc; + + // Just tell the stack that this device has done a Tx. + ndp = (struct cyg_netdevtab_entry *)(p_i82559->ndp); + sc = (struct eth_drv_sc *)(ndp->device_instance); + + CHECK_NDP_SC_LINK(); + +#ifdef DEBUG_82559 + os_printf("TxDone %d %x: KEY %x\n", + p_i82559->index, (int)p_i82559, key ); +#endif + + eth_drv_tx_done( sc, key, 1 /* status */ ); +} + + +// ------------------------------------------------------------------------ +// +// Function : QueueThreadRequest +// +// ------------------------------------------------------------------------ +static void QueueThreadRequest(int type, + struct i82559* p_i82559, + unsigned long key) +{ + if ( ! i82559_q_full ) { + + i82559_queue[i82559_q_in].request = type; + i82559_queue[i82559_q_in].p = p_i82559; + i82559_queue[i82559_q_in].key = key; + + if ( ++i82559_q_in >= I82559_QUEUE_SIZE ) + i82559_q_in = 0; + + if ( i82559_q_in == i82559_q_out ) + i82559_q_full = 1; + } +} + + + +// ------------------------------------------------------------------------ +// +// Function : i82559_isr +// +// ------------------------------------------------------------------------ +int last_status[16] = { 0 }; +int last_index = 0; + +static int i82559_isr(struct i82559* p_i82559) +{ + cyg_uint16 status; + cyg_uint32 io_address; + int return_value; + + IF_BAD_82559( p_i82559 ) { + os_printf( "i82559_isr: Bad device pointer %x\n", p_i82559 ); + return 0; + } + + io_address = p_i82559->io_address; + status = INW(io_address + SCBStatus); + OUTW(status & 0xFC00, io_address + SCBStatus); + + return_value = 0; + + last_status[last_index++] = status; + last_status[last_index &= 15] = -1; + + // receiver left ready state ? + if ( status & SCB_STATUS_RNR ) { +#ifdef KEEP_STATISTICS + statistics[p_i82559->index].rx_resource++; +#endif + // flag out of resources + p_i82559->out_of_resources = 1; + } + + // frame receive interrupt ? + if ( status & SCB_STATUS_FR ) { +#ifdef KEEP_STATISTICS + statistics[p_i82559->index].rx_count++; +#endif + QueueThreadRequest(PACKET_RX, p_i82559, 0); + return_value = 1; + } + + // transmit interrupt ? + if ( status & SCB_STATUS_CX ) { + unsigned long key; +#ifdef KEEP_STATISTICS + statistics[p_i82559->index].tx_complete++; +#endif + key = TxComplete(p_i82559); + QueueThreadRequest(PACKET_TX, p_i82559, key); + return_value = 1; + } + + return return_value; +} + +// ------------------------------------------------------------------------ +// +// Function : i82559_mux_isr +// +// ------------------------------------------------------------------------ +static int i82559_mux_isr(void) +{ + int return_value = 0; + + static int mux_device_index = 0; + + int device_index = mux_device_index; + + return_value = i82559_isr( &i82559[device_index] ); + + mux_device_index ^= 1; // look at the other one first next time. + + if ( return_value ) + return return_value; + + device_index = mux_device_index; + + return_value = i82559_isr( &i82559[device_index] ); + + return return_value; +} + +// ------------------------------------------------------------------------ +// +// Function : i82559_reset +// +// ------------------------------------------------------------------------ +static void i82559_reset(struct i82559* p_i82559) +{ + cyg_uint32 ioaddr; + int count; + + ioaddr = p_i82559->io_address; + // make sure no command operating + wait_for_cmd_done(ioaddr + SCBCmd); + + OUTL(I82559_SELECTIVE_RESET, ioaddr + SCBPort); + + for (count = 10 ; count-- ; ) { + udelay(1000); + } + + OUTL(I82559_RESET, ioaddr + SCBPort); + + for (count = 10 ; count-- ; ) { + udelay(1000); + } +} + + +// ------------------------------------------------------------------------ +// +// Function : eth_set_promiscuous_mode +// +// Return : 0 = It worked. +// non0 = It failed. +// ------------------------------------------------------------------------ + +static int eth_set_promiscuous_mode(struct i82559* p_i82559) +{ + cyg_uint32 ioaddr; + volatile CONFIG_CMD_STRUCT *ccs; + + IF_BAD_82559( p_i82559 ) { + os_printf( "eth_set_promiscuos_mode: Bad device pointer %x\n", + p_i82559 ); + return -1; + } + + ioaddr = p_i82559->io_address; + wait_for_cmd_done(ioaddr + SCBCmd); + // load cu base address = 0 */ + OUTL(0, ioaddr + SCBPointer); + // 32 bit linear addressing used + + OUTW(SCB_M | CUC_ADDR_LOAD, ioaddr + SCBCmd); + // wait for SCB command complete + wait_for_cmd_done(ioaddr + SCBCmd); + + ccs = (CONFIG_CMD_STRUCT *)mem_reserved_ioctl; + + // Check the malloc we did earlier worked + if (ccs == (void*)0) + return 2; // Failed + + ccs->cb_entry.cb_cmd=0x2; + ccs->cb_entry.cb_cmd_word=0x0; + ccs->cb_entry.cb_status_word=0x0; + ccs->cb_entry.cb_int=0; + ccs->cb_entry.cb_suspend=1; + ccs->cb_entry.cb_el=1; + ccs->cb_entry.cb_complete=0; + ccs->cb_entry.cb_link_offset=VIRT_TO_BUS((cyg_uint32)&ccs); + + // Default values from the Intel Manual + ccs->config_bytes[0]=0x13; + ccs->config_bytes[1]=0x8; + ccs->config_bytes[2]=0x0; + ccs->config_bytes[3]=0x0; + ccs->config_bytes[4]=0x0; + ccs->config_bytes[5]=0x0; + ccs->config_bytes[6]=0xb2; + ccs->config_bytes[7]=0x0; + ccs->config_bytes[8]=0x0; + ccs->config_bytes[9]=0x0; + ccs->config_bytes[10]=0x28; + ccs->config_bytes[11]=0x0; + ccs->config_bytes[12]=0x60; + ccs->config_bytes[13]=0x0; // arp + ccs->config_bytes[14]=0x0; // arp + + ccs->config_bytes[15]=0x81; // promiscuous mode set + + ccs->config_bytes[16]=0x0; + ccs->config_bytes[17]=0x40; + ccs->config_bytes[18]=0x70; + + // wait for SCB command complete + wait_for_cmd_done(ioaddr + SCBCmd); + + OUTL(VIRT_TO_BUS(ccs), ioaddr + SCBPointer); + OUTW(SCB_M | CUC_START, ioaddr + SCBCmd); + + // now check for result ... + wait_for_cmd_done(ioaddr + SCBCmd); + + if ( (!ccs->cb_entry.cb_ok) || (!ccs->cb_entry.cb_complete) ) + return 1; // Failed + return 0; // OK +} + +// ------------------------------------------------------------------------ +// +// Function : eth_set_mac_address +// +// Return : 0 = It worked. +// non0 = It failed. +// ------------------------------------------------------------------------ +static int eth_set_mac_address(struct i82559* p_i82559, char *addr) +{ + int addr_length; + + cyg_uint32 ioaddr; + volatile CONFIG_CMD_STRUCT *ccs; + + IF_BAD_82559( p_i82559 ) { + os_printf( "eth_set_mac_address : Bad device pointer %x\n", + p_i82559 ); + return -1; + } + + ioaddr = p_i82559->io_address; + + wait_for_cmd_done(ioaddr + SCBCmd); + // load cu base address = 0 */ + OUTL(0, ioaddr + SCBPointer); + // 32 bit linear addressing used + + OUTW(SCB_M | CUC_ADDR_LOAD, ioaddr + SCBCmd); + // wait for SCB command complete + wait_for_cmd_done(ioaddr + SCBCmd); + + ccs = (CONFIG_CMD_STRUCT *)mem_reserved_ioctl; + if (ccs == (void*)0) + return 2; + + ccs->cb_entry.cb_cmd=0x1; + ccs->cb_entry.cb_cmd_word=0x0; + ccs->cb_entry.cb_status_word=0x0; + ccs->cb_entry.cb_int=0; + ccs->cb_entry.cb_suspend=1; + ccs->cb_entry.cb_el=1; + + memcpy((char *)(ccs->config_bytes),addr,6); + + ccs->config_bytes[6]=0x0; + ccs->config_bytes[7]=0x0; + + ioaddr = p_i82559->io_address; + + OUTL(VIRT_TO_BUS(ccs), ioaddr + SCBPointer); + OUTW(SCB_M | CUC_START, ioaddr + SCBCmd); + // Next delay seems to be required, otherwise, + // cb_ok/cb_complete won't be set later. + + udelay(100); + wait_for_cmd_done(ioaddr + SCBCmd); + + // now check for result ... + if ( (!ccs->cb_entry.cb_ok) || (!ccs->cb_entry.cb_complete) ) + return 3; + + // now set this address in the device eeprom .... + (void)memcpy(eeprom_burn,addr,6); + eeprom_burn[20] &= 0xfe; + eeprom_burn[20] |= p_i82559->index; + + addr_length=6; // eeprom address word length in bits ... + program_eeprom(ioaddr,addr_length,eeprom_burn); + + // now update netword stack ... + // FIXME - no feedback to stack when MAC changes + + // update 82559 driver data structure ... + (void)memcpy((char *)(p_i82559->mac_address),addr,6); + p_i82559->mac_addr_ok = 1; + return 0; +} + +// ------------------------------------------------------------------------ +// +// Function : write_enable_eeprom +// +// ------------------------------------------------------------------------ +static int write_enable_eeprom(long ioaddr, int addr_len) +{ + int ee_addr = ioaddr + SCBeeprom; + int write_en_cmd = EE_WRITE_EN_CMD; + int i; + + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(1); + OUTW(EE_ENB, ee_addr); + eeprom_delay(1); + + + // Shift the wr/er enable command bits out. + for (i = (addr_len+2); i >= 0; i--) { + short dataval = (write_en_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + OUTW(EE_ENB | dataval, ee_addr); + eeprom_delay(1); + OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(1); + } + + // Terminate the EEPROM access. + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(1); + return 0; +} + +// ------------------------------------------------------------------------ +// +// Function : write_eeprom +// +// Return : 0 = It worked. +// 1 = It failed. +// ------------------------------------------------------------------------ +static int write_eeprom(long ioaddr, int location, + int addr_len, unsigned short value) +{ + unsigned short retval = 0; + int ee_addr = ioaddr + SCBeeprom; + int write_cmd = location | EE_WRITE_CMD; + int i; + + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(1); + OUTW(EE_ENB, ee_addr); + eeprom_delay(1); + + // Shift the write command bits out. + for (i = (addr_len+2); i >= 0; i--) { + short dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + OUTW(EE_ENB | dataval, ee_addr); + eeprom_delay(1); + OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(1); + } + OUTW(EE_ENB, ee_addr); + eeprom_delay(1); + + for (i = 15; i >= 0; i--) { + short dataval = (value & (1 << i)) ? EE_DATA_WRITE : 0; + OUTW(EE_ENB | dataval, ee_addr); + eeprom_delay(1); + OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(1); + } + + // Terminate the EEPROM access. + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(10000); + return retval; +} + +// ------------------------------------------------------------------------ +// +// Function : Program EEPROM +// Parameters : ioaddr +// addr_length in bits (8 or 6) +// char[128] data to program +// Return : void +// ------------------------------------------------------------------------ +static void program_eeprom(cyg_uint32 ioaddr, + cyg_uint32 eeprom_size, + cyg_uint8 * data) +{ + cyg_uint32 i; + cyg_uint16 checksum = 0; + cyg_uint16 value; + cyg_uint16 * cyg_uint16_data = (cyg_uint16 *) data; + + // first enable erase/write operations on the eeprom ... + // this is done through the EWEN instruction ... + + write_enable_eeprom(ioaddr,eeprom_size); + + // Now write the bytes, except the checksum + for (i=0 ; i< 63 ; i++) { + value = ((unsigned short*)cyg_uint16_data)[i]; + checksum += value; + write_eeprom(ioaddr,i,eeprom_size,value); + } + + // Work out the checksum and program it + value = 0xBABA - checksum; + write_eeprom(ioaddr,i,eeprom_size,value); +} + +// ------------------------------------------------------------------------ +// +// Function : eth_get_mac_address +// +// ------------------------------------------------------------------------ +#ifdef ETH_DRV_GET_MAC_ADDRESS +static int eth_get_mac_address(struct i82559* p_i82559, char *addr) +{ + IF_BAD_82559( p_i82559 ) { + os_printf( "eth_get_mac_address : Bad device pointer %x\n", + p_i82559 ); + return -1; + } + + memcpy( addr, (char *)(&p_i82559->mac_address[0]), 6 ); + return (0); +} +#endif +// ------------------------------------------------------------------------ +// +// Function : i82559_ioctl +// +// ------------------------------------------------------------------------ +static int i82559_ioctl(struct eth_drv_sc *sc, unsigned long key, + void *data, int data_length) +{ + struct i82559 *p_i82559; + + p_i82559 = (struct i82559 *)sc->driver_private; + + IF_BAD_82559( p_i82559 ) { + os_printf( "i82559_ioctl/control: Bad device pointer %x\n", p_i82559 ); + return -1; + } + + switch ( key ) { + +#ifdef ETH_DRV_SET_MAC_ADDRESS + case ETH_DRV_SET_MAC_ADDRESS: + if ( 6 != data_length ) + return -2; + eth_set_mac_address( p_i82559, data ); + return 0; +#endif + +#ifdef ETH_DRV_GET_MAC_ADDRESS + case ETH_DRV_GET_MAC_ADDRESS: + eth_get_mac_address( p_i82559, data ); + return 0; +#endif + + default: + break; + } + return -1; +} + +// ------------------------------------------------------------------------ +// +// INTERRUPT HANDLERS +// +// ------------------------------------------------------------------------ + +static cyg_uint32 eth_isr(cyg_vector_t vector, cyg_addrword_t data) +{ + int schedule_dsr; + + cyg_drv_interrupt_mask(vector); // mask this interrupt + + schedule_dsr = i82559_isr( (struct i82559 *)data ); // process interrupt + + cyg_drv_interrupt_acknowledge(vector); // acknowledge interrupt + + // schedule further processing ? + if ( schedule_dsr ) + return CYG_ISR_CALL_DSR; // yes, schedule DSR + + // else... + cyg_drv_interrupt_unmask(vector); // allow more of these interrupts + return CYG_ISR_HANDLED; +} + + + +static cyg_uint32 eth_mux_isr(cyg_vector_t vector, cyg_addrword_t data) +{ + int schedule_dsr; + + cyg_drv_interrupt_mask( vector ); // mask this interrupt + + schedule_dsr = i82559_mux_isr(); // process interrupt + + cyg_drv_interrupt_acknowledge( vector ); // ack interrupt + + // schedule further processing ? + if ( schedule_dsr ) + return CYG_ISR_CALL_DSR; // yes, schedule DSR + + // else... + cyg_drv_interrupt_unmask( vector ); // allow more of these interrupts + return CYG_ISR_HANDLED; +} + +// ------------------------------------------------------------------------ + +void eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + while ( (i82559_q_out != i82559_q_in) || (i82559_q_full) ) { + switch ( i82559_queue[i82559_q_out].request ) { + case PACKET_RX: + PacketRxReady(i82559_queue[i82559_q_out].p); + break; + + case PACKET_TX: + PacketTxDone(i82559_queue[i82559_q_out].p, + i82559_queue[i82559_q_out].key); + break; + } + i82559_q_full = 0; + if ( ++i82559_q_out == I82559_QUEUE_SIZE ) + i82559_q_out = 0; + } + // allow interrupts to continue from whichever source + // (if multiple device actions were dispatched in this DSR call, + // another call will occur almost immediately) + cyg_drv_interrupt_unmask(vector); +} + +// ------------------------------------------------------------------------ +// +// Function : pci_init_find_82559s +// +// This is called exactly once at the start of time to: +// o scan the PCI bus for objects +// o record them in the device table +// o acquire all the info needed for the driver to access them +// o instantiate interrupts for them +// o attach those interrupts appropriately +// ------------------------------------------------------------------------ +static int +pci_init_find_82559s( void ) +{ + cyg_pci_device_id devid; + cyg_pci_device dev_info; + cyg_uint16 cmd; + int device_index; + + // MUX interrupt - special case when 2 cards share one intr. + static cyg_handle_t mux_interrupt_handle = 0; + static cyg_interrupt mux_interrupt_object; + +#ifdef DEBUG + db_printf("pci_init_find_82559s()\n"); +#endif + + // allocate memory to be used in ioctls later + if (mem_reserved_ioctl != (void*)0) { + db_printf("pci_init_find_82559s() called > once\n"); + return 0; + } + + // First initialize the heap in PCI window'd memory + i82559_heap_size = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE; + i82559_heap_base = (cyg_uint8 *)CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE; + i82559_heap_free = i82559_heap_base; + + mem_reserved_ioctl = pciwindow_mem_alloc(MAX_MEM_RESERVED_IOCTL); + + // initialize the event queue for DSR actions + i82559_q_out = i82559_q_in = 0; + i82559_q_full = 0; + + cyg_pci_init(); +#ifdef DEBUG + db_printf("Finished cyg_pci_init();\n"); +#endif + devid = CYG_PCI_NULL_DEVID; + + for (device_index = 0; device_index < MAX_82559; device_index++) { + struct i82559 *p_i82559 = &i82559[device_index]; + p_i82559->index = device_index; + + if (cyg_pci_find_device(0x8086, 0x1229, &devid) ) { +#ifdef DEBUG + db_printf("eth%d = 82559\n", device_index); +#endif + cyg_pci_get_device_info(devid, &dev_info); + + if (cyg_pci_translate_interrupt(&dev_info, &p_i82559->vector)) { +#ifdef DEBUG + db_printf(" Wired to HAL vector %d\n", p_i82559->vector); +#endif + cyg_drv_interrupt_create( + p_i82559->vector, + 0, // Priority - unused + (CYG_ADDRWORD)p_i82559, // Data item passed to ISR + eth_isr, // ISR + eth_dsr, // DSR + &p_i82559->interrupt_handle, // handle to intr obj + &p_i82559->interrupt_object ); // space for int obj + + cyg_drv_interrupt_attach(p_i82559->interrupt_handle); + + // Don't unmask the interrupt yet, that could get us into a + // race. + + // ALSO attach it to interrupt #18 for multiplexed + // interrupts. This is for certain boards where the + // PCI backplane is wired "straight through" instead of + // with a rotation of interrupt lines in the different + // slots. + if ( ! mux_interrupt_handle ) { +#ifdef DEBUG + db_printf(" Also attaching to HAL vector %d\n", + CYGNUM_HAL_INTERRUPT_PCI_IRQ); +#endif + cyg_drv_interrupt_create( + CYGNUM_HAL_INTERRUPT_PCI_IRQ, + 0, // Priority - unused + 0, // Data item passed to ISR (not used) + eth_mux_isr, // ISR + eth_dsr, // DSR + &mux_interrupt_handle, + &mux_interrupt_object ); + + cyg_drv_interrupt_attach(mux_interrupt_handle); + } + } + else { + p_i82559->vector=0; +#ifdef DEBUG + db_printf(" Does not generate interrupts.\n"); +#endif + } + + if (cyg_pci_configure_device(&dev_info)) { +#ifdef DEBUG + int i; + db_printf("Found device on bus %d, devfn 0x%02x:\n", + CYG_PCI_DEV_GET_BUS(devid), + CYG_PCI_DEV_GET_DEVFN(devid)); + + if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) { + db_printf(" Note that board is active. Probed" + " sizes and CPU addresses invalid!\n"); + } + db_printf(" Vendor 0x%04x", dev_info.vendor); + db_printf("\n Device 0x%04x", dev_info.device); + db_printf("\n Command 0x%04x, Status 0x%04x\n", + dev_info.command, dev_info.status); + + db_printf(" Class/Rev 0x%08x", dev_info.class_rev); + db_printf("\n Header 0x%02x\n", dev_info.header_type); + + db_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n", + dev_info.header.normal.sub_vendor, + dev_info.header.normal.sub_id); + + for(i = 0; i < CYG_PCI_MAX_BAR; i++) { + db_printf(" BAR[%d] 0x%08x /", i, dev_info.base_address[i]); + db_printf(" probed size 0x%08x / CPU addr 0x%08x\n", + dev_info.base_size[i], dev_info.base_map[i]); + } + db_printf(" eth%d configured\n", device_index); +#endif + p_i82559->found = 1; + p_i82559->active = 0; + p_i82559->devid = devid; + p_i82559->memory_address = dev_info.base_map[0]; + p_i82559->io_address = dev_info.base_map[1]; +#ifdef DEBUG + db_printf(" memory address = 0x%08x\n", dev_info.base_map[0]); + db_printf(" I/O address = 0x%08x\n", dev_info.base_map[1]); +#endif + + // Don't use cyg_pci_set_device_info since it clears + // some of the fields we want to print out below. + cyg_pci_read_config_uint16(dev_info.devid, CYG_PCI_CFG_COMMAND, &cmd); + cmd |= CYG_PCI_CFG_COMMAND_IO // enable I/O space + | CYG_PCI_CFG_COMMAND_MEMORY // enable memory space + | CYG_PCI_CFG_COMMAND_MASTER; // enable bus master + cyg_pci_write_config_uint16(dev_info.devid, CYG_PCI_CFG_COMMAND, cmd); + + // Now the PCI part of the device is configured, reset it. This + // should make it safe to enable the interrupt + i82559_reset(p_i82559); + + if (p_i82559->vector != 0) { + cyg_interrupt_acknowledge(p_i82559->vector); + cyg_drv_interrupt_unmask(p_i82559->vector); + } +#ifdef DEBUG + db_printf(" **** Device enabled for I/O and Memory and Bus Master\n"); +#endif + } + else { + p_i82559->found = 0; + p_i82559->active = 0; + db_printf("Failed to configure device %d\n",device_index); + } + } + else { + p_i82559->found = 0; + p_i82559->active = 0; + db_printf("eth%d not found\n", device_index); + } + } + + // Now enable the mux shared interrupt if it is in use + if (mux_interrupt_handle) { + cyg_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_PCI_IRQ); + cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_PCI_IRQ); + } + + return 1; +} + + + +// ------------------------------------------------------------------------ + +// EOF if_ebsa285.c diff --git a/packages/devs/eth/arm/edb7xxx/current/ChangeLog b/packages/devs/eth/arm/edb7xxx/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/eth/arm/edb7xxx/current/ChangeLog @@ -0,0 +1,100 @@ +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-03-28 Gary Thomas + + * src/if_edb7xxx.c (cs8900_recv): Handle case where there were + no buffers (and thus the sg_list[] has NULL pointers). + +2000-03-06 Gary Thomas + + * src/if_edb7xxx.c: Use new driver API. + +2000-02-29 Gary Thomas + + * src/if_edb7xxx.c: Support new API - hardware support of 'ioctl' + and tagged output. + +2000-02-14 Gary Thomas + + * cdl/edb7xxx_eth_drivers.cdl: Add CDL magic to indicate availability + of 'eth0' interface. + +2000-02-09 Gary Thomas + + * cdl/edb7xxx_eth_drivers.cdl: Rename CDL file. + +2000-02-08 John Dallaway + + * cdl/eth_drivers.cdl: + + Tidy display strings. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== + + + diff --git a/packages/devs/eth/arm/edb7xxx/current/cdl/edb7xxx_eth_drivers.cdl b/packages/devs/eth/arm/edb7xxx/current/cdl/edb7xxx_eth_drivers.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/eth/arm/edb7xxx/current/cdl/edb7xxx_eth_drivers.cdl @@ -0,0 +1,76 @@ +# ==================================================================== +# +# edb7xxx_eth_drivers.cdl +# +# Ethernet drivers - platform dependent support for Cirrus Logic +# EDB7xxx family of development boards +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): gthomas +# Original data: gthomas +# Contributors: +# Date: 2000-01-25 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + +cdl_package CYGPKG_DEVS_ETH_ARM_EDB7XXX { + display "Cirrus Logic ethernet driver" + + parent CYGPKG_NET_ETH_DRIVERS + active_if CYGPKG_NET_ETH_DRIVERS + active_if CYGPKG_HAL_ARM_EDB7XXX + + implements CYGHWR_NET_DRIVERS + implements CYGHWR_NET_DRIVER_ETH0 + include_dir . +# include_files ; # none _exported_ whatsoever + description "Ethernet driver for Cirrus Logic EDB7xxx boards." + compile -library=libextras.a if_edb7xxx.c + + cdl_component CYGPKG_DEVS_ETH_ARM_EDB7XXX_OPTIONS { + display "Cirrus Logic ethernet driver build options" + flavor none + no_define + + cdl_option CYGPKG_DEVS_ETH_ARM_EDB7XXX_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "-D_KERNEL -D__ECOS" } + description " + This option modifies the set of compiler flags for + building the Cirrus Logic ethernet driver package. + These flags are used in addition + to the set of global flags." + } + } +} + diff --git a/packages/devs/eth/arm/edb7xxx/current/doc/README b/packages/devs/eth/arm/edb7xxx/current/doc/README new file mode 100644 --- /dev/null +++ b/packages/devs/eth/arm/edb7xxx/current/doc/README @@ -0,0 +1,18 @@ +Preliminary documentation for Cirrus Logic EDB72xx Ethernet driver +================================================================== + +This driver has been tested on both the EDB7211 (EDB7111-2) and +EDB7209 boards. + +There is a problem with some EDB7209 boards which keeps the ethernet +chip from generating interrupts. The following hardware change will +allow this (and thus the driver to work), but it precludes the +generation of interrupts when using the parallel port. + + Remove resistor R168 + Remove all jumpers from JP45 + +This problem is known to exist at least through EDB7209-2B.0. It is +unknown [by the eCos team] if later revisions from Cirrus Logic have +fixed this problem. + diff --git a/packages/devs/eth/arm/edb7xxx/current/src/cs8900.h b/packages/devs/eth/arm/edb7xxx/current/src/cs8900.h new file mode 100644 --- /dev/null +++ b/packages/devs/eth/arm/edb7xxx/current/src/cs8900.h @@ -0,0 +1,209 @@ +//========================================================================== +// +// dev/cs8900.h +// +// Cirrus Logic CS8900 Ethernet chip +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 2000-01-10 +// Purpose: +// Description: +// +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +// Cirrus Logic CS8900A Ethernet + +// Assumption - all registers are 16 bits + +// Directly visible registers +#define CS8900_RTDATA *(volatile unsigned short *)(CS8900_BASE+0x00) +#define CS8900_TxCMD *(volatile unsigned short *)(CS8900_BASE+0x08) +#define CS8900_TxLEN *(volatile unsigned short *)(CS8900_BASE+0x0C) +#define CS8900_ISQ *(volatile unsigned short *)(CS8900_BASE+0x10) +#define CS8900_PPTR *(volatile unsigned short *)(CS8900_BASE+0x14) +#define CS8900_PDATA *(volatile unsigned short *)(CS8900_BASE+0x18) + +#define ISQ_RxEvent 0x04 +#define ISQ_TxEvent 0x08 +#define ISQ_BufEvent 0x0C +#define ISQ_RxMissEvent 0x10 +#define ISQ_TxColEvent 0x12 +#define ISQ_EventMask 0x3F + +// Registers available via "page pointer" (indirect access) +#define PP_ChipID 0x0000 // Chip identifier - must be 0x630E +#define PP_ChipRev 0x0002 // Chip revision, model codes + +#define PP_IntReg 0x0022 // Interrupt configuration +#define PP_IntReg_IRQ0 0x0000 // Use INTR0 pin +#define PP_IntReg_IRQ1 0x0001 // Use INTR1 pin +#define PP_IntReg_IRQ2 0x0002 // Use INTR2 pin +#define PP_IntReg_IRQ3 0x0003 // Use INTR3 pin + +#define PP_RxCFG 0x0102 // Receiver configuration +#define PP_RxCFG_Skip1 0x0040 // Skip (i.e. discard) current frame +#define PP_RxCFG_Stream 0x0080 // Enable streaming mode +#define PP_RxCFG_RxOK 0x0100 // RxOK interrupt enable +#define PP_RxCFG_RxDMAonly 0x0200 // Use RxDMA for all frames +#define PP_RxCFG_AutoRxDMA 0x0400 // Select RxDMA automatically +#define PP_RxCFG_BufferCRC 0x0800 // Include CRC characters in frame +#define PP_RxCFG_CRC 0x1000 // Enable interrupt on CRC error +#define PP_RxCFG_RUNT 0x2000 // Enable interrupt on RUNT frames +#define PP_RxCFG_EXTRA 0x4000 // Enable interrupt on frames with extra data + +#define PP_RxCTL 0x0104 // Receiver control +#define PP_RxCTL_IAHash 0x0040 // Accept frames that match hash +#define PP_RxCTL_Promiscuous 0x0080 // Accept any frame +#define PP_RxCTL_RxOK 0x0100 // Accept well formed frames +#define PP_RxCTL_Multicast 0x0200 // Accept multicast frames +#define PP_RxCTL_IA 0x0400 // Accept frame that matches IA +#define PP_RxCTL_Broadcast 0x0800 // Accept broadcast frames +#define PP_RxCTL_CRC 0x1000 // Accept frames with bad CRC +#define PP_RxCTL_RUNT 0x2000 // Accept runt frames +#define PP_RxCTL_EXTRA 0x4000 // Accept frames that are too long + +#define PP_TxCFG 0x0106 // Transmit configuration +#define PP_TxCFG_CRS 0x0040 // Enable interrupt on loss of carrier +#define PP_TxCFG_SQE 0x0080 // Enable interrupt on Signal Quality Error +#define PP_TxCFG_TxOK 0x0100 // Enable interrupt on successful xmits +#define PP_TxCFG_Late 0x0200 // Enable interrupt on "out of window" +#define PP_TxCFG_Jabber 0x0400 // Enable interrupt on jabber detect +#define PP_TxCFG_Collision 0x0800 // Enable interrupt if collision +#define PP_TxCFG_16Collisions 0x8000 // Enable interrupt if > 16 collisions + +#define PP_TxCmd 0x0108 // Transmit command status +#define PP_TxCmd_TxStart_5 0x0000 // Start after 5 bytes in buffer +#define PP_TxCmd_TxStart_381 0x0040 // Start after 381 bytes in buffer +#define PP_TxCmd_TxStart_1021 0x0080 // Start after 1021 bytes in buffer +#define PP_TxCmd_TxStart_Full 0x00C0 // Start after all bytes loaded +#define PP_TxCmd_Force 0x0100 // Discard any pending packets +#define PP_TxCmd_OneCollision 0x0200 // Abort after a single collision +#define PP_TxCmd_NoCRC 0x1000 // Do not add CRC +#define PP_TxCmd_NoPad 0x2000 // Do not pad short packets + +#define PP_BufCFG 0x010A // Buffer configuration +#define PP_BufCFG_SWI 0x0040 // Force interrupt via software +#define PP_BufCFG_RxDMA 0x0080 // Enable interrupt on Rx DMA +#define PP_BufCFG_TxRDY 0x0100 // Enable interrupt when ready for Tx +#define PP_BufCFG_TxUE 0x0200 // Enable interrupt in Tx underrun +#define PP_BufCFG_RxMiss 0x0400 // Enable interrupt on missed Rx packets +#define PP_BufCFG_Rx128 0x0800 // Enable Rx interrupt after 128 bytes +#define PP_BufCFG_TxCol 0x1000 // Enable int on Tx collision ctr overflow +#define PP_BufCFG_Miss 0x2000 // Enable int on Rx miss ctr overflow +#define PP_BufCFG_RxDest 0x8000 // Enable int on Rx dest addr match + +#define PP_LineCTL 0x0112 // Line control +#define PP_LineCTL_Rx 0x0040 // Enable receiver +#define PP_LineCTL_Tx 0x0080 // Enable transmitter + +#define PP_RER 0x0124 // Receive event +#define PP_RER_IAHash 0x0040 // Frame hash match +#define PP_RER_Dribble 0x0080 // Frame had 1-7 extra bits after last byte +#define PP_RER_RxOK 0x0100 // Frame received with no errors +#define PP_RER_Hashed 0x0200 // Frame address hashed OK +#define PP_RER_IA 0x0400 // Frame address matched IA +#define PP_RER_Broadcast 0x0800 // Broadcast frame +#define PP_RER_CRC 0x1000 // Frame had CRC error +#define PP_RER_RUNT 0x2000 // Runt frame +#define PP_RER_EXTRA 0x4000 // Frame was too long + +#define PP_TER 0x0128 // Transmit event +#define PP_TER_CRS 0x0040 // Carrier lost +#define PP_TER_SQE 0x0080 // Signal Quality Error +#define PP_TER_TxOK 0x0100 // Packet sent without error +#define PP_TER_Late 0x0200 // Out of window +#define PP_TER_Jabber 0x0400 // Stuck transmit? +#define PP_TER_NumCollisions 0x7800 // Number of collisions +#define PP_TER_16Collisions 0x8000 // > 16 collisions + +#define PP_SelfCtl 0x0114 // Chip control +#define PP_SelfCtl_Reset 0x0040 // Self-clearing reset + +#define PP_BusCtl 0x0116 // Bus control +#define PP_BusCtl_ResetRxDMA 0x0040 // Reset receiver DMA engine +#define PP_BusCtl_DMAextend 0x0100 +#define PP_BusCtl_UseSA 0x0200 +#define PP_BusCtl_MemoryE 0x0400 // Enable "memory mode" +#define PP_BusCtl_DMAburst 0x0800 +#define PP_BusCtl_IOCH_RDYE 0x1000 +#define PP_BusCtl_RxDMAsize 0x2000 +#define PP_BusCtl_EnableIRQ 0x8000 // Enable interrupts + +#define PP_LineStat 0x0134 // Line status +#define PP_LineStat_LinkOK 0x0080 // Line is connected and working +#define PP_LineStat_AUI 0x0100 // Connected via AUI +#define PP_LineStat_10BT 0x0200 // Connected via twisted pair +#define PP_LineStat_Polarity 0x1000 // Line polarity OK (10BT only) +#define PP_LineStat_CRS 0x4000 // Frame being received + +#define PP_SelfStat 0x0136 // Chip status +#define PP_SelfStat_InitD 0x0080 // Chip initialization complete +#define PP_SelfStat_SIBSY 0x0100 // EEPROM is busy +#define PP_SelfStat_EEPROM 0x0200 // EEPROM present +#define PP_SelfStat_EEPROM_OK 0x0400 // EEPROM checks out +#define PP_SelfStat_ELPresent 0x0800 // External address latch logic available +#define PP_SelfStat_EEsize 0x1000 // Size of EEPROM + +#define PP_BusStat 0x0138 // Bus status +#define PP_BusStat_TxBid 0x0080 // Tx error +#define PP_BusStat_TxRDY 0x0100 // Ready for Tx data + +#define PP_LAF 0x0150 // Logical address filter (6 bytes) +#define PP_IA 0x0158 // Individual address (MAC) + +// "page pointer" access functions + +static __inline__ unsigned short +get_reg(int regno) +{ + CS8900_PPTR = regno; + return CS8900_PDATA; +} + +static __inline__ void +put_reg(int regno, unsigned short val) +{ + CS8900_PPTR = regno; + CS8900_PDATA = val; +} diff --git a/packages/devs/eth/arm/edb7xxx/current/src/if_edb7xxx.c b/packages/devs/eth/arm/edb7xxx/current/src/if_edb7xxx.c new file mode 100644 --- /dev/null +++ b/packages/devs/eth/arm/edb7xxx/current/src/if_edb7xxx.c @@ -0,0 +1,420 @@ +//========================================================================== +// +// dev/if_edb7xxx.c +// +// Ethernet device driver for Cirrus Logic EDB7xxx using CS8900 +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 2000-01-10 +// Purpose: +// Description: hardware driver for CS8900 ethernet +// +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +// Ethernet device driver for Cirrus Logic EDB7xxx +// Based on CS8900A + +#include +#include +#include +#include +#include +#include +#include + +#define INTS_DONT_WORK +#undef INTS_DONT_WORK + +#ifdef INTS_DONT_WORK +#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM +static char cs8900_fake_int_stack[STACK_SIZE]; +static cyg_thread cs8900_fake_int_thread_data; +static cyg_handle_t cs8900_fake_int_thread_handle; +static void cs8900_fake_int(cyg_addrword_t); +#endif + +#define CS8900_BASE 0x20000000 +#include "cs8900.h" +#define ETHER_ADDR_LEN 6 + +extern int net_debug; // FIXME + +struct cs8900_priv_data { + int txbusy; // A packet has been sent + unsigned long txkey; // Used to ack when packet sent +} _cs8900_priv_data; + +ETH_DRV_SC(edb7xxx_sc, + &_cs8900_priv_data, // Driver specific data + "eth0", // Name for this interface + cs8900_start, + cs8900_stop, + cs8900_control, + cs8900_can_send, + cs8900_send, + cs8900_recv); + +NETDEVTAB_ENTRY(edb7xxx_netdev, + "edb7xxx", + edb7xxx_cs8900_init, + &edb7xxx_sc); + +// FIXME +static unsigned char enaddr[] = { 0x08, 0x88, 0x12, 0x34, 0x56, 0x78}; + +static void cs8900_int(struct eth_drv_sc *sc); +static cyg_interrupt cs8900_interrupt; +static cyg_handle_t cs8900_interrupt_handle; + +// This ISR is called when the ethernet interrupt occurs +static int +cs8900_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs) +{ + cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_EINT3); + return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR +} + +// This DSR handles the ethernet [logical] processing +static void +cs8900_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + cs8900_int((struct eth_drv_sc *)data); + // Allow interrupts to happen again + cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EINT3); + cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT3); +} + +static bool +edb7xxx_cs8900_init(struct cyg_netdevtab_entry *tab) +{ + struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; + unsigned short chip_type, chip_rev, chip_status; + int i; + + diag_printf("cs8900 init\n"); + + // Initialize environment, setup interrupt handler + cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EINT3, + 99, // Priority - what goes here? + (cyg_addrword_t)sc, // Data item passed to interrupt handler + (cyg_ISR_t *)cs8900_isr, + (cyg_DSR_t *)cs8900_dsr, + &cs8900_interrupt_handle, + &cs8900_interrupt); + cyg_drv_interrupt_attach(cs8900_interrupt_handle); + cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EINT3); + cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT3); + +#ifdef INTS_DONT_WORK + cyg_thread_create(1, // Priority + cs8900_fake_int, // entry + 0, // entry parameter + "CS8900 int", // Name + &cs8900_fake_int_stack[0], // Stack + STACK_SIZE, // Size + &cs8900_fake_int_thread_handle, // Handle + &cs8900_fake_int_thread_data // Thread data structure + ); + cyg_thread_resume(cs8900_fake_int_thread_handle); // Start it +#endif + + chip_type = get_reg(PP_ChipID); + chip_rev = get_reg(PP_ChipRev); + + diag_printf("CS8900 - type: %x, rev: %x\n", chip_type, chip_rev); + + put_reg(PP_SelfCtl, PP_SelfCtl_Reset); // Reset chip + while ((get_reg(PP_SelfStat) & PP_SelfStat_InitD) == 0) ; + + chip_status = get_reg(PP_SelfStat); + diag_printf("CS8900 - status: %x (%sEEPROM present)\n", chip_status, + chip_status&PP_SelfStat_EEPROM ? "" : "no "); + + // Set up hardware address - FIXME + for (i = 0; i < ETHER_ADDR_LEN; i += 2) { + put_reg(PP_LAF+i, 0xFFFF); + put_reg(PP_IA+i, enaddr[i] | (enaddr[i+1] << 8)); + } + + // Initialize upper level driver + eth_drv_init(sc, enaddr); + + return true; +} + +static void +cs8900_stop(struct eth_drv_sc *sc) +{ + put_reg(PP_SelfCtl, PP_SelfCtl_Reset); // Reset chip + while ((get_reg(PP_SelfStat) & PP_SelfStat_InitD) == 0) ; +} + +// +// This function is called to "start up" the interface. It may be called +// multiple times, even when the hardware is already running. It will be +// called whenever something "hardware oriented" changes and should leave +// the hardware ready to send/receive packets. +// +static void +cs8900_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags) +{ + unsigned short stat; + put_reg(PP_BusCtl, PP_BusCtl_MemoryE); // Disable interrupts, memory mode + put_reg(PP_IntReg, PP_IntReg_IRQ0); // Only possibility + put_reg(PP_RxCFG, PP_RxCFG_RxOK | PP_RxCFG_CRC | + PP_RxCFG_RUNT | PP_RxCFG_EXTRA); + put_reg(PP_RxCTL, PP_RxCTL_RxOK | PP_RxCTL_Broadcast | + PP_RxCTL_IA); + put_reg(PP_TxCFG, PP_TxCFG_TxOK | PP_TxCFG_Collision | + PP_TxCFG_CRS | PP_TxCFG_SQE | PP_TxCFG_Late | + PP_TxCFG_Jabber | PP_TxCFG_16Collisions); + put_reg(PP_BufCFG, PP_BufCFG_TxRDY | PP_BufCFG_TxUE | PP_BufCFG_RxMiss | + PP_BufCFG_TxCol | PP_BufCFG_Miss | PP_BufCFG_SWI); + put_reg(PP_IntReg, PP_IntReg_IRQ0); // Only possibility + put_reg(PP_LineCTL, PP_LineCTL_Rx | PP_LineCTL_Tx); + // Clear Interrupt Status Queue before enabling interrupts + while ((stat = CS8900_ISQ) != 0) ; + put_reg(PP_BusCtl, PP_BusCtl_EnableIRQ); +} + +// +// This routine is called to perform special "control" opertions +// +static int +cs8900_control(struct eth_drv_sc *sc, unsigned long key, + void *data, int data_length) +{ + switch (key) { + case ETH_DRV_SET_MAC_ADDRESS: + return 0; + break; + default: + return 1; + break; + } +} + +// +// This routine is called to see if it is possible to send another packet. +// It will return non-zero if a transmit is possible, zero otherwise. +// +static int +cs8900_can_send(struct eth_drv_sc *sc) +{ + struct cs8900_priv_data *cpd = (struct cs8900_priv_data *)sc->driver_private; + return (cpd->txbusy == 0); +} + +// +// This routine is called to send data to the hardware. +static void +cs8900_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, + int total_len, unsigned long key) +{ + struct cs8900_priv_data *cpd = (struct cs8900_priv_data *)sc->driver_private; + int i; + int len; + unsigned char *data; + unsigned short saved_data = 0, *sdata; + unsigned short stat; + bool odd_byte = false; + + // Mark xmitter busy + cpd->txbusy = 1; + cpd->txkey = key; + // Start the xmit sequence +// Note: this can go back once the 'dump' is removed +// CS8900_TxCMD = PP_TxCmd_TxStart_5; // Start more-or-less immediately + CS8900_TxCMD = PP_TxCmd_TxStart_Full; // Start only when all data sent to chip + CS8900_TxLEN = total_len; + stat = get_reg(PP_BusStat); // This actually starts the xmit + + // Put data into buffer + for (i = 0; i < sg_len; i++) { + data = (unsigned char *)sg_list[i].buf; + len = sg_list[i].len; + if (len > 0) { + /* Finish the last word. */ + if (odd_byte) { + saved_data |= (*data++ << 8); + CS8900_RTDATA = saved_data; + len--; + odd_byte = false; + } + /* Output contiguous words. */ + sdata = (unsigned short *)data; + while (len > 1) { + CS8900_RTDATA = *sdata++; + len -= sizeof(unsigned short); + } + /* Save last byte, if necessary. */ + if (len == 1) { + data = (unsigned char *)sdata; + saved_data = *data; + odd_byte = true; + } + } + } + if (odd_byte) { + CS8900_RTDATA = saved_data; + } +} + +// +// This function is called when a packet has been received. It's job is +// to prepare to unload the packet from the hardware. Once the length of +// the packet is known, the upper layer of the driver can be told. When +// the upper layer is ready to unload the packet, the internal function +// 'cs8900_recv' will be called to actually fetch it from the hardware. +// +static void +cs8900_RxEvent(struct eth_drv_sc *sc) +{ + unsigned short stat, len; + + stat = CS8900_RTDATA; + len = CS8900_RTDATA; + if (net_debug) { + diag_printf("RxEvent - stat: %x, len: %d\n", stat, len); + } + eth_drv_recv(sc, len); +} + +// +// This function is called as a result of the "eth_drv_recv()" call above. +// It's job is to actually fetch data for a packet from the hardware once +// memory buffers have been allocated for the packet. Note that the buffers +// may come in pieces, using a scatter-gather list. This allows for more +// efficient processing in the upper layers of the stack. +// +static void +cs8900_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) +{ + int i, mlen; + unsigned short *data, val; + unsigned char *cp, cval; + + for (i = 0; i < sg_len; i++) { + data = (unsigned short *)sg_list[i].buf; + mlen = sg_list[i].len; + while (mlen >= sizeof(*data)) { + val = CS8900_RTDATA; + if (data) { + *data++ = val; + } + mlen -= sizeof(*data); + } + if (mlen) { + // Fetch last odd byte + cval = CS8900_RTDATA & 0xFF; + if (cp = (unsigned char *)data) { + *cp = cval; + } + } + } +} + +static void +cs8900_TxEvent(struct eth_drv_sc *sc, int stat) +{ + struct cs8900_priv_data *cpd = (struct cs8900_priv_data *)sc->driver_private; + stat = get_reg(PP_TER); + if (net_debug) { + diag_printf("Tx event: %x\n", stat); + } + cpd->txbusy = 0; + eth_drv_tx_done(sc, cpd->txkey, 0); +} + +static void +cs8900_BufEvent(struct eth_drv_sc *sc, int stat) +{ + if (stat & PP_BufCFG_RxMiss) { + } + if (stat & PP_BufCFG_TxUE) { + } +} + +static void +cs8900_int(struct eth_drv_sc *sc) +{ + unsigned short event; + while ((event = CS8900_ISQ) != 0) { + switch (event & ISQ_EventMask) { + case ISQ_RxEvent: + cs8900_RxEvent(sc); + break; + case ISQ_TxEvent: + cs8900_TxEvent(sc, event); + break; + case ISQ_BufEvent: + cs8900_BufEvent(sc, event); + break; + case ISQ_RxMissEvent: + // Receive miss counter has overflowed + break; + case ISQ_TxColEvent: + // Transmit collision counter has overflowed + break; + default: + diag_printf("%s: Unknown event: %x\n", __FUNCTION__, event); + break; + } + } +} + +#ifdef INTS_DONT_WORK +void +cs8900_fake_int(cyg_addrword_t param) +{ + int s; + while (true) { + cyg_thread_delay(5); + s = splnet(); + cs8900_int(&edb7xxx_sc); + splx(s); + } +} +#endif + diff --git a/packages/devs/eth/powerpc/quicc/current/ChangeLog b/packages/devs/eth/powerpc/quicc/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/eth/powerpc/quicc/current/ChangeLog @@ -0,0 +1,115 @@ +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-03-28 Gary Thomas + + * src/if_quicc.c (quicc_eth_recv): Handle case where there were + no buffers (and thus the sg_list[] contains NULL pointers). + +2000-03-06 Gary Thomas + + * src/if_quicc.c: New driver API. + +2000-03-05 Gary Thomas + + * src/if_quicc.c: Cleanup to remove compiler warnings. + +2000-03-03 Gary Thomas + + * src/quicc_eth.h: Move standard CPM defines to common (ppc8xx.h). + + * src/if_quicc.c: Fetch ethernet hardware address (MAC) from the + board EEPROM. Also remove a bunch of diagnostic prints which aren't + needed any longer, now that the device is properly running. + +2000-03-01 Gary Thomas + + * src/quicc_eth.h (MBX_CTL1): + * src/if_quicc.c (quicc_eth_init): Add intialization of board control + register which lets driver work when booted from eCos/GDB. + +2000-03-01 Gary Thomas + + * src/if_quicc.c: Lots of fixes. Now works, but only if application + is booted via PPCbug (some initialization is still missing). + +2000-02-29 Gary Thomas + + * src/quicc_eth.h: + * src/if_quicc.c: Some improvements. Almost works when booted via + PPCbug, but not from eCos/GDB. + +2000-02-21 Gary Thomas + + * cdl/quicc_eth_drivers.cdl: + * src/quicc_eth.h + * src/if_quicc.c: New file(s). + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== + + + diff --git a/packages/devs/eth/powerpc/quicc/current/cdl/quicc_eth_drivers.cdl b/packages/devs/eth/powerpc/quicc/current/cdl/quicc_eth_drivers.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/eth/powerpc/quicc/current/cdl/quicc_eth_drivers.cdl @@ -0,0 +1,104 @@ +# ==================================================================== +# +# quicc_eth_drivers.cdl +# +# Ethernet drivers - platform dependent support for PowerPC MPC8xx +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): gthomas +# Original data: gthomas +# Contributors: +# Date: 2000-01-25 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + +cdl_package CYGPKG_DEVS_ETH_POWERPC_QUICC { + display "MPC8xx QUICC ethernet driver" + + parent CYGPKG_NET_ETH_DRIVERS + active_if CYGPKG_NET_ETH_DRIVERS + active_if CYGPKG_HAL_POWERPC + active_if CYGPKG_HAL_POWERPC_MPC8xx + + implements CYGHWR_NET_DRIVERS + implements CYGHWR_NET_DRIVER_ETH0 + include_dir . +# include_files ; # none _exported_ whatsoever + + description "Ethernet driver for PowerPC MPC8xx boards." + compile -library=libextras.a if_quicc.c + + cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE { + display "Buffer size" + flavor data + default_value 1520 + description " + This option specifies the size of the internal buffers used + for the PowerPC QUICC/ethernet device." + } + + cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM { + display "Number of output buffers" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of output buffer packets + to be used for the PowerPC QUICC/ethernet device." + } + + cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM { + display "Number of input buffers" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of input buffer packets + to be used for the PowerPC QUICC/ethernet device." + } + + cdl_component CYGPKG_DEVS_ETH_POWERPC_QUICC_OPTIONS { + display "MPC8xx QUICC ethernet driver build options" + flavor none + no_define + + cdl_option CYGPKG_DEVS_ETH_POWERPC_QUICC_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "-D_KERNEL -D__ECOS" } + description " + This option modifies the set of compiler flags for + building the MPC8xx QUICC ethernet driver package. These flags are used in addition + to the set of global flags." + } + } +} diff --git a/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c b/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c new file mode 100644 --- /dev/null +++ b/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c @@ -0,0 +1,516 @@ +//========================================================================== +// +// dev/if_quicc.c +// +// Ethernet device driver for PowerPC QUICC (MPC8xx) boards +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 2000-01-10 +// Purpose: +// Description: hardware driver for MPC8xx QUICC +// +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +// Ethernet device driver for MPC8xx QUICC + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "quicc_eth.h" + +static unsigned char quicc_eth_rxbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM] + [CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE]; +static unsigned char quicc_eth_txbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM] + [CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE]; + +static struct quicc_eth_info quicc_eth0_info; +static unsigned char enaddr[] = { 0x08, 0x00, 0x3E, 0x28, 0x79, 0xB8}; + +ETH_DRV_SC(quicc_eth0_sc, + &quicc_eth0_info, // Driver specific data + "eth0", // Name for this interface + quicc_eth_start, + quicc_eth_stop, + quicc_eth_control, + quicc_eth_can_send, + quicc_eth_send, + quicc_eth_recv); + +NETDEVTAB_ENTRY(quicc_netdev, + "quicc_eth", + quicc_eth_init, + &quicc_eth0_sc); + +static cyg_interrupt quicc_eth_interrupt; +static cyg_handle_t quicc_eth_interrupt_handle; +static void quicc_eth_int(struct eth_drv_sc *data); + +extern int _mbx_fetch_VPD(int, void *, int); + +// This ISR is called when the ethernet interrupt occurs +static int +quicc_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs) +{ + cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_CPM_SCC1); + return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR +} + +// This DSR handles the ethernet [logical] processing +static void +quicc_eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + quicc_eth_int((struct eth_drv_sc *)data); + // Allow interrupts to happen again + cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_CPM_SCC1); + cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_CPM_SCC1); +} + +// +// Initialize the interface - performed at system startup +// This function must set up the interface, including arranging to +// handle interrupts, etc, so that it may be "started" cheaply later. +// +static bool +quicc_eth_init(struct cyg_netdevtab_entry *tab) +{ + struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + volatile EPPC *eppc = (volatile EPPC *)eppc_base(); + struct cp_bufdesc *rxbd, *txbd; + unsigned char *RxBUF, *TxBUF, *ep, *ap; + volatile struct ethernet_pram *enet_pram; + volatile struct scc_regs *scc; + int TxBD, RxBD; + int cache_state; + int i; + + // Fetch the board address from the VPD +#define VPD_ETHERNET_ADDRESS 0x08 + _mbx_fetch_VPD(VPD_ETHERNET_ADDRESS, enaddr, sizeof(enaddr)); + + // Ensure consistent state between cache and what the QUICC sees + HAL_DCACHE_IS_ENABLED(cache_state); + HAL_DCACHE_SYNC(); + HAL_DCACHE_DISABLE(); + + // Set up to handle interrupts + cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_CPM_SCC1, + CYGARC_SIU_PRIORITY_HIGH, + (cyg_addrword_t)sc, // Data item passed to interrupt handler + (cyg_ISR_t *)quicc_eth_isr, + (cyg_DSR_t *)quicc_eth_dsr, + &quicc_eth_interrupt_handle, + &quicc_eth_interrupt); + cyg_drv_interrupt_attach(quicc_eth_interrupt_handle); + cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_CPM_SCC1); + cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_CPM_SCC1); + + qi->pram = enet_pram = &eppc->pram[0].enet_scc; + qi->ctl = scc = &eppc->scc_regs[0]; // Use SCC1 + + // Shut down ethernet, in case it is already running + scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT); + + bzero((void *)enet_pram, sizeof(*enet_pram)); + + TxBD = 0x2C00; // FIXME + RxBD = TxBD + CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM * sizeof(struct cp_bufdesc); + + txbd = (struct cp_bufdesc *)((char *)eppc + TxBD); + rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD); + qi->tbase = txbd; + qi->txbd = txbd; + qi->tnext = txbd; + qi->rbase = rxbd; + qi->rxbd = rxbd; + qi->rnext = rxbd; + + RxBUF = &quicc_eth_rxbufs[0][0]; + TxBUF = &quicc_eth_txbufs[0][0]; + + // setup buffer descriptors + for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM; i++) { + rxbd->length = 0; + rxbd->buffer = RxBUF; + rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int; + RxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; + rxbd++; + } + rxbd--; + rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer + for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM; i++) { + txbd->length = 0; + txbd->buffer = TxBUF; + txbd->ctrl = 0; + TxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; + txbd++; + } + txbd--; + txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer + + // Set up parallel ports for connection to MC68160 ethernet tranceiver + eppc->pio_papar |= (QUICC_MBX_PA_RXD | QUICC_MBX_PA_TXD); + eppc->pio_padir &= ~(QUICC_MBX_PA_RXD | QUICC_MBX_PA_TXD); + eppc->pio_paodr &= ~QUICC_MBX_PA_TXD; + + eppc->pio_pcpar &= ~(QUICC_MBX_PC_COLLISION | QUICC_MBX_PC_Rx_ENABLE); + eppc->pio_pcdir &= ~(QUICC_MBX_PC_COLLISION | QUICC_MBX_PC_Rx_ENABLE); + eppc->pio_pcso |= (QUICC_MBX_PC_COLLISION | QUICC_MBX_PC_Rx_ENABLE); + + eppc->pio_papar |= (QUICC_MBX_PA_Tx_CLOCK | QUICC_MBX_PA_Rx_CLOCK); + eppc->pio_padir &= ~(QUICC_MBX_PA_Tx_CLOCK | QUICC_MBX_PA_Rx_CLOCK); + + // Set up clock routing + eppc->si_sicr &= ~QUICC_MBX_SICR_MASK; + eppc->si_sicr |= QUICC_MBX_SICR_ENET; + eppc->si_sicr &= ~QUICC_MBX_SICR_SCC1_ENABLE; + + // Set up DMA mode + eppc->dma_sdcr = 0x0001; + + // Initialize shared PRAM + enet_pram->rbase = RxBD; + enet_pram->tbase = TxBD; + + // Set Big Endian mode + enet_pram->rfcr = QUICC_SCC_FCR_BE; + enet_pram->tfcr = QUICC_SCC_FCR_BE; + + // Size of receive buffers + enet_pram->mrblr = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; + + // Initialize CRC calculations + enet_pram->c_pres = 0xFFFFFFFF; + enet_pram->c_mask = 0xDEBB20E3; // Actual CRC formula + enet_pram->crcec = 0; + enet_pram->alec = 0; + enet_pram->disfc = 0; + + // Frame padding + enet_pram->pads = 0x8888; + enet_pram->pads = 0x0000; + + // Retries + enet_pram->ret_lim = 15; + enet_pram->ret_cnt = 0; + + // Frame sizes + enet_pram->mflr = IEEE_8023_MAX_FRAME; + enet_pram->minflr = IEEE_8023_MIN_FRAME; + enet_pram->maxd1 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; + enet_pram->maxd2 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; + + // Group address hash + enet_pram->gaddr1 = 0; + enet_pram->gaddr2 = 0; + enet_pram->gaddr3 = 0; + enet_pram->gaddr4 = 0; + + // Device physical address + ep = &enaddr[sizeof(enaddr)]; + ap = (unsigned char *)&enet_pram->paddr_h; + for (i = 0; i < sizeof(enaddr); i++) { + *ap++ = *--ep; + } + + // Persistence counter + enet_pram->p_per = 0; + + // Individual address filter + enet_pram->iaddr1 = 0; + enet_pram->iaddr2 = 0; + enet_pram->iaddr3 = 0; + enet_pram->iaddr4 = 0; + + // Temp address + enet_pram->taddr_h = 0; + enet_pram->taddr_m = 0; + enet_pram->taddr_l = 0; + + // Initialize the CPM (set up buffer pointers, etc). + eppc->cp_cr = QUICC_CPM_SCC1 | QUICC_CPM_CR_INIT_TXRX | QUICC_CPM_CR_BUSY; + while (eppc->cp_cr & QUICC_CPM_CR_BUSY) ; + + // Clear any pending interrupt/exceptions + scc->scc_scce = 0xFFFF; + + // Enable interrupts + scc->scc_sccm = QUICC_SCCE_INTS; + + // Set up SCC1 to run in ethernet mode + scc->scc_gsmr_h = 0; + scc->scc_gsmr_l = QUICC_SCC_GSML_TCI | QUICC_SCC_GSML_TPL_48 | + QUICC_SCC_GSML_TPP_01 | QUICC_SCC_GSML_MODE_ENET; + + // Sync delimiters + scc->scc_dsr = 0xD555; + + // Protocol specifics (as if GSML wasn't enough) + scc->scc_psmr = QUICC_PMSR_ENET_CRC | QUICC_PMSR_SEARCH_AFTER_22 | + QUICC_PMSR_RCV_SHORT_FRAMES; + + // Configure board interface + *MBX_CTL1 = MBX_CTL1_ETEN | MBX_CTL1_TPEN; // Enable ethernet, TP mode + + // Enable ethernet interface + eppc->pio_pcpar |= QUICC_MBX_PC_Tx_ENABLE; + eppc->pio_pcdir &= ~QUICC_MBX_PC_Tx_ENABLE; + + if (cache_state) + HAL_DCACHE_ENABLE(); + + // Initialize upper level driver + eth_drv_init(sc, (unsigned char *)&enaddr); + + return true; +} + +// +// This function is called to shut down the interface. +// +static void +quicc_eth_stop(struct eth_drv_sc *sc) +{ + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + volatile struct scc_regs *scc = qi->ctl; + // Disable the device! + scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT); +} + +// +// This function is called to "start up" the interface. It may be called +// multiple times, even when the hardware is already running. It will be +// called whenever something "hardware oriented" changes and should leave +// the hardware ready to send/receive packets. +// +static void +quicc_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags) +{ + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + volatile struct scc_regs *scc = qi->ctl; + // Enable the device! + scc->scc_gsmr_l |= QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT; +} + +// +// This function is called for low level "control" operations +// +static int +quicc_eth_control(struct eth_drv_sc *sc, unsigned long key, + void *data, int length) +{ + switch (key) { + case ETH_DRV_SET_MAC_ADDRESS: + return 0; + break; + default: + return 1; + break; + } +} + +// +// This function is called to see if another packet can be sent. +// It should return the number of packets which can be handled. +// Zero should be returned if the interface is busy and can not send any more. +// +static int +quicc_eth_can_send(struct eth_drv_sc *sc) +{ + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + volatile struct cp_bufdesc *txbd = qi->txbd; + return ((txbd->ctrl & QUICC_BD_CTL_Ready) == 0); +} + +// +// This routine is called to send data to the hardware. +static void +quicc_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, + int total_len, unsigned long key) +{ + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + volatile struct cp_bufdesc *txbd, *txfirst; + volatile char *bp; + int i, txindex, cache_state; + // Find a free buffer + txbd = txfirst = qi->txbd; + while (txbd->ctrl & QUICC_BD_CTL_Ready) { + // This buffer is busy, move to next one + if (txbd->ctrl & QUICC_BD_CTL_Wrap) { + txbd = qi->tbase; + } else { + txbd++; + } + if (txbd == txfirst) { + panic ("No free xmit buffers"); + } + } + // Remember the next buffer to try + if (txbd->ctrl & QUICC_BD_CTL_Wrap) { + qi->txbd = qi->tbase; + } else { + qi->txbd = txbd+1; + } + txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd); + qi->txkey[txindex] = key; + // Set up buffer + txbd->length = total_len; + bp = txbd->buffer; + for (i = 0; i < sg_len; i++) { + bcopy((void *)sg_list[i].buf, (void *)bp, sg_list[i].len); + bp += sg_list[i].len; + } + // Note: the MBX860 does not seem to snoop/invalidate the data cache properly! + HAL_DCACHE_IS_ENABLED(cache_state); + if (cache_state) { + HAL_DCACHE_INVALIDATE(txbd->buffer, txbd->length); // Make sure no stale data + } + // Send it on it's way + txbd->ctrl |= QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int | + QUICC_BD_TX_PAD | QUICC_BD_TX_LAST | QUICC_BD_TX_TC; +} + +// +// This function is called when a packet has been received. It's job is +// to prepare to unload the packet from the hardware. Once the length of +// the packet is known, the upper layer of the driver can be told. When +// the upper layer is ready to unload the packet, the internal function +// 'quicc_eth_recv' will be called to actually fetch it from the hardware. +// +static void +quicc_eth_RxEvent(struct eth_drv_sc *sc) +{ + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + volatile struct cp_bufdesc *rxbd; + rxbd = qi->rnext; + while ((rxbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) { + qi->rxbd = rxbd; // Save for callback + eth_drv_recv(sc, rxbd->length); + rxbd->ctrl |= QUICC_BD_CTL_Ready; + if (rxbd->ctrl & QUICC_BD_CTL_Wrap) { + rxbd = qi->rbase; + } else { + rxbd++; + } + } + // Remember where we left off + qi->rnext = (struct cp_bufdesc *)rxbd; +} + +// +// This function is called as a result of the "eth_drv_recv()" call above. +// It's job is to actually fetch data for a packet from the hardware once +// memory buffers have been allocated for the packet. Note that the buffers +// may come in pieces, using a scatter-gather list. This allows for more +// efficient processing in the upper layers of the stack. +// +static void +quicc_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) +{ + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + unsigned char *bp; + int i, cache_state; + bp = (unsigned char *)qi->rxbd->buffer; + // Note: the MBX860 does not seem to snoop/invalidate the data cache properly! + HAL_DCACHE_IS_ENABLED(cache_state); + if (cache_state) { + HAL_DCACHE_INVALIDATE(qi->rxbd->buffer, qi->rxbd->length); // Make sure no stale data + } + for (i = 0; i < sg_len; i++) { + if (sg_list[i].buf != 0) { + bcopy(bp, (void *)sg_list[i].buf, sg_list[i].len); + bp += sg_list[i].len; + } + } +} + +static void +quicc_eth_TxEvent(struct eth_drv_sc *sc, int stat) +{ + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + volatile struct cp_bufdesc *txbd; + int txindex; + txbd = qi->tnext; + while ((txbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) { + txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd); + txbd->ctrl &= ~QUICC_BD_CTL_Int; // Reset int pending bit + eth_drv_tx_done(sc, qi->txkey[txindex], 0); + if (txbd->ctrl & QUICC_BD_CTL_Wrap) { + txbd = qi->tbase; + } else { + txbd++; + } + } + // Remember where we left off + qi->tnext = (struct cp_bufdesc *)txbd; +} + +// +// Interrupt processing +// +static void +quicc_eth_int(struct eth_drv_sc *sc) +{ + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + volatile struct scc_regs *scc = qi->ctl; + unsigned short scce; + while ((scce = (scc->scc_scce & QUICC_SCCE_INTS)) != 0) { + if ((scce & (QUICC_SCCE_TXE | QUICC_SCCE_TX)) != 0) { + quicc_eth_TxEvent(sc, scce); + } + if ((scce & QUICC_SCCE_RXF) != 0) { + quicc_eth_RxEvent(sc); + } + scc->scc_scce = scce; // Reset the bits we handled + } +} diff --git a/packages/devs/eth/powerpc/quicc/current/src/quicc_eth.h b/packages/devs/eth/powerpc/quicc/current/src/quicc_eth.h new file mode 100644 --- /dev/null +++ b/packages/devs/eth/powerpc/quicc/current/src/quicc_eth.h @@ -0,0 +1,170 @@ +//========================================================================== +// +// quicc_eth.h +// +// PowerPC QUICC (MPC8xx) ethernet +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 2000-01-10 +// Purpose: +// Description: +// +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +// PowerPC QUICC (MPC8xx) Ethernet + +#include // QUICC structure definitions + +struct quicc_eth_info { + volatile struct ethernet_pram *pram; // Parameter RAM pointer + volatile struct scc_regs *ctl; // SCC control registers + volatile struct cp_bufdesc *txbd, *rxbd; // Next Tx,Rx descriptor to use + struct cp_bufdesc *tbase, *rbase; // First Tx,Rx descriptor + struct cp_bufdesc *tnext, *rnext; // Next descriptor to check for interrupt + int txsize, rxsize; // Length of individual buffers + unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM]; +}; + +// SCC registers - ethernet mode + +// General SCC mode register +#define QUICC_SCC_GSMH_IRP 0x00040000 // Infared polarity +#define QUICC_SCC_GSMH_GDE 0x00010000 // Glitch detect enable +#define QUICC_SCC_GSMH_TCRC 0x00008000 // Transparent CRC +#define QUICC_SCC_GSMH_REVD 0x00004000 // Reverse data (transparent) +#define QUICC_SCC_GSMH_TRX 0x00002000 // Transparent Rx +#define QUICC_SCC_GSMH_TTX 0x00001000 // Transparent Tx + +#define QUICC_SCC_GSML_TCI 0x10000000 // Transmit clock invert +#define QUICC_SCC_GSML_TPL 0x00E00000 // Tx preamble bits +#define QUICC_SCC_GSML_TPL_8 0x00200000 // 8 bits +#define QUICC_SCC_GSML_TPL_16 0x00400000 // 16 bits +#define QUICC_SCC_GSML_TPL_32 0x00600000 // 32 bits +#define QUICC_SCC_GSML_TPL_48 0x00800000 // 48 bits (used for ethernet) +#define QUICC_SCC_GSML_TPL_64 0x00A00000 // 64 bits +#define QUICC_SCC_GSML_TPL_128 0x00C00000 // 128 bits +#define QUICC_SCC_GSML_TPP 0x00180000 // Tx preamble pattern +#define QUICC_SCC_GSML_TPP_00 0x00000000 // all zeroes +#define QUICC_SCC_GSML_TPP_01 0x00080000 // 10 repeats (ethernet) +#define QUICC_SCC_GSML_TPP_10 0x00100000 // 01 repeats +#define QUICC_SCC_GSML_TPP_11 0x00180000 // all ones (localtalk) +#define QUICC_SCC_GSML_ENR 0x00000020 // Enable receiver +#define QUICC_SCC_GSML_ENT 0x00000010 // Enable transmitter +#define QUICC_SCC_GSML_MODE 0x0000000F // Operating mode +#define QUICC_SCC_GSML_MODE_HDLC 0x00000000 +#define QUICC_SCC_GSML_MODE_ATALK 0x00000002 +#define QUICC_SCC_GSML_MODE_ENET 0x0000000C + +// Function code +#define QUICC_SCC_FCR_BE 0x0010 // Big Endian operation + +// Event register +#define QUICC_SCCE_GRC 0x0080 // Gracefull stop complete +#define QUICC_SCCE_TXE 0x0010 // Transmit error +#define QUICC_SCCE_RXF 0x0008 // Received full frame +#define QUICC_SCCE_BSY 0x0004 // No free receive buffers +#define QUICC_SCCE_TX 0x0002 // Buffer transmit complete +#define QUICC_SCCE_RX 0x0001 // Buffer received +#define QUICC_SCCE_INTS (QUICC_SCCE_TXE | QUICC_SCCE_RXF | QUICC_SCCE_TX) + +// Protocol specific mode register +#define QUICC_PMSR_HEARTBEAT 0x8000 // Enable heartbeat +#define QUICC_PMSR_FORCE_COLLISION 0x4000 // Force a collision +#define QUICC_PMSR_RCV_SHORT_FRAMES 0x2000 // Accept short frames +#define QUICC_PMSR_INDIV_ADDR_MODE 0x1000 // Check individual address (hash) +#define QUICC_PMSR_ENET_CRC 0x0800 // Enable ethernet CRC mode +#define QUICC_PMSR_PROMISCUOUS 0x0200 // Enable promiscuous mode +#define QUICC_PMSR_BROADCAST 0x0100 // Accept broadcast packets +#define QUICC_PMSR_SPECIAL_BACKOFF 0x0080 // Enable special backoff timer +#define QUICC_PMSR_LOOPBACK 0x0040 // Enable loopback mode +#define QUICC_PMSR_SAMPLE_INPUTS 0x0020 // Discretely look at input pins +#define QUICC_PMSR_LATE_COLLISION 0x0010 // Enable late collision window +#define QUICC_PMSR_SEARCH_AFTER_22 0x000A // Start frame search after 22 bits +#define QUICC_PMSR_FULL_DUPLEX 0x0001 // Full duplex mode + +// Receive buffer status +#define QUICC_BD_RX_LAST 0x0800 // Last buffer in chain +#define QUICC_BD_RX_FIRST 0x0400 // First buffer in chain +#define QUICC_BD_RX_MISS 0x0100 // Missed data +#define QUICC_BD_RX_LG 0x0020 // Rx frame too long +#define QUICC_BD_RX_NO 0x0010 // Rx frame not properly aligned +#define QUICC_BD_RX_SH 0x0008 // Rx frame too short +#define QUICC_BD_RX_CR 0x0004 // Bad CRC +#define QUICC_BD_RX_OV 0x0002 // Rx overrun +#define QUICC_BD_RX_CL 0x0001 // Collision during frame + +// Transmit buffer status +#define QUICC_BD_TX_PAD 0x4000 // Pad short packets +#define QUICC_BD_TX_LAST 0x0800 // Last buffer in chain +#define QUICC_BD_TX_TC 0x0400 // Transmit CRC after buffer +#define QUICC_BD_TX_DEF 0x0200 // Transmission was deferred +#define QUICC_BD_TX_HB 0x0100 // Heartbeat detected +#define QUICC_BD_TX_LC 0x0080 // Late collision +#define QUICC_BD_TX_RL 0x0040 // Retransmit limit exceeded +#define QUICC_BD_TX_RC 0x003C // Retry count +#define QUICC_BD_TX_UN 0x0002 // Tx underrun +#define QUICC_BD_TX_CSL 0x0001 // Carrier lost + +// MBX specific "wiring" - aux connections to MX68160 Ethernet support chip +#define QUICC_MBX_PA_RXD 0x0001 // Rx Data on Port A +#define QUICC_MBX_PA_TXD 0x0002 // Tx Data on Port A +#define QUICC_MBX_PA_Tx_CLOCK 0x0200 // Tx Clock = CLK2 +#define QUICC_MBX_PA_Rx_CLOCK 0x0800 // Rx Clock = CLK4 +#define QUICC_MBX_PC_Tx_ENABLE 0x0001 // Tx Enable (TENA) +#define QUICC_MBX_PC_COLLISION 0x0010 // Collision detect +#define QUICC_MBX_PC_Rx_ENABLE 0x0020 // Rx Enable (RENA) +#define QUICC_MBX_SICR_MASK 0x00FF // SI Clock Route - important bits +#define QUICC_MBX_SICR_ENET (7<<3)|(5<<0) // Rx=CLK4, Tx=CLK2 +#define QUICC_MBX_SICR_SCC1_ENABLE 0x0040 // Enable SCC1 to use NMSI + +#define MBX_CTL1 (cyg_uint8 *)0xFA100000 // System control register +#define MBX_CTL1_ETEN 0x80 // 1 = Enable ethernet tranceiver +#define MBX_CTL1_ELEN 0x40 // 1 = Enable ethernet loopback +#define MBX_CTL1_EAEN 0x20 // 1 = Auto select ethernet interface +#define MBX_CTL1_TPEN 0x10 // 0 = AUI, 1 = TPI +#define MBX_CTL1_FDDIS 0x08 // 1 = Disable full duplex (if TP mode) + +#define IEEE_8023_MAX_FRAME 1518 // Largest possible ethernet frame +#define IEEE_8023_MIN_FRAME 64 // Smallest possible ethernet frame + diff --git a/packages/devs/serial/arm/aeb/current/ChangeLog b/packages/devs/serial/arm/aeb/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/aeb/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_arm_aeb.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/arm/aeb/current/cdl/ser_arm_aeb.cdl b/packages/devs/serial/arm/aeb/current/cdl/ser_arm_aeb.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/aeb/current/cdl/ser_arm_aeb.cdl @@ -0,0 +1,180 @@ +# ==================================================================== +# +# ser_arm_aeb.cdl +# +# eCos serial ARM/AEB configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-08 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_ARM_AEB { + display "ARM AEB-1 serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_ARM_AEB + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + ARM AEB-1." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a aeb_serial.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_ARM_AEB_SERIAL0 { + display "ARM AEB-1 serial port 0 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the ARM AEB-1 + port 0." + + cdl_option CYGDAT_IO_SERIAL_ARM_AEB_SERIAL0_NAME { + display "Device name for the ARM AEB-1 serial port 0 driver" + flavor data + default_value {"\"/dev/ser0\""} + description " + This option sets the name of the serial device for the ARM + AEB-1 port 0." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BAUD { + display "Baud rate for the ARM AEB-1 serial port 0 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + ARM AEB-1 port 0." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE { + display "Buffer size for the ARM AEB-1 serial port 0 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used for + the ARM AEB-1 port 0." + } +} + +cdl_component CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1 { + display "ARM AEB-1 serial port 1 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the ARM + AEB-1 port 1." + + cdl_option CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME { + display "Device name for the ARM AEB-1 serial port 1 driver" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the name of serial device for the + ARM AEB-1 port 1." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BAUD { + display "Baud rate for the ARM AEB-1 serial port 1 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + ARM AEB-1 port 1." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE { + display "Buffer size for the ARM AEB-1 serial port 1 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the ARM AEB-1 port 1." + } +} + + cdl_component CYGPKG_IO_SERIAL_ARM_AEB_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_ARM_AEB_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_ARM_AEB_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_arm_aeb.cdl diff --git a/packages/devs/serial/arm/aeb/current/src/aeb_serial.c b/packages/devs/serial/arm/aeb/current/src/aeb_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/aeb/current/src/aeb_serial.c @@ -0,0 +1,318 @@ +//========================================================================== +// +// io/serial/arm/aeb_serial.c +// +// ARM AEB-1 Serial I/O Interface Module (interrupt driven) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-04 +// Purpose: AEB-1 Serial I/O module (interrupt driven version) +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_ARM_AEB + +#include "aeb_serial.h" + +typedef struct aeb_serial_info { + CYG_ADDRWORD base; + CYG_WORD int_num; + cyg_interrupt serial_interrupt; + cyg_handle_t serial_interrupt_handle; +} aeb_serial_info; + +static bool aeb_serial_init(struct cyg_devtab_entry *tab); +static bool aeb_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo aeb_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char aeb_serial_getc(serial_channel *chan); +static bool aeb_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void aeb_serial_start_xmit(serial_channel *chan); +static void aeb_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 aeb_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void aeb_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(aeb_serial_funs, + aeb_serial_putc, + aeb_serial_getc, + aeb_serial_set_config, + aeb_serial_start_xmit, + aeb_serial_stop_xmit + ); + +#ifdef CYGPKG_IO_SERIAL_ARM_AEB_SERIAL0 +static aeb_serial_info aeb_serial_info0 = {0xFFFF0000, + CYGNUM_HAL_INTERRUPT_UART0}; +#if CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE > 0 +static unsigned char aeb_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE]; +static unsigned char aeb_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(aeb_serial_channel0, + aeb_serial_funs, + aeb_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &aeb_serial_out_buf0[0], sizeof(aeb_serial_out_buf0), + &aeb_serial_in_buf0[0], sizeof(aeb_serial_in_buf0) + ); +#else +static SERIAL_CHANNEL(aeb_serial_channel0, + aeb_serial_funs, + aeb_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(aeb_serial_io0, + CYGDAT_IO_SERIAL_ARM_AEB_SERIAL0_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + aeb_serial_init, + aeb_serial_lookup, // Serial driver may need initializing + &aeb_serial_channel0 + ); +#endif // CYGPKG_IO_SERIAL_ARM_AEB_SERIAL0 + +#ifdef CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1 +static aeb_serial_info aeb_serial_info1 = {0xFFFF0400, + CYGNUM_HAL_INTERRUPT_UART1}; +#if CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE > 0 +static unsigned char aeb_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE]; +static unsigned char aeb_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(aeb_serial_channel1, + aeb_serial_funs, + aeb_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &aeb_serial_out_buf1[0], sizeof(aeb_serial_out_buf1), + &aeb_serial_in_buf1[0], sizeof(aeb_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(aeb_serial_channel1, + aeb_serial_funs, + aeb_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(aeb_serial_io1, + CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + aeb_serial_init, + aeb_serial_lookup, // Serial driver may need initializing + &aeb_serial_channel1 + ); +#endif // CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1 + +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool +aeb_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; + unsigned short baud_divisor = select_baud[new_config->baud]; + unsigned char _lcr, _ier; + if (baud_divisor == 0) return false; + _ier = port->REG_IER; + port->REG_IER = 0; // Disable port interrupts while changing hardware + _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | + select_stop_bits[new_config->stop] | + select_parity[new_config->parity]; + port->REG_LCR = _lcr; + port->REG_LCR |= LCR_DL; + port->REG_MDL = baud_divisor >> 8; + port->REG_LDL = baud_divisor & 0xFF; + port->REG_LCR &= ~LCR_DL; + if (init) { + port->REG_FCR = 0x07; // Enable and clear FIFO + if (chan->out_cbuf.len != 0) { + port->REG_IER = IER_RCV; + } else { + port->REG_IER = 0; + } + port->REG_MCR = MCR_INT|MCR_DTR|MCR_RTS; // Master interrupt enable + } else { + port->REG_IER = _ier; + } + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +aeb_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; +#ifdef CYGDBG_IO_INIT + diag_printf("AEB SERIAL init - dev: %x.%d\n", aeb_chan->base, aeb_chan->int_num); +#endif + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (chan->out_cbuf.len != 0) { + cyg_drv_interrupt_create(aeb_chan->int_num, + 99, // Priority - unused + (cyg_addrword_t)chan, // Data item passed to interrupt handler + aeb_serial_ISR, + aeb_serial_DSR, + &aeb_chan->serial_interrupt_handle, + &aeb_chan->serial_interrupt); + cyg_drv_interrupt_attach(aeb_chan->serial_interrupt_handle); + cyg_drv_interrupt_unmask(aeb_chan->int_num); + } + aeb_serial_config_port(chan, &chan->config, true); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +aeb_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +aeb_serial_putc(serial_channel *chan, unsigned char c) +{ + aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; + if (port->REG_LSR & LSR_THE) { +// Transmit buffer is empty + port->REG_THR = c; + return true; + } else { +// No space + return false; + } +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +aeb_serial_getc(serial_channel *chan) +{ + unsigned char c; + aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; + while ((port->REG_LSR & LSR_RSR) == 0) ; // Wait for char + c = port->REG_RHR; + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +aeb_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return aeb_serial_config_port(chan, config, false); +} + +// Enable the transmitter on the device +static void +aeb_serial_start_xmit(serial_channel *chan) +{ + aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; + port->REG_IER |= IER_XMT; // Enable xmit interrupt +} + +// Disable the transmitter on the device +static void +aeb_serial_stop_xmit(serial_channel *chan) +{ + aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; + port->REG_IER &= ~IER_XMT; // Disable xmit interrupt +} + +// Serial I/O - low level interrupt handler (ISR) +static cyg_uint32 +aeb_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(aeb_chan->int_num); + cyg_drv_interrupt_acknowledge(aeb_chan->int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level interrupt handler (DSR) +static void +aeb_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; + unsigned char isr; + isr = port->REG_ISR & 0x0E; + if (isr == ISR_Tx) { + (chan->callbacks->xmt_char)(chan); + } else if (isr == ISR_Rx) { + (chan->callbacks->rcv_char)(chan, port->REG_RHR); + } + cyg_drv_interrupt_unmask(aeb_chan->int_num); +} +#endif diff --git a/packages/devs/serial/arm/aeb/current/src/aeb_serial.h b/packages/devs/serial/arm/aeb/current/src/aeb_serial.h new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/aeb/current/src/aeb_serial.h @@ -0,0 +1,154 @@ +#ifndef CYGONCE_ARM_AEB_SERIAL_H +#define CYGONCE_ARM_AEB_SERIAL_H + +// ==================================================================== +// +// aeb_serial.h +// +// Device I/O - Description of ARM AEB-1 serial hardware +// +// ==================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +// ==================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-04 +// Purpose: Internal interfaces for serial I/O drivers +// Description: +// +//####DESCRIPTIONEND#### +// +// ==================================================================== + +// Description of serial ports on ARM AEB-1 + +struct serial_port { + unsigned char _byte[32]; +}; + +#define REG(n) _byte[n*4] + +// Receive control registers +#define REG_RHR REG(0) // Receive holding register +#define REG_ISR REG(2) // Interrupt status register +#define REG_LSR REG(5) // Line status register +#define REG_MSR REG(6) // Modem status register +#define REG_SCR REG(7) // Scratch register + +// Transmit control registers +#define REG_THR REG(0) // Transmit holding register +#define REG_IER REG(1) // Interrupt enable register +#define REG_FCR REG(2) // FIFO control register +#define REG_LCR REG(3) // Line control register +#define REG_MCR REG(4) // Modem control register +#define REG_LDL REG(0) // LSB of baud rate +#define REG_MDL REG(1) // MSB of baud rate + +// Interrupt Enable Register +#define IER_RCV 0x01 +#define IER_XMT 0x02 +#define IER_LS 0x04 +#define IER_MS 0x08 + +// Line Control Register +#define LCR_WL5 0x00 // Word length +#define LCR_WL6 0x01 +#define LCR_WL7 0x02 +#define LCR_WL8 0x03 +#define LCR_SB1 0x00 // Number of stop bits +#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words +#define LCR_SB2 0x04 +#define LCR_PN 0x00 // Parity mode - none +#define LCR_PE 0x0C // Parity mode - even +#define LCR_PO 0x08 // Parity mode - odd +#define LCR_PM 0x28 // Forced "mark" parity +#define LCR_PS 0x38 // Forced "space" parity +#define LCR_DL 0x80 // Enable baud rate latch + +// Line Status Register +#define LSR_RSR 0x01 +#define LSR_THE 0x20 + +// Modem Control Register +#define MCR_DTR 0x01 +#define MCR_RTS 0x02 +#define MCR_INT 0x08 // Enable interrupts + +// Interrupt status register +#define ISR_Tx 0x02 +#define ISR_Rx 0x04 + +static unsigned char select_word_length[] = { + LCR_WL5, // 5 bits / word (char) + LCR_WL6, + LCR_WL7, + LCR_WL8 +}; + +static unsigned char select_stop_bits[] = { + 0, + LCR_SB1, // 1 stop bit + LCR_SB1_5, // 1.5 stop bit + LCR_SB2 // 2 stop bits +}; + +static unsigned char select_parity[] = { + LCR_PN, // No parity + LCR_PE, // Even parity + LCR_PO, // Odd parity + LCR_PM, // Mark parity + LCR_PS, // Space parity +}; + +// Baud rate values, based on raw 24MHz clock + +static unsigned short select_baud[] = { + 0, // Unused + 10000*3, // 50 + 6667*3, // 75 + 4545*3, // 110 + 3717*3, // 134.5 + 3333*3, // 150 + 0, // 200 + 1667*3, // 300 + 833*3, // 600 + 417*3, // 1200 + 277*3, // 1800 + 208*3, // 2400 + 139*3, // 3600 + 104*3, // 4800 + 69*3, // 7200 + 52*3, // 9600 + (69*3)/2, // 14400 + 26*3, // 19200 + 13*3, // 38400 + 0, // 57600 + 0, // 115200 + 0, // 230400 +}; + +#endif // CYGONCE_ARM_AEB_SERIAL_H diff --git a/packages/devs/serial/arm/cma230/current/ChangeLog b/packages/devs/serial/arm/cma230/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/cma230/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_arm_cma230.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/arm/cma230/current/cdl/ser_arm_cma230.cdl b/packages/devs/serial/arm/cma230/current/cdl/ser_arm_cma230.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/cma230/current/cdl/ser_arm_cma230.cdl @@ -0,0 +1,180 @@ +# ==================================================================== +# +# ser_arm_cma230.cdl +# +# eCos serial ARM/CMA230 configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-08 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_ARM_CMA230 { + display "Cogent ARM/CMA230 serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_ARM_CMA230 + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + Cogent ARM/CMA230." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a cma230_serial.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A { + display "Cogent ARM/CMA230 serial port A driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the Cogent + ARM/CMA230 port A." + + cdl_option CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_A_NAME { + display "Device name for Cogent ARM/CMA230 serial port A" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the device name for the Cogent + ARM/CMA230 port A." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BAUD { + display "Baud rate for the Cogent ARM/CMA230 serial port A driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + Cogent ARM/CMA230 port A." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE { + display "Buffer size for the Cogent ARM/CMA230 serial port A driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the Cogent ARM/CMA230 port A." + } +} + +cdl_component CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_B { + display "Cogent ARM/CMA230 serial port B driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the Cogent + ARM/CMA230 port B." + + cdl_option CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_B_NAME { + display "Device name for Cogent ARM/CMA230 serial port B" + flavor data + default_value {"\"/dev/ser2\""} + description " + This option specifies the device name for the Cogent + ARM/CMA230 port B." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BAUD { + display "Baud rate for the Cogent ARM/CMA230 serial port B driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + Cogent ARM/CMA230 port B." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE { + display "Buffer size for the Cogent ARM/CMA230 serial port B driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the Cogent ARM/CMA230 port B." + } +} + + cdl_component CYGPKG_IO_SERIAL_ARM_CMA230_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_ARM_CMA230_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_ARM_CMA230_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_arm_cma230.cdl diff --git a/packages/devs/serial/arm/cma230/current/src/cma230_serial.c b/packages/devs/serial/arm/cma230/current/src/cma230_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/cma230/current/src/cma230_serial.c @@ -0,0 +1,319 @@ +//========================================================================== +// +// io/serial/arm/cma230_serial.c +// +// Cogent CMA230 Serial I/O Interface Module (interrupt driven) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-04 +// Purpose: CMA230 Serial I/O module (interrupt driven version) +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_ARM_CMA230 + +#include "cma230_serial.h" + +typedef struct cma230_serial_info { + CYG_ADDRWORD base; + CYG_WORD int_num; + cyg_interrupt serial_interrupt; + cyg_handle_t serial_interrupt_handle; +} cma230_serial_info; + +static bool cma230_serial_init(struct cyg_devtab_entry *tab); +static bool cma230_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo cma230_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char cma230_serial_getc(serial_channel *chan); +static bool cma230_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void cma230_serial_start_xmit(serial_channel *chan); +static void cma230_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 cma230_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void cma230_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(cma230_serial_funs, + cma230_serial_putc, + cma230_serial_getc, + cma230_serial_set_config, + cma230_serial_start_xmit, + cma230_serial_stop_xmit + ); + +#ifdef CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A +static cma230_serial_info cma230_serial_info0 = {CMA101_DUARTA, + CYGNUM_HAL_INTERRUPT_SERIAL_A}; +#if CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE > 0 +static unsigned char cma230_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE]; +static unsigned char cma230_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(cma230_serial_channel0, + cma230_serial_funs, + cma230_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &cma230_serial_out_buf0[0], sizeof(cma230_serial_out_buf0), + &cma230_serial_in_buf0[0], sizeof(cma230_serial_in_buf0) + ); +#else +static SERIAL_CHANNEL(cma230_serial_channel0, + cma230_serial_funs, + cma230_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(cma230_serial_io0, + CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_A_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + cma230_serial_init, + cma230_serial_lookup, // Serial driver may need initializing + &cma230_serial_channel0 + ); +#endif // CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A + +#ifdef CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_B +static cma230_serial_info cma230_serial_info1 = {CMA101_DUARTB, + CYGNUM_HAL_INTERRUPT_SERIAL_B}; +#if CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE > 0 +static unsigned char cma230_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE]; +static unsigned char cma230_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(cma230_serial_channel1, + cma230_serial_funs, + cma230_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &cma230_serial_out_buf1[0], sizeof(cma230_serial_out_buf1), + &cma230_serial_in_buf1[0], sizeof(cma230_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(cma230_serial_channel1, + cma230_serial_funs, + cma230_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(cma230_serial_io1, + CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_B_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + cma230_serial_init, + cma230_serial_lookup, // Serial driver may need initializing + &cma230_serial_channel1 + ); +#endif // CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_B + +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool +cma230_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; + unsigned short baud_divisor = select_baud[new_config->baud]; + unsigned char _lcr, _ier; + if (baud_divisor == 0) return false; // Invalid configuration + _ier = port->ier; + port->ier = 0; // Disable port interrupts while changing hardware + _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | + select_stop_bits[new_config->stop] | + select_parity[new_config->parity]; + port->lcr = _lcr; + port->lcr |= LCR_DL; + port->mdl = baud_divisor >> 8; + port->ldl = baud_divisor & 0xFF; + port->lcr &= ~LCR_DL; + if (init) { + port->fcr = 0x07; // Enable and clear FIFO + if (chan->out_cbuf.len != 0) { + port->ier = IER_RCV; + } else { + port->ier = 0; + } + port->mcr = MCR_INT|MCR_DTR|MCR_RTS; // Master interrupt enable + } else { + port->ier = _ier; + } + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +cma230_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; +#ifdef CYGDBG_IO_INIT + diag_printf("CMA230 SERIAL init - dev: %x.%d\n", cma230_chan->base, cma230_chan->int_num); +#endif + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (chan->out_cbuf.len != 0) { + cyg_drv_interrupt_create(cma230_chan->int_num, + 99, // Priority - what goes here? + (cyg_addrword_t)chan, // Data item passed to interrupt handler + cma230_serial_ISR, + cma230_serial_DSR, + &cma230_chan->serial_interrupt_handle, + &cma230_chan->serial_interrupt); + cyg_drv_interrupt_attach(cma230_chan->serial_interrupt_handle); + cyg_drv_interrupt_unmask(cma230_chan->int_num); + } + cma230_serial_config_port(chan, &chan->config, true); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +cma230_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +cma230_serial_putc(serial_channel *chan, unsigned char c) +{ + cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; + if (port->lsr & LSR_THE) { +// Transmit buffer is empty + port->thr = c; + return true; + } else { +// No space + return false; + } +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +cma230_serial_getc(serial_channel *chan) +{ + unsigned char c; + cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; + while ((port->lsr & LSR_RSR) == 0) ; // Wait for char + c = port->rhr; + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +cma230_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return cma230_serial_config_port(chan, config, false); +} + +// Enable the transmitter on the device +static void +cma230_serial_start_xmit(serial_channel *chan) +{ + cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; + port->ier |= IER_XMT; // Enable xmit interrupt +} + +// Disable the transmitter on the device +static void +cma230_serial_stop_xmit(serial_channel *chan) +{ + cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; + port->ier &= ~IER_XMT; // Disable xmit interrupt +} + +// Serial I/O - low level interrupt handler (ISR) +static cyg_uint32 +cma230_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(cma230_chan->int_num); + cyg_drv_interrupt_acknowledge(cma230_chan->int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level interrupt handler (DSR) +static void +cma230_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; + unsigned char isr; + isr = port->isr & 0x0E; + if (isr == ISR_Tx) { + (chan->callbacks->xmt_char)(chan); + } else if (isr == ISR_Rx) { + (chan->callbacks->rcv_char)(chan, port->rhr); + } + cyg_drv_interrupt_unmask(cma230_chan->int_num); +} +#endif diff --git a/packages/devs/serial/arm/cma230/current/src/cma230_serial.h b/packages/devs/serial/arm/cma230/current/src/cma230_serial.h new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/cma230/current/src/cma230_serial.h @@ -0,0 +1,153 @@ +#ifndef CYGONCE_ARM_CMA230_SERIAL_H +#define CYGONCE_ARM_CMA230_SERIAL_H + +// ==================================================================== +// +// cma230_serial.h +// +// Device I/O - Description of Cogent CMA230 serial hardware +// +// ==================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +// ==================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-05-20 +// Purpose: Internal interfaces for serial I/O drivers +// Description: +// +//####DESCRIPTIONEND#### +// +// ==================================================================== + +// Description of serial ports on Cogent CMA230 + +struct serial_port { + unsigned char _byte[32]; +}; + +#define reg(n) _byte[n*8] + +// Receive control registers +#define rhr reg(0) // Receive holding register +#define isr reg(2) // Interrupt status register +#define lsr reg(5) // Line status register +#define msr reg(6) // Modem status register +#define scr reg(7) // Scratch register + +// Transmit control registers +#define thr reg(0) // Transmit holding register +#define ier reg(1) // Interrupt enable register +#define fcr reg(2) // FIFO control register +#define lcr reg(3) // Line control register +#define mcr reg(4) // Modem control register +#define ldl reg(0) // LSB of baud rate +#define mdl reg(1) // MSB of baud rate + +// Interrupt Enable Register +#define IER_RCV 0x01 +#define IER_XMT 0x02 +#define IER_LS 0x04 +#define IER_MS 0x08 + +// Line Control Register +#define LCR_WL5 0x00 // Word length +#define LCR_WL6 0x01 +#define LCR_WL7 0x02 +#define LCR_WL8 0x03 +#define LCR_SB1 0x00 // Number of stop bits +#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words +#define LCR_SB2 0x04 +#define LCR_PN 0x00 // Parity mode - none +#define LCR_PE 0x0C // Parity mode - even +#define LCR_PO 0x08 // Parity mode - odd +#define LCR_PM 0x28 // Forced "mark" parity +#define LCR_PS 0x38 // Forced "space" parity +#define LCR_DL 0x80 // Enable baud rate latch + +// Line Status Register +#define LSR_RSR 0x01 +#define LSR_THE 0x20 + +// Modem Control Register +#define MCR_DTR 0x01 +#define MCR_RTS 0x02 +#define MCR_INT 0x08 // Enable interrupts + +// Interrupt status register +#define ISR_Tx 0x02 +#define ISR_Rx 0x04 + +static unsigned char select_word_length[] = { + LCR_WL5, // 5 bits / word (char) + LCR_WL6, + LCR_WL7, + LCR_WL8 +}; + +static unsigned char select_stop_bits[] = { + 0, + LCR_SB1, // 1 stop bit + LCR_SB1_5, // 1.5 stop bit + LCR_SB2 // 2 stop bits +}; + +static unsigned char select_parity[] = { + LCR_PN, // No parity + LCR_PE, // Even parity + LCR_PO, // Odd parity + LCR_PM, // Mark parity + LCR_PS, // Space parity +}; + +// The Cogent board has a 3.6864 MHz crystal +static unsigned short select_baud[] = { + 0, // Unused + 4608, // 50 + 0, // 75 + 2094, // 110 + 0, // 134.5 + 1536, // 150 + 0, // 200 + 768, // 300 + 384, // 600 + 182, // 1200 + 0, // 1800 + 96, // 2400 + 0, // 3600 + 48, // 4800 + 32, // 7200 + 24, // 9600 + 16, // 14400 + 12, // 19200 + 6, // 38400 + 4, // 57600 + 2, // 115200 + 0, // 230400 +}; + +#endif // CYGONCE_ARM_CMA230_SERIAL_H diff --git a/packages/devs/serial/arm/ebsa285/current/ChangeLog b/packages/devs/serial/arm/ebsa285/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/ebsa285/current/ChangeLog @@ -0,0 +1,1176 @@ +2000-04-12 Hugo Tyson + + * src/ebsa285_serial.c (ebsa285_serial_init): Fix silly debug + message - enabled by serial1 test permutation. + +2000-04-12 Hugo Tyson + + * src/ebsa285_serial.c (ebsa285_serial_tx_DSR): Record + whether tx is to be enabled in ebsa285_chan->tx_active, so that + the DSR does not universally unmask it regardless. That led to an + interrupt loop, when the DSR callback had turned off the tx. + Also removed a typo - rx data was being read twice! + +2000-04-11 Hugo Tyson + + * cdl/ser_arm_ebsa285.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/arm/ebsa285/current/cdl/ser_arm_ebsa285.cdl b/packages/devs/serial/arm/ebsa285/current/cdl/ser_arm_ebsa285.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/ebsa285/current/cdl/ser_arm_ebsa285.cdl @@ -0,0 +1,138 @@ +# ==================================================================== +# +# ser_arm_ebsa285.cdl +# +# eCos serial ARM/EBSA285 configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): hmt +# Original data: gthomas +# Contributors: jskov +# Date: 2000-04-04 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + +cdl_package CYGPKG_IO_SERIAL_ARM_EBSA285 { + display "Intel StrongARM/EBSA285 serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_ARM_EBSA285 + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + StrongARM/EBSA285." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a ebsa285_serial.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + + cdl_component CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL { + display "Intel StrongARM/EBSA285 serial driver" + flavor bool + default_value 1 + description " + The serial device driver for the Intel StrongARM/EBSA285. + There is only one serial device on this board." + + cdl_option CYGDAT_IO_SERIAL_ARM_EBSA285_SERIAL_NAME { + display "Device name for the Intel StrongARM/EBSA285 serial port" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the name of serial device for the + Intel StrongARM/EBSA285 serial port." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BAUD { + display "Baud rate for the Intel StrongARM/EBSA285 serial port" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 \ + 4800 7200 9600 14400 19200 38400 57600 115200 234000 } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + Intel StrongARM/EBSA285 serial port." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE { + display "Buffer size for the Intel StrongARM/EBSA285 serial driver" + flavor data + default_value 128 + legal_values 0 to 8192 + description " + This option specifies the size of the internal buffers used + for the Intel StrongARM/EBSA285 serial port." + } + } + + cdl_component CYGPKG_IO_SERIAL_ARM_EBSA285_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_ARM_EBSA285_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_ARM_EBSA285_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_arm_ebsa285.cdl diff --git a/packages/devs/serial/arm/ebsa285/current/src/ebsa285_serial.c b/packages/devs/serial/arm/ebsa285/current/src/ebsa285_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/ebsa285/current/src/ebsa285_serial.c @@ -0,0 +1,427 @@ +//========================================================================== +// +// devs/serial/arm/ebsa285/current/src/ebsa285_serial.c +// +// ARM EBSA285 Serial I/O Interface Module (interrupt driven) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): hmt +// Contributors: hmt +// Date: 1999-07-26 +// Purpose: EBSA285 Serial I/O module (interrupt driven version) +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_ARM_EBSA285 + +#include +#include +#include +#include +#include + +#include // Hardware definitions + +// ------------------------------------------------------------------------ +// Baud rates and the like, table-driven setup +#define FCLK_MHZ 50 + +struct _baud { + unsigned char divisor_high, divisor_low; +}; + +// The indexing of this table must match the enum in serialio.h +// The arithmetic is (clock/4)/(baud * 16) - 1 + +#define NONE {0,0} +const static struct _baud bauds[] = { +#if (FCLK_MHZ == 50) + NONE, // unused + NONE, // 50 + NONE, // 75 + NONE, // 110 + NONE, // 134.5 + NONE, // 150 + NONE, // 200 + { 0xA, 0x2B }, // 300 2603 = 0x0A2B + { 0x5, 0x15 }, // 600 1301 = 0x0515 + { 0x2, 0x8A }, // 1200 650 = 0x028A + { 0x1, 0xB1 }, // 1800 433 = 0x01B1 + { 0x1, 0x45 }, // 2400 325 = 0x0145 + { 0x0, 0xD8 }, // 3600 216 = 0x00D8 + { 0x0, 0xA2 }, // 4800 162 = 0x00A2 + { 0x0, 0x6B }, // 7200 107 = 0x006B + { 0x0, 0x50 }, // 9600 80 = 0x0050 + { 0x0, 0x35 }, // 14400 53 = 0x0035 + { 0x0, 0x28 }, // 19200 40 = 0x0028 + { 0x0, 0x13 }, // 38400 19 = 0x0013 + NONE, // 57600 + NONE, // 115200 + NONE // 230400 +#elif (FCLK_MHZ == 60) +#error NOT SUPPORTED - these figures are more for documentation + { /* 300, */ 0xC, 0x34}, /* 2603 = 0x0A2B */ + { /* 600, */ 0x6, 0x19}, /* 1301 = 0x0515 */ + { /* 1200, */ 0x3, 0x0C}, /* 650 = 0x028A */ + { /* 2400, */ 0x1, 0x86}, /* 325 = 0x0145 */ + { /* 4800, */ 0x0, 0xC2}, /* 162 = 0x00A2 */ + { /* 9600, */ 0x0, 0x61}, /* 80 = 0x0050 */ + { /* 19200, */ 0x0, 0x30}, /* 40 = 0x0028 */ + { /* 38400, */ 0x0, 0x17}, /* 19 = 0x0013 */ +#endif +}; + +static int select_word_length[] = { + SA110_UART_DATA_LENGTH_5_BITS, // 5 bits + SA110_UART_DATA_LENGTH_6_BITS, // 6 bits + SA110_UART_DATA_LENGTH_7_BITS, // 7 bits + SA110_UART_DATA_LENGTH_8_BITS // 8 bits +}; + +static int select_stop_bits[] = { + -1, // unused + SA110_UART_STOP_BITS_ONE, // 1 stop bit + -1, // 1.5 stop bit + SA110_UART_STOP_BITS_TWO // 2 stop bits +}; + +static int select_parity[] = { + SA110_UART_PARITY_DISABLED, // No parity + SA110_UART_PARITY_ENABLED | SA110_UART_PARITY_EVEN, // Even parity + SA110_UART_PARITY_ENABLED | SA110_UART_PARITY_ODD, // Odd parity + -1, // Mark parity + -1 // Space parity +}; + +// ------------------------------------------------------------------------ +// some forward references + +struct ebsa285_serial_interrupt { + CYG_WORD int_num; + cyg_interrupt serial_interrupt; + cyg_handle_t serial_interrupt_handle; +}; + +typedef struct ebsa285_serial_info { + struct ebsa285_serial_interrupt rx; + struct ebsa285_serial_interrupt tx; + int tx_active; +} ebsa285_serial_info; + +static bool ebsa285_serial_init(struct cyg_devtab_entry *tab); +static bool ebsa285_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo ebsa285_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char ebsa285_serial_getc(serial_channel *chan); +static bool ebsa285_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void ebsa285_serial_start_xmit(serial_channel *chan); +static void ebsa285_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 ebsa285_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void ebsa285_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); +static cyg_uint32 ebsa285_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void ebsa285_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(ebsa285_serial_funs, + ebsa285_serial_putc, + ebsa285_serial_getc, + ebsa285_serial_set_config, + ebsa285_serial_start_xmit, + ebsa285_serial_stop_xmit + ); + + +// ------------------------------------------------------------------------ +// this is dummy in config: there is only one device on the EBSA285 +#ifdef CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL + +static ebsa285_serial_info ebsa285_serial_info1 = { + { CYGNUM_HAL_INTERRUPT_SERIAL_RX }, + { CYGNUM_HAL_INTERRUPT_SERIAL_TX }, + 0 +}; + +#if CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE > 0 +static unsigned char ebsa285_serial_out_buf[CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE]; +static unsigned char ebsa285_serial_in_buf[CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(ebsa285_serial_channel, + ebsa285_serial_funs, + ebsa285_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &ebsa285_serial_out_buf[0], sizeof(ebsa285_serial_out_buf), + &ebsa285_serial_in_buf[0], sizeof(ebsa285_serial_in_buf) + ); +#else +static SERIAL_CHANNEL(ebsa285_serial_channel, + ebsa285_serial_funs, + ebsa285_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(ebsa285_serial_io, + CYGDAT_IO_SERIAL_ARM_EBSA285_SERIAL_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + ebsa285_serial_init, + ebsa285_serial_lookup, // Serial driver may need initializing + &ebsa285_serial_channel + ); +#endif // CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL + +// ------------------------------------------------------------------------ + + +// ------------------------------------------------------------------------ +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool +ebsa285_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + int dummy, h, m, l; + + // Make sure everything is off + *SA110_UART_CONTROL_REGISTER = SA110_UART_DISABLED | SA110_SIR_DISABLED; + + // Read the RXStat to drain the fifo + dummy = *SA110_UART_RXSTAT; + + // Set the baud rate - this also turns the uart on. + // + // Note that the ordering of these writes is critical, + // and the writes to the H_BAUD_CONTROL and CONTROL_REGISTER + // are necessary to force the UART to update its register + // contents. + + l = bauds[new_config->baud].divisor_low; // zeros in unused slots here + m = bauds[new_config->baud].divisor_high; // and here + h = SA110_UART_BREAK_DISABLED | + select_stop_bits[new_config->stop] | // -1s in unused slots for these + select_parity[new_config->parity] | // and these + SA110_UART_FIFO_ENABLED | // and these below + select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; + + if ( 0 != (l + m) && h >= 0 && h < 256 ) { + *SA110_UART_L_BAUD_CONTROL = l; + *SA110_UART_M_BAUD_CONTROL = m; + *SA110_UART_H_BAUD_CONTROL = h; + init = true; // AOK + } + else if ( init ) { + // put in some sensible defaults + *SA110_UART_L_BAUD_CONTROL = 0x13; // bp->divisor_low; + *SA110_UART_M_BAUD_CONTROL = 0x00; // bp->divisor_high; + *SA110_UART_H_BAUD_CONTROL = SA110_UART_BREAK_DISABLED | + SA110_UART_PARITY_DISABLED | + SA110_UART_STOP_BITS_ONE | + SA110_UART_FIFO_ENABLED | + SA110_UART_DATA_LENGTH_8_BITS; + } + + // All set, re-enable the device: + *SA110_UART_CONTROL_REGISTER = SA110_UART_ENABLED | SA110_SIR_DISABLED; + + if (init && new_config != &chan->config) { + // record the new setup + chan->config = *new_config; + } + // All done + return init; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +ebsa285_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; +#ifdef CYGDBG_IO_INIT + diag_printf("EBSA285 SERIAL init - dev: %x\n", ebsa285_chan); +#endif + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (chan->out_cbuf.len != 0) { + + // first for rx + cyg_drv_interrupt_create(ebsa285_chan->rx.int_num, + 99, // Priority - unused + (cyg_addrword_t)chan, // Data item passed to interrupt handler + ebsa285_serial_rx_ISR, + ebsa285_serial_rx_DSR, + &ebsa285_chan->rx.serial_interrupt_handle, + &ebsa285_chan->rx.serial_interrupt); + cyg_drv_interrupt_attach(ebsa285_chan->rx.serial_interrupt_handle); + cyg_drv_interrupt_unmask(ebsa285_chan->rx.int_num); + + // then for tx + cyg_drv_interrupt_create(ebsa285_chan->tx.int_num, + 99, // Priority - unused + (cyg_addrword_t)chan, // Data item passed to interrupt handler + ebsa285_serial_tx_ISR, + ebsa285_serial_tx_DSR, + &ebsa285_chan->tx.serial_interrupt_handle, + &ebsa285_chan->tx.serial_interrupt); + cyg_drv_interrupt_attach(ebsa285_chan->tx.serial_interrupt_handle); + // DO NOT cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num); + ebsa285_chan->tx_active = 0; + } + (void)ebsa285_serial_config_port(chan, &chan->config, true); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +ebsa285_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +ebsa285_serial_putc(serial_channel *chan, unsigned char c) +{ + if ((*SA110_UART_FLAG_REGISTER & SA110_TX_FIFO_STATUS_MASK) == SA110_TX_FIFO_BUSY) + return false; // No space + + *SA110_UART_DATA_REGISTER = c; // Transmit buffer is empty + return true; +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +ebsa285_serial_getc(serial_channel *chan) +{ + unsigned char c; + while ((*SA110_UART_FLAG_REGISTER & SA110_RX_FIFO_STATUS_MASK) == SA110_RX_FIFO_EMPTY) + ; // wait for char + c = (char)(*SA110_UART_DATA_REGISTER & 0xFF); + // no error checking... no way to return the info + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +ebsa285_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return ebsa285_serial_config_port(chan, config, false); +} + +// Enable the transmitter on the device (nope, already in use by hal_diag) +static void +ebsa285_serial_start_xmit(serial_channel *chan) +{ + ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; + ebsa285_chan->tx_active = 1; + cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num); +} + +// Disable the transmitter on the device (nope, remains in use by hal_diag) +static void +ebsa285_serial_stop_xmit(serial_channel *chan) +{ + ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(ebsa285_chan->tx.int_num); + ebsa285_chan->tx_active = 0; +} + +// Serial I/O - low level interrupt handlers (ISR) +static cyg_uint32 +ebsa285_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(ebsa285_chan->rx.int_num); + cyg_drv_interrupt_acknowledge(ebsa285_chan->rx.int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +static cyg_uint32 +ebsa285_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(ebsa285_chan->tx.int_num); + cyg_drv_interrupt_acknowledge(ebsa285_chan->tx.int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level interrupt handlers (DSR) +static void +ebsa285_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; + if ((*SA110_UART_FLAG_REGISTER & SA110_RX_FIFO_STATUS_MASK) != SA110_RX_FIFO_EMPTY) { + char c; + int status; + c = (char)(*SA110_UART_DATA_REGISTER & 0xFF); + status = *SA110_UART_RXSTAT; + if ( 0 == (status & (SA110_UART_FRAMING_ERROR_MASK | + SA110_UART_PARITY_ERROR_MASK | + SA110_UART_OVERRUN_ERROR_MASK)) ) + (chan->callbacks->rcv_char)(chan, c); + } + cyg_drv_interrupt_unmask(ebsa285_chan->rx.int_num); +} + +static void +ebsa285_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; + if ((*SA110_UART_FLAG_REGISTER & SA110_TX_FIFO_STATUS_MASK) != SA110_TX_FIFO_BUSY) { + (chan->callbacks->xmt_char)(chan); + } + if ( ebsa285_chan->tx_active ) // it might be halted in callback above + cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num); +} +#endif // CYGPKG_IO_SERIAL_ARM_EBSA285 + +// ------------------------------------------------------------------------ +// EOF ebsa285_serial.c diff --git a/packages/devs/serial/arm/edb7xxx/current/ChangeLog b/packages/devs/serial/arm/edb7xxx/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/edb7xxx/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_arm_edb7xxx.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/arm/edb7xxx/current/cdl/ser_arm_edb7xxx.cdl b/packages/devs/serial/arm/edb7xxx/current/cdl/ser_arm_edb7xxx.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/edb7xxx/current/cdl/ser_arm_edb7xxx.cdl @@ -0,0 +1,181 @@ +# ==================================================================== +# +# ser_arm_edb7xxx.cdl +# +# eCos serial ARM/EDB7XXX configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-08 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_ARM_EDB7XXX { + display "ARM EDB7XXX serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_ARM_EDB7XXX + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + Cirrus Logic EDB7XXX." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a edb7xxx_serial.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL1 { + display "Cirrus Logic EDB7XXX serial port 1 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the Cirrus Logic EDB7XXX + port 1." + + + cdl_option CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL1_NAME { + display "Device name for the Cirrus Logic EDB7XXX serial port 1 driver" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the name of serial device for the ARM + EDB7XXX port 1." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BAUD { + display "Baud rate for the Cirrus Logic EDB7XXX serial port 1 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the ARM + EDB7XXX port 1." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE { + display "Buffer size for the Cirrus Logic EDB7XXX serial port 1 driver" + flavor data + default_value 128 + legal_values 0 to 8192 + description " + This option specifies the size of the internal buffers used + for the Cirrus Logic EDB7XXX port 1." + } +} + +cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2 { + display "Cirrus Logic EDB7XXX serial port 2 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the ARM + EDB7XXX port 2." + + cdl_option CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL2_NAME { + display "Device name for the Cirrus Logic EDB7XXX serial port 2 driver" + flavor data + default_value {"\"/dev/ser2\""} + description " + This option specifies the name of serial device for the ARM + EDB7XXX port 2." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BAUD { + display "Baud rate for the Cirrus Logic EDB7XXX serial port 2 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + Cirrus Logic EDB7XXX port 2." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE { + display "Buffer size for the Cirrus Logic EDB7XXX serial port 2 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used for + the Cirrus Logic EDB7XXX port 2." + } +} + + cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_ARM_EDB7XXX_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_ARM_EDB7XXX_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_arm_edb7xxx.cdl diff --git a/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.c b/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.c @@ -0,0 +1,383 @@ +//========================================================================== +// +// io/serial/arm/edb7xxx_serial.c +// +// Cirrus Logic EDB7XXX Serial I/O Interface Module (interrupt driven) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-04 +// Purpose: EDB7XXX Serial I/O module (interrupt driven version) +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_ARM_EDB7XXX + +#include "edb7xxx_serial.h" + +typedef struct edb7xxx_serial_info { + CYG_ADDRWORD data, // Pointer to data register + control, // Pointer to baud rate/line control register + stat, // Pointer to system flags for this port + syscon; // Pointer to system control for this port + CYG_WORD tx_int_num, // Transmit interrupt number + rx_int_num, // Receive interrupt number + ms_int_num; // Modem Status Change interrupt number + cyg_interrupt serial_tx_interrupt, + serial_rx_interrupt, + serial_ms_interrupt; + cyg_handle_t serial_tx_interrupt_handle, + serial_rx_interrupt_handle, + serial_ms_interrupt_handle; + bool tx_enabled; +} edb7xxx_serial_info; + +static bool edb7xxx_serial_init(struct cyg_devtab_entry *tab); +static bool edb7xxx_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo edb7xxx_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char edb7xxx_serial_getc(serial_channel *chan); +static bool edb7xxx_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void edb7xxx_serial_start_xmit(serial_channel *chan); +static void edb7xxx_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 edb7xxx_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void edb7xxx_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); +static cyg_uint32 edb7xxx_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void edb7xxx_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); +static cyg_uint32 edb7xxx_serial_ms_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void edb7xxx_serial_ms_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(edb7xxx_serial_funs, + edb7xxx_serial_putc, + edb7xxx_serial_getc, + edb7xxx_serial_set_config, + edb7xxx_serial_start_xmit, + edb7xxx_serial_stop_xmit + ); + +#ifdef CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL1 +static edb7xxx_serial_info edb7xxx_serial_info1 = {UARTDR1, // Data register + UBLCR1, // Port control + SYSFLG1, // Status + SYSCON1, // System config + CYGNUM_HAL_INTERRUPT_UTXINT1, // Tx interrupt + CYGNUM_HAL_INTERRUPT_URXINT1, // Rx interrupt + 0 /*CYGNUM_HAL_INTERRUPT_UMSINT*/}; // Modem control +#if CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE > 0 +static unsigned char edb7xxx_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE]; +static unsigned char edb7xxx_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(edb7xxx_serial_channel1, + edb7xxx_serial_funs, + edb7xxx_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &edb7xxx_serial_out_buf1[0], sizeof(edb7xxx_serial_out_buf1), + &edb7xxx_serial_in_buf1[0], sizeof(edb7xxx_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(edb7xxx_serial_channel1, + edb7xxx_serial_funs, + edb7xxx_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(edb7xxx_serial_io1, + CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL1_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + edb7xxx_serial_init, + edb7xxx_serial_lookup, // Serial driver may need initializing + &edb7xxx_serial_channel1 + ); +#endif // CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2 + +#ifdef CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2 +static edb7xxx_serial_info edb7xxx_serial_info2 = {UARTDR2, // Data register + UBLCR2, // Port control + SYSFLG2, // Status + SYSCON2, // System config + CYGNUM_HAL_INTERRUPT_UTXINT2, // Tx interrupt + CYGNUM_HAL_INTERRUPT_URXINT2, // Rx interrupt + 0}; // No modem control +#if CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE > 0 +static unsigned char edb7xxx_serial_out_buf2[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE]; +static unsigned char edb7xxx_serial_in_buf2[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(edb7xxx_serial_channel2, + edb7xxx_serial_funs, + edb7xxx_serial_info2, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &edb7xxx_serial_out_buf2[0], sizeof(edb7xxx_serial_out_buf2), + &edb7xxx_serial_in_buf2[0], sizeof(edb7xxx_serial_in_buf2) + ); +#else +static SERIAL_CHANNEL(edb7xxx_serial_channel2, + edb7xxx_serial_funs, + edb7xxx_serial_info2, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(edb7xxx_serial_io2, + CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL2_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + edb7xxx_serial_init, + edb7xxx_serial_lookup, // Serial driver may need initializing + &edb7xxx_serial_channel2 + ); +#endif // CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2 + +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool +edb7xxx_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + volatile cyg_uint32 *syscon = (volatile cyg_uint32 *)edb7xxx_chan->syscon; + volatile cyg_uint32 *blcfg = (volatile cyg_uint32 *)edb7xxx_chan->control; + unsigned int baud_divisor = select_baud[new_config->baud]; + cyg_uint32 _lcr; + if (baud_divisor == 0) return false; + // Disable port interrupts while changing hardware + _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | + select_stop_bits[new_config->stop] | + select_parity[new_config->parity] | + UBLCR_FIFOEN | UART_BITRATE(baud_divisor); +#ifdef CYGDBG_IO_INIT + diag_printf("Set CTL: %x = %x\n", blcfg, _lcr); +#endif + *blcfg = _lcr; + *syscon |= SYSCON1_UART1EN; + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +edb7xxx_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; +#ifdef CYGDBG_IO_INIT + diag_printf("EDB7XXX SERIAL init - dev: %x.%d\n", edb7xxx_chan->control, edb7xxx_chan->tx_int_num); +#endif + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (chan->out_cbuf.len != 0) { + cyg_drv_interrupt_create(edb7xxx_chan->tx_int_num, + 99, // Priority - unused + (cyg_addrword_t)chan, // Data item passed to interrupt handler + edb7xxx_serial_tx_ISR, + edb7xxx_serial_tx_DSR, + &edb7xxx_chan->serial_tx_interrupt_handle, + &edb7xxx_chan->serial_tx_interrupt); + cyg_drv_interrupt_attach(edb7xxx_chan->serial_tx_interrupt_handle); + cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num); + edb7xxx_chan->tx_enabled = false; + } + if (chan->in_cbuf.len != 0) { + cyg_drv_interrupt_create(edb7xxx_chan->rx_int_num, + 99, // Priority - unused + (cyg_addrword_t)chan, // Data item passed to interrupt handler + edb7xxx_serial_rx_ISR, + edb7xxx_serial_rx_DSR, + &edb7xxx_chan->serial_rx_interrupt_handle, + &edb7xxx_chan->serial_rx_interrupt); + cyg_drv_interrupt_attach(edb7xxx_chan->serial_rx_interrupt_handle); + cyg_drv_interrupt_unmask(edb7xxx_chan->rx_int_num); + } + edb7xxx_serial_config_port(chan, &chan->config, true); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +edb7xxx_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +edb7xxx_serial_putc(serial_channel *chan, unsigned char c) +{ + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + volatile cyg_uint8 *data = (volatile cyg_uint8 *)edb7xxx_chan->data; + volatile cyg_uint32 *stat = (volatile cyg_uint32 *)edb7xxx_chan->stat; + if ((*stat & SYSFLG1_UTXFF1) == 0) { +// Transmit buffer/FIFO is not full + *data = c; + return true; + } else { +// No space + return false; + } +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +edb7xxx_serial_getc(serial_channel *chan) +{ + unsigned char c; + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + volatile cyg_uint32 *data = (volatile cyg_uint32 *)edb7xxx_chan->data; + volatile cyg_uint32 *stat = (volatile cyg_uint32 *)edb7xxx_chan->stat; + while (*stat & SYSFLG1_URXFE1) ; // Wait for char + c = *data; + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +edb7xxx_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return edb7xxx_serial_config_port(chan, config, false); +} + +// Enable the transmitter (interrupt) on the device +static void +edb7xxx_serial_start_xmit(serial_channel *chan) +{ + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + edb7xxx_chan->tx_enabled = true; + cyg_drv_interrupt_unmask(edb7xxx_chan->tx_int_num); +} + +// Disable the transmitter on the device +static void +edb7xxx_serial_stop_xmit(serial_channel *chan) +{ + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num); + edb7xxx_chan->tx_enabled = false; +} + +// Serial I/O - low level Tx interrupt handler (ISR) +static cyg_uint32 +edb7xxx_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num); + cyg_drv_interrupt_acknowledge(edb7xxx_chan->tx_int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level Tx interrupt handler (DSR) +static void +edb7xxx_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + (chan->callbacks->xmt_char)(chan); + if (edb7xxx_chan->tx_enabled) { + cyg_drv_interrupt_unmask(edb7xxx_chan->tx_int_num); + } +} + +// Serial I/O - low level Rx interrupt handler (ISR) +static cyg_uint32 +edb7xxx_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(edb7xxx_chan->rx_int_num); + cyg_drv_interrupt_acknowledge(edb7xxx_chan->rx_int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level Rx interrupt handler (DSR) +static void +edb7xxx_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + volatile cyg_uint32 *datreg = (volatile cyg_uint32 *)edb7xxx_chan->data; + volatile cyg_uint32 *stat = (volatile cyg_uint32 *)edb7xxx_chan->stat; + while (!(*stat & SYSFLG1_URXFE1)) + (chan->callbacks->rcv_char)(chan, *datreg); + cyg_drv_interrupt_unmask(edb7xxx_chan->rx_int_num); +} + +// Serial I/O - low level Ms interrupt handler (ISR) +static cyg_uint32 +edb7xxx_serial_ms_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(edb7xxx_chan->ms_int_num); + cyg_drv_interrupt_acknowledge(edb7xxx_chan->ms_int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level Ms interrupt handler (DSR) +static void +edb7xxx_serial_ms_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ +} +#endif // CYGPKG_IO_SERIAL_ARM_EDB7XXX + diff --git a/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.h b/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.h new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/edb7xxx/current/src/edb7xxx_serial.h @@ -0,0 +1,100 @@ +#ifndef CYGONCE_ARM_EDB7XXX_SERIAL_H +#define CYGONCE_ARM_EDB7XXX_SERIAL_H + +// ==================================================================== +// +// edb7xxx_serial.h +// +// Device I/O - Description of Cirrus Logic EDB7XXX serial hardware +// +// ==================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +// ==================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-04 +// Purpose: Internal interfaces for serial I/O drivers +// Description: +// +//####DESCRIPTIONEND#### +// +// ==================================================================== + +// Description of serial ports on Cirrus Logic EDB7XXX + +#include // Hardware definitions + +static unsigned int select_word_length[] = { + UBLCR_WRDLEN5, // 5 bits / word (char) + UBLCR_WRDLEN6, + UBLCR_WRDLEN7, + UBLCR_WRDLEN8 +}; + +static unsigned int select_stop_bits[] = { + 0, + 0, // 1 stop bit + 0, // 1.5 stop bit + UBLCR_XSTOP // 2 stop bits +}; + +static unsigned int select_parity[] = { + 0, // No parity + UBLCR_PRTEN|UBLCR_EVENPRT, // Even parity + UBLCR_PRTEN, // Odd parity + 0, // Mark parity + 0, // Space parity +}; + +// Baud rate values, based on PLL clock + +static cyg_int32 select_baud[] = { + 0, // Unused + 50, // 50 + 75, // 75 + 110, // 110 + 0, // 134.5 + 150, // 150 + 200, // 200 + 300, // 300 + 600, // 600 + 1200, // 1200 + 1800, // 1800 + 2400, // 2400 + 3600, // 3600 + 4800, // 4800 + 7200, // 7200 + 9600, // 9600 + 14400, // 14400 + 19200, // 19200 + 38400, // 38400 + 57600, // 57600 + 115200, // 115200 + 0, // 230400 +}; + +#endif // CYGONCE_ARM_EDB7XXX_SERIAL_H diff --git a/packages/devs/serial/arm/pid/current/ChangeLog b/packages/devs/serial/arm/pid/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/pid/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_arm_pid.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/arm/pid/current/cdl/ser_arm_pid.cdl b/packages/devs/serial/arm/pid/current/cdl/ser_arm_pid.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/pid/current/cdl/ser_arm_pid.cdl @@ -0,0 +1,180 @@ +# ==================================================================== +# +# ser_arm_pid.cdl +# +# eCos serial ARM/PID configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-07 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_ARM_PID { + display "ARM PID serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_ARM_PID + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + ARM PID." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a pid_serial_with_ints.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_ARM_PID_SERIAL0 { + display "ARM PID serial port 0 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the ARM PID + port 0." + + cdl_option CYGDAT_IO_SERIAL_ARM_PID_SERIAL0_NAME { + display "Device name for ARM PID serial port 0 driver" + flavor data + default_value {"\"/dev/ser0\""} + description " + This option specifies the name of the serial device for the + ARM PID port 0." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BAUD { + display "Baud rate for the ARM PID serial port 0 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + ARM PID port 0." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE { + display "Buffer size for the ARM PID serial port 0 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the ARM PID port 0." + } +} + +cdl_component CYGPKG_IO_SERIAL_ARM_PID_SERIAL1 { + display "ARM PID serial port 1 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the ARM PID + port 1." + + cdl_option CYGDAT_IO_SERIAL_ARM_PID_SERIAL1_NAME { + display "Device name for ARM PID serial port 1 driver" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the name of the serial device for the + ARM PID port 1." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BAUD { + display "Baud rate for the ARM PID serial port 1 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + ARM PID port 1." + } + + cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE { + display "Buffer size for the ARM PID serial port 1 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the ARM PID port 1." + } +} + + cdl_component CYGPKG_IO_SERIAL_ARM_PID_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_ARM_PID_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_ARM_PID_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_arm_pid.cdl diff --git a/packages/devs/serial/arm/pid/current/src/pid_serial.h b/packages/devs/serial/arm/pid/current/src/pid_serial.h new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/pid/current/src/pid_serial.h @@ -0,0 +1,162 @@ +#ifndef CYGONCE_ARM_PID_SERIAL_H +#define CYGONCE_ARM_PID_SERIAL_H + +// ==================================================================== +// +// pid_serial.h +// +// Device I/O - Description of ARM PID7T serial hardware +// +// ==================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +// ==================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-04 +// Purpose: Internal interfaces for serial I/O drivers +// Description: +// +//####DESCRIPTIONEND#### +// +// ==================================================================== + +// Description of serial ports on ARM PID7T + +struct serial_port { + unsigned char _byte[32]; +}; + +// Little-endian version +#if (CYG_BYTEORDER == CYG_LSBFIRST) + +#define reg(n) _byte[n*4] + +#else // Big-endian version + +#define reg(n) _byte[(n*4)^3] + +#endif + +// Receive control registers +#define rhr reg(0) // Receive holding register +#define isr reg(2) // Interrupt status register +#define lsr reg(5) // Line status register +#define msr reg(6) // Modem status register +#define scr reg(7) // Scratch register + +// Transmit control registers +#define thr reg(0) // Transmit holding register +#define ier reg(1) // Interrupt enable register +#define fcr reg(2) // FIFO control register +#define lcr reg(3) // Line control register +#define mcr reg(4) // Modem control register +#define ldl reg(0) // LSB of baud rate +#define mdl reg(1) // MSB of baud rate + +// Interrupt Enable Register +#define IER_RCV 0x01 +#define IER_XMT 0x02 +#define IER_LS 0x04 +#define IER_MS 0x08 + +// Line Control Register +#define LCR_WL5 0x00 // Word length +#define LCR_WL6 0x01 +#define LCR_WL7 0x02 +#define LCR_WL8 0x03 +#define LCR_SB1 0x00 // Number of stop bits +#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words +#define LCR_SB2 0x04 +#define LCR_PN 0x00 // Parity mode - none +#define LCR_PE 0x0C // Parity mode - even +#define LCR_PO 0x08 // Parity mode - odd +#define LCR_PM 0x28 // Forced "mark" parity +#define LCR_PS 0x38 // Forced "space" parity +#define LCR_DL 0x80 // Enable baud rate latch + +// Line Status Register +#define LSR_RSR 0x01 +#define LSR_THE 0x20 + +// Modem Control Register +#define MCR_DTR 0x01 +#define MCR_RTS 0x02 +#define MCR_INT 0x08 // Enable interrupts + +// Interrupt status register +#define ISR_Tx 0x02 +#define ISR_Rx 0x04 +#define ISR_RxTO 0x0C + +static unsigned char select_word_length[] = { + LCR_WL5, // 5 bits / word (char) + LCR_WL6, + LCR_WL7, + LCR_WL8 +}; + +static unsigned char select_stop_bits[] = { + 0, + LCR_SB1, // 1 stop bit + LCR_SB1_5, // 1.5 stop bit + LCR_SB2 // 2 stop bits +}; + +static unsigned char select_parity[] = { + LCR_PN, // No parity + LCR_PE, // Even parity + LCR_PO, // Odd parity + LCR_PM, // Mark parity + LCR_PS, // Space parity +}; + +static unsigned short select_baud[] = { + 0, // Unused + 0, // 50 + 0, // 75 + 1047, // 110 + 0, // 134.5 + 768, // 150 + 0, // 200 + 384, // 300 + 192, // 600 + 96, // 1200 + 24, // 1800 + 48, // 2400 + 0, // 3600 + 24, // 4800 + 16, // 7200 + 12, // 9600 + 8, // 14400 + 6, // 19200 + 3, // 38400 + 2, // 57600 + 1, // 115200 + 0, // 230400 +}; + +#endif // CYGONCE_ARM_PID_SERIAL_H diff --git a/packages/devs/serial/arm/pid/current/src/pid_serial_with_ints.c b/packages/devs/serial/arm/pid/current/src/pid_serial_with_ints.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/arm/pid/current/src/pid_serial_with_ints.c @@ -0,0 +1,318 @@ +//========================================================================== +// +// io/serial/arm/pid_serial_with_ints.c +// +// ARM PID Serial I/O Interface Module (interrupt driven) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-04 +// Purpose: PID Serial I/O module (interrupt driven version) +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_ARM_PID +#include "pid_serial.h" + +typedef struct pid_serial_info { + CYG_ADDRWORD base; + CYG_WORD int_num; + cyg_interrupt serial_interrupt; + cyg_handle_t serial_interrupt_handle; +} pid_serial_info; + +static bool pid_serial_init(struct cyg_devtab_entry *tab); +static bool pid_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo pid_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char pid_serial_getc(serial_channel *chan); +static bool pid_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void pid_serial_start_xmit(serial_channel *chan); +static void pid_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 pid_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void pid_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(pid_serial_funs, + pid_serial_putc, + pid_serial_getc, + pid_serial_set_config, + pid_serial_start_xmit, + pid_serial_stop_xmit + ); + +#ifdef CYGPKG_IO_SERIAL_ARM_PID_SERIAL0 +static pid_serial_info pid_serial_info0 = {0x0D800000, CYGNUM_HAL_INTERRUPT_SERIALA}; +#if CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE > 0 +static unsigned char pid_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE]; +static unsigned char pid_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(pid_serial_channel0, + pid_serial_funs, + pid_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &pid_serial_out_buf0[0], sizeof(pid_serial_out_buf0), + &pid_serial_in_buf0[0], sizeof(pid_serial_in_buf0) + ); +#else +static SERIAL_CHANNEL(pid_serial_channel0, + pid_serial_funs, + pid_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(pid_serial_io0, + CYGDAT_IO_SERIAL_ARM_PID_SERIAL0_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + pid_serial_init, + pid_serial_lookup, // Serial driver may need initializing + &pid_serial_channel0 + ); +#endif // CYGPKG_IO_SERIAL_ARM_PID_SERIAL0 + +#ifdef CYGPKG_IO_SERIAL_ARM_PID_SERIAL1 +static pid_serial_info pid_serial_info1 = {0x0D800020, CYGNUM_HAL_INTERRUPT_SERIALB}; +#if CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE > 0 +static unsigned char pid_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE]; +static unsigned char pid_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(pid_serial_channel1, + pid_serial_funs, + pid_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &pid_serial_out_buf1[0], sizeof(pid_serial_out_buf1), + &pid_serial_in_buf1[0], sizeof(pid_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(pid_serial_channel1, + pid_serial_funs, + pid_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(pid_serial_io1, + CYGDAT_IO_SERIAL_ARM_PID_SERIAL1_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + pid_serial_init, + pid_serial_lookup, // Serial driver may need initializing + &pid_serial_channel1 + ); +#endif // CYGPKG_IO_SERIAL_ARM_PID_SERIAL1 + +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool +pid_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; + unsigned short baud_divisor = select_baud[new_config->baud]; + unsigned char _lcr, _ier; + if (baud_divisor == 0) return false; // Invalid configuration + _ier = port->ier; + port->ier = 0; // Disable port interrupts while changing hardware + _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | + select_stop_bits[new_config->stop] | + select_parity[new_config->parity]; + port->lcr = _lcr; + port->lcr |= LCR_DL; + port->mdl = baud_divisor >> 8; + port->ldl = baud_divisor & 0xFF; + port->lcr &= ~LCR_DL; + if (init) { + port->fcr = 0x07; // Enable and clear FIFO + if (chan->out_cbuf.len != 0) { + port->ier = IER_RCV; + } else { + port->ier = 0; + } + port->mcr = MCR_INT|MCR_DTR|MCR_RTS; // Master interrupt enable + } else { + port->ier = _ier; + } + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +pid_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; +#ifdef CYGDBG_IO_INIT + diag_printf("PID SERIAL init - dev: %x.%d\n", pid_chan->base, pid_chan->int_num); +#endif + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (chan->out_cbuf.len != 0) { + cyg_drv_interrupt_create(pid_chan->int_num, + 99, // Priority - what goes here? + (cyg_addrword_t)chan, // Data item passed to interrupt handler + pid_serial_ISR, + pid_serial_DSR, + &pid_chan->serial_interrupt_handle, + &pid_chan->serial_interrupt); + cyg_drv_interrupt_attach(pid_chan->serial_interrupt_handle); + cyg_drv_interrupt_unmask(pid_chan->int_num); + } + pid_serial_config_port(chan, &chan->config, true); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +pid_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +pid_serial_putc(serial_channel *chan, unsigned char c) +{ + pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; + if (port->lsr & LSR_THE) { +// Transmit buffer is empty + port->thr = c; + return true; + } else { +// No space + return false; + } +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +pid_serial_getc(serial_channel *chan) +{ + unsigned char c; + pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; + while ((port->lsr & LSR_RSR) == 0) ; // Wait for char + c = port->rhr; + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +pid_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return pid_serial_config_port(chan, config, false); +} + +// Enable the transmitter on the device +static void +pid_serial_start_xmit(serial_channel *chan) +{ + pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; + port->ier |= IER_XMT; // Enable xmit interrupt +} + +// Disable the transmitter on the device +static void +pid_serial_stop_xmit(serial_channel *chan) +{ + pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; + port->ier &= ~IER_XMT; // Disable xmit interrupt +} + +// Serial I/O - low level interrupt handler (ISR) +static cyg_uint32 +pid_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(pid_chan->int_num); + cyg_drv_interrupt_acknowledge(pid_chan->int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level interrupt handler (DSR) +static void +pid_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; + unsigned char isr; + while ((isr = port->isr & 0x0E) != 0) { + if (isr == ISR_Tx) { + (chan->callbacks->xmt_char)(chan); + } else if (isr == ISR_RxTO) { + (chan->callbacks->rcv_char)(chan, port->rhr); + } else if (isr == ISR_Rx) { + (chan->callbacks->rcv_char)(chan, port->rhr); + } + } + cyg_drv_interrupt_unmask(pid_chan->int_num); +} +#endif diff --git a/packages/devs/serial/i386/pc/current/ChangeLog b/packages/devs/serial/i386/pc/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/i386/pc/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_i386_pc.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/i386/pc/current/cdl/ser_i386_pc.cdl b/packages/devs/serial/i386/pc/current/cdl/ser_i386_pc.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/i386/pc/current/cdl/ser_i386_pc.cdl @@ -0,0 +1,232 @@ +# ==================================================================== +# +# ser_i386_pc.cdl +# +# eCos serial PC configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): nickg +# Original data: gthomas, jskov, pjo +# Contributors: +# Date: 2000-02-14 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_I386_PC { + display "PC serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_I386_PC + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + PC." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a pc_serial.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_I386_PC_SERIAL0 { + display "PC serial port 0 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for port 0 on the + PC." + + cdl_option CYGDAT_IO_SERIAL_I386_PC_SERIAL0_NAME { + display "Device name for PC serial port 0" + flavor data + default_value {"\"/dev/ser0\""} + description " + This option specifies the device name port 0 on the PC." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BAUD { + display "Baud rate for the PC serial port 0 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + PC port 0." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE { + display "Buffer size for the PC serial port 0 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the PC port 0." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IOBASE { + display "I/O base address for the i386-PC serial port 0" + flavor data + legal_values 0 to 0xFF8 + default_value 0x3F8 + description " + This option specifies the I/O address of the 8250 or 16550 for serial port 0." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IRQ { + display "IRQ for the i386-PC serial port 0" + flavor data + legal_values 0 to 15 + default_value 4 + description " + This option specifies the IRQ of the 8250 or 16550 for serial port 0." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_INT { + display "IRQ for the i386-PC serial port 0" + flavor data + legal_values 32 to 47 + default_value { CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IRQ + 32 } + description " + This option specifies the interrupt vector of the 8250 or 16550 for serial port 0." + } +} + +cdl_component CYGPKG_IO_SERIAL_I386_PC_SERIAL1 { + display "PC serial port 1 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for port 1 on + the PC." + + cdl_option CYGDAT_IO_SERIAL_I386_PC_SERIAL1_NAME { + display "Device name for PC serial port 1" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the device name port 1 on the PC." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BAUD { + display "Baud rate for the PC serial port 1 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + PC port 1." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE { + display "Buffer size for the PC serial port 1 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the PC port 1." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IOBASE { + display "I/O base address for the i386-PC serial port 1" + flavor data + legal_values 0 to 0xFF8 + default_value 0x2F8 + description " + This option specifies the I/O address of the 8250 or 16550 for serial port 1." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IRQ { + display "IRQ for the i386-PC serial port 1" + flavor data + legal_values 0 to 15 + default_value 3 + description " + This option specifies the IRQ of the 8250 or 16550 for serial port 1." + } + + cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_INT { + display "IRQ for the i386-PC serial port 1" + flavor data + legal_values 32 to 47 + default_value { CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IRQ + 32 } + description " + This option specifies the interrupt vector of the 8250 or 16550 for serial port 1." + } +} + + cdl_component CYGPKG_IO_SERIAL_I386_PC_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_I386_PC_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_I386_PC_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_i386_pc.cdl diff --git a/packages/devs/serial/i386/pc/current/src/pc_serial.c b/packages/devs/serial/i386/pc/current/src/pc_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/i386/pc/current/src/pc_serial.c @@ -0,0 +1,399 @@ +//========================================================================== +// +// io/serial/i386/pc_serial.c +// +// i386 PC Serial I/O Interface Module (interrupt driven) +// for use with 8250s or 16550s. +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas, pjo +// Date: 1999-02-04 +// Purpose: AEB-1 Serial I/O module (interrupt driven version) +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_I386_PC + +#include "pc_serial.h" + +typedef struct pc_serial_info { + CYG_ADDRWORD base; + CYG_WORD int_num; + cyg_interrupt serial_interrupt; + cyg_handle_t serial_interrupt_handle; + enum { sNone = 0, + s8250, + s16450, + s16550, + s16550a + } deviceType ; + unsigned char _ier ; + unsigned char charsInTransmitter ; +} pc_serial_info; + +static bool pc_serial_init(struct cyg_devtab_entry *tab); +static bool pc_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo pc_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char pc_serial_getc(serial_channel *chan); +static bool pc_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void pc_serial_start_xmit(serial_channel *chan); +static void pc_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 pc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(pc_serial_funs, + pc_serial_putc, + pc_serial_getc, + pc_serial_set_config, + pc_serial_start_xmit, + pc_serial_stop_xmit + ); + +#ifdef CYGPKG_IO_SERIAL_I386_PC_SERIAL0 +static pc_serial_info pc_serial_info0 = { CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IOBASE, + CYGNUM_IO_SERIAL_I386_PC_SERIAL0_INT}; +#if CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE > 0 +static unsigned char pc_serial_out_buf0[CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE]; +static unsigned char pc_serial_in_buf0[CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(pc_serial_channel0, + pc_serial_funs, + pc_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &pc_serial_out_buf0[0], sizeof(pc_serial_out_buf0), + &pc_serial_in_buf0[0], sizeof(pc_serial_in_buf0) + ); +#else +static SERIAL_CHANNEL(pc_serial_channel0, + pc_serial_funs, + pc_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(pc_serial_io0, + CYGDAT_IO_SERIAL_I386_PC_SERIAL0_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + pc_serial_init, + pc_serial_lookup, // Serial driver may need initializing + &pc_serial_channel0 + ); +#endif // CYGPKG_IO_SERIAL_I386_PC_SERIAL0 + +#ifdef CYGPKG_IO_SERIAL_I386_PC_SERIAL1 +static pc_serial_info pc_serial_info1 = { CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IOBASE, + CYGNUM_IO_SERIAL_I386_PC_SERIAL1_INT}; +#if CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE > 0 +static unsigned char pc_serial_out_buf1[CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE]; +static unsigned char pc_serial_in_buf1[CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(pc_serial_channel1, + pc_serial_funs, + pc_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &pc_serial_out_buf1[0], sizeof(pc_serial_out_buf1), + &pc_serial_in_buf1[0], sizeof(pc_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(pc_serial_channel1, + pc_serial_funs, + pc_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(pc_serial_io1, + CYGDAT_IO_SERIAL_I386_PC_SERIAL1_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + pc_serial_init, + pc_serial_lookup, // Serial driver may need initializing + &pc_serial_channel1 + ); +#endif // CYGPKG_IO_SERIAL_I386_PC_SERIAL1 + + +void pc_outb(int port, int byte) ; +int pc_inb(int port) ; + + +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool pc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + pc_serial_info * port = (pc_serial_info *) chan->dev_priv; + unsigned short baud_divisor = select_baud[new_config->baud]; + unsigned char _lcr ; + if (baud_divisor == 0) return false; + +// Initialize the device, if necessary. First, find out what kind of device +// it is. Use a while() loop so that we can break to the next statement; +// otherwise we'd have an avalanche of if/else, which can become very +// difficult to understand. + while (init) + { port->deviceType = sNone ; + pc_outb(port->base + MCR, MCR_LOOP) ; + if (pc_inb(port->base + MSR) & 0xF0) + break ; + pc_outb(port->base + MCR, MCR_LOOP | 0xF) ; + if ((pc_inb(port->base + MSR) & 0xF0) != 0xF0) + break; +// So we have at least an 8250. + pc_outb(port->base + MCR, 0x00) ; + port->deviceType = s8250 ; +// Check for a scratch register; scratch register indicates 16450 or above. + pc_outb(port->base + SCR, 0x55) ; + if (pc_inb(port->base + SCR) != 0x55) + break ; + pc_outb(port->base + SCR, 0xAA) ; + if (pc_inb(port->base + SCR) != 0xAA) + break; +// Check for a FIFO + pc_outb(port->base + FCR, FCR_FE) ; + if ((pc_inb(port->base + ISR) & 0x80) == 0) + break ; + port->deviceType = s16550 ; // Note! 16550 fifo's don't work! + if ((pc_inb(port->base + ISR) & 0x40) == 0) + break ; + port->deviceType = s16550a ; // But 16550A fifos do. + break; + } + + port->_ier = pc_inb(port->base + IER); + pc_outb(port->base + IER, 0) ; // Disable port interrupts while changing hardware + _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | + select_stop_bits[new_config->stop] | + select_parity[new_config->parity]; + pc_outb(port->base + LCR, _lcr | LCR_DL) ; + pc_outb(port->base + MDL, baud_divisor >> 8) ; + pc_outb(port->base + LDL, baud_divisor & 0xFF) ; + pc_outb(port->base + LCR, _lcr) ; + + if (init) + { if (port->deviceType == s16550a) + pc_outb(port->base + FCR, FCR_FE | FCR_RFR | FCR_TFR | FCR_RT14); + else + pc_outb(port->base + FCR, 0); + + if (chan->out_cbuf.len != 0) + pc_outb(port->base + IER, IER_RCV) ; + else + pc_outb(port->base + IER, 0) ; +// port->_ier = MCR_INT | MCR_DTR | MCR_RTS ; +// port->_ier = IER_RCV | IER_LS | IER_MS ; + pc_outb(port->base + MCR, MCR_INT | MCR_DTR | MCR_RTS) ; + port->_ier = IER_RCV ; + } + + pc_outb(port->base + IER, port->_ier) ; + + if (new_config != &chan->config) + chan->config = *new_config; + + return true; +} + + + +// Function to initialize the device. Called at bootstrap time. +static bool pc_serial_init(struct cyg_devtab_entry * tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + pc_serial_info *pc_chan = (pc_serial_info *)chan->dev_priv; +#ifdef CYGDBG_IO_INIT + diag_printf("I386_PC SERIAL init - dev: %x.%d\n", pc_chan->base, pc_chan->int_num); +#endif + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (chan->out_cbuf.len != 0) { + cyg_drv_interrupt_create(pc_chan->int_num, + 99, // Priority - unused + (cyg_addrword_t)chan, // Data item passed to interrupt handler + pc_serial_ISR, + pc_serial_DSR, + &pc_chan->serial_interrupt_handle, + &pc_chan->serial_interrupt); + cyg_drv_interrupt_attach(pc_chan->serial_interrupt_handle); + cyg_drv_interrupt_unmask(pc_chan->int_num); + } + pc_serial_config_port(chan, &chan->config, true); + return true; +} + + + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo pc_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + + + + + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device, return 'false' when +// we've ran out of buffer space in the device itself. +static bool pc_serial_putc(serial_channel *chan, unsigned char c) +{ + int x = 0 ; + + pc_serial_info * port = (pc_serial_info *)chan->dev_priv; + +#if 0 +// Make sure the transmitter is empty. + if ((pc_inb(port->base + LSR) & LSR_THE) == 0) + return false ; +#else + // There isn't a status for FIFO "not full" from the '550, so we have to + // keep track of it ourselves. + if ((pc_inb(port->base + LSR) & LSR_THE) == 0) + { if ((port->deviceType == s16550a) && + (port->charsInTransmitter++ < PC16550_FIFO_TX_LENGTH)) + { /* We're cool to keep sending characters. */ + } + else + return false ; + } +#endif + pc_outb(port->base + THR, c); + + return true ; +} + + + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char pc_serial_getc(serial_channel *chan) +{ + pc_serial_info * port = (pc_serial_info *)chan->dev_priv; + + while ((pc_inb(port->base + LSR) & LSR_RSR) == 0) + ; + + return pc_inb(port->base + RHR) ; +} + + + +// Set up the device characteristics; baud rate, etc. +static bool pc_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return pc_serial_config_port(chan, config, false); +} + + + +// Enable the transmitter on the device +static void pc_serial_start_xmit(serial_channel *chan) +{ + pc_serial_info * port = (pc_serial_info *) chan->dev_priv; + pc_outb(port->base + IER, port->_ier |= IER_XMT) ; +} + + + +// Disable the transmitter on the device +static void pc_serial_stop_xmit(serial_channel * chan) +{ pc_serial_info * port = (pc_serial_info *) chan->dev_priv; + pc_outb(port->base + IER, port->_ier &= ~IER_XMT) ; +} + + + +// Serial I/O - low level interrupt handler (ISR) +static cyg_uint32 pc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *) data; + pc_serial_info * port = (pc_serial_info *) chan->dev_priv; + cyg_drv_interrupt_mask(port->int_num); + cyg_drv_interrupt_acknowledge(port->int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + + + +// Serial I/O - high level interrupt handler (DSR) +static void pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + pc_serial_info *port = (pc_serial_info *)chan->dev_priv; + unsigned char isr; + isr = pc_inb(port->base + ISR) & 0x0E; + if (isr == ISR_Tx) + { port->charsInTransmitter = 0 ; + (chan->callbacks->xmt_char)(chan); + } else if (isr == ISR_Rx) + { + // If we've got s16550a, then read all the characters in the fifo. + while (pc_inb(port->base + LSR) & LSR_RSR) + { + char c = pc_inb(port->base + RHR); + (chan->callbacks->rcv_char)(chan, c); + } + } + cyg_drv_interrupt_unmask(port->int_num); +} +#endif diff --git a/packages/devs/serial/i386/pc/current/src/pc_serial.h b/packages/devs/serial/i386/pc/current/src/pc_serial.h new file mode 100644 --- /dev/null +++ b/packages/devs/serial/i386/pc/current/src/pc_serial.h @@ -0,0 +1,164 @@ +#ifndef CYGONCE_I386_PC_SERIAL_H +#define CYGONCE_I386_PC_SERIAL_H + +// ==================================================================== +// +// pc_serial.h +// +// Device I/O - Description of i386/PC 8250/16550 serial hardware +// +// ==================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +// ==================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas, pjo +// Date: 1999-02-04 +// Purpose: Internal interfaces for serial I/O drivers +// Description: +// +//####DESCRIPTIONEND#### +// +// ==================================================================== + +// Description of serial ports on i386/PC 8250/16550 + + +// Receive control registers +#define RHR 0 // Receive holding register +#define ISR 2 // Interrupt status register +#define LSR 5 // Line status register +#define MSR 6 // Modem status register +#define SCR 7 // Scratch register + +// Transmit control registers +#define THR 0 // Transmit holding register +#define IER 1 // Interrupt enable register +#define FCR 2 // FIFO control register +#define LCR 3 // Line control register +#define MCR 4 // Modem control register +#define LDL 0 // LSB of baud rate +#define MDL 1 // MSB of baud rate + +// Interrupt Enable Register +#define IER_RCV 0x01 +#define IER_XMT 0x02 +#define IER_LS 0x04 +#define IER_MS 0x08 + +// Line Control Register +#define LCR_WL5 0x00 // Word length +#define LCR_WL6 0x01 +#define LCR_WL7 0x02 +#define LCR_WL8 0x03 +#define LCR_SB1 0x00 // Number of stop bits +#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words +#define LCR_SB2 0x04 +#define LCR_PN 0x00 // Parity mode - none +#define LCR_PE 0x0C // Parity mode - even +#define LCR_PO 0x08 // Parity mode - odd +#define LCR_PM 0x28 // Forced "mark" parity +#define LCR_PS 0x38 // Forced "space" parity +#define LCR_DL 0x80 // Enable baud rate latch + +// Line Status Register +#define LSR_RSR 0x01 +#define LSR_THE 0x20 + +// Modem Control Register +#define MCR_DTR 0x01 +#define MCR_RTS 0x02 +#define MCR_INT 0x0C // Enable interrupts +#define MCR_LOOP 0x10 // Loopback mode. + + +// FIFO control register +#define FCR_FE 0x01 // Fifo enable +#define FCR_RFR 0x02 // Receiver fifo reset +#define FCR_TFR 0x04 // Transmitter fifo reset +#define FCR_RT14 0xC0 +#define FCR_RT8 0x80 +#define FCR_RT4 0x40 +#define FCR_RT1 0x00 + +// FIFO lengths +#define PC16550_FIFO_TX_LENGTH (16 /*only for s16550a*/) +#define PC16550_FIFO_RX_LENGTH (16 /*only for s16550a*/) + +// Interrupt status register +#define ISR_Tx 0x02 +#define ISR_Rx 0x04 + +static unsigned char select_word_length[] = { + LCR_WL5, // 5 bits / word (char) + LCR_WL6, + LCR_WL7, + LCR_WL8 +}; + +static unsigned char select_stop_bits[] = { + 0, + LCR_SB1, // 1 stop bit + LCR_SB1_5, // 1.5 stop bit + LCR_SB2 // 2 stop bits +}; + +static unsigned char select_parity[] = { + LCR_PN, // No parity + LCR_PE, // Even parity + LCR_PO, // Odd parity + LCR_PM, // Mark parity + LCR_PS, // Space parity +}; + +// Baud rate values, based on raw 24MHz clock + +static unsigned short select_baud[] = { + 0, // Unused + 2304, // 50 + 1536, // 75 + 1047, // 110 + 857, // 134.5 + 768, // 150 + 576, // 200 + 384, // 300 + 192, // 600 + 96, // 1200 + 64, // 1800 + 48, // 2400 + 32, // 3600 + 24, // 4800 + 16, // 7200 + 12, // 9600 + 8, // 14400 + 6, // 19200 + 3, // 38400 + 2, // 57600 + 1, // 115200 + 0, // 230400 +}; + +#endif // CYGONCE_I386_PC_SERIAL_H diff --git a/packages/devs/serial/mips/jmr3904/current/ChangeLog b/packages/devs/serial/mips/jmr3904/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mips/jmr3904/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_mips_jmr3904.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/mips/jmr3904/current/cdl/ser_mips_jmr3904.cdl b/packages/devs/serial/mips/jmr3904/current/cdl/ser_mips_jmr3904.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mips/jmr3904/current/cdl/ser_mips_jmr3904.cdl @@ -0,0 +1,188 @@ +# ==================================================================== +# +# ser_mips_jmr3904.cdl +# +# eCos serial MIPS/JMR3904 configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-14 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_TX39_JMR3904 { + display "TX39 JMR3904 serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_MIPS_TX39_JMR3904 + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + TX39 JMR3904." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a tx3904_serial.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +# FIXME: Bad name +cdl_option CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE { + display "TX39 JMR3904 polled mode serial drivers" + flavor bool + default_value 0 + description " + If asserted, this option specifies that the serial device + drivers for the TX39 JMR3904 should be polled-mode instead of + interrupt driven." +} + +cdl_component CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 { + display "TX39 JMR3904 serial port 0 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for port 0 on the + TX39 JMR3904." + + cdl_option CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL0_NAME { + display "Device name for TX39 JMR3904 serial port 0" + flavor data + default_value {"\"/dev/ser0\""} + description " + This option specifies the device name port 0 on the TX39 JMR3904." + } + + cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BAUD { + display "Baud rate for the TX39 JMR3904 serial port 0 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + TX39 JMR3904 port 0." + } + + cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE { + display "Buffer size for the TX39 JMR3904 serial port 0 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the TX39 JMR3904 port 0." + } +} +cdl_component CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 { + display "TX39 JMR3904 serial port 1 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for port 1 on + the TX39 JMR3904." + + cdl_option CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL1_NAME { + display "Device name for TX39 JMR3904 serial port 1" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the device name port 1 on the TX39 JMR3904." + } + + cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BAUD { + display "Baud rate for the TX39 JMR3904 serial port 1 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + TX39 JMR3904 port 1." + } + + cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE { + display "Buffer size for the TX39 JMR3904 serial port 1 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the TX39 JMR3904 port 1." + } +} + + cdl_component CYGPKG_IO_SERIAL_MIPS_JMR3904_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_MIPS_JMR3904_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_MIPS_JMR3904_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_mips_jmr3904.cdl diff --git a/packages/devs/serial/mips/jmr3904/current/src/tx3904_serial.c b/packages/devs/serial/mips/jmr3904/current/src/tx3904_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mips/jmr3904/current/src/tx3904_serial.c @@ -0,0 +1,731 @@ +//========================================================================== +// +// tx3904_serial.c +// +// Serial device driver for TX3904 on-chip serial devices +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributors: nickg +// Date: 1999-03-3 +// Purpose: TX3904 serial device driver +// Description: TX3904 serial device driver +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904 + +cyg_bool cyg_hal_is_break(char *buf, int size); +void cyg_hal_user_break( CYG_ADDRWORD *regs ); + +//------------------------------------------------------------------------- + +extern void diag_printf(const char *fmt, ...); + +//------------------------------------------------------------------------- +// Forward definitions + +static bool tx3904_serial_init(struct cyg_devtab_entry *tab); +static bool tx3904_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo tx3904_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char tx3904_serial_getc(serial_channel *chan); +static bool tx3904_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void tx3904_serial_start_xmit(serial_channel *chan); +static void tx3904_serial_stop_xmit(serial_channel *chan); + +#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE +static cyg_uint32 tx3904_serial_ISR(cyg_vector_t vector, cyg_addrword_t data, cyg_addrword_t *regs); +static void tx3904_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); +#endif + + +//------------------------------------------------------------------------- +// TX3904 serial line control register values: + +// Offsets to serial control registers from base +#define SERIAL_CR 0x00 +#define SERIAL_SR 0x04 +#define SERIAL_ICR 0x08 +#define SERIAL_ISR 0x0C +#define SERIAL_FCR 0x10 +#define SERIAL_BRG 0x14 +#define SERIAL_TXB 0x20 +#define SERIAL_RXB 0x30 + +// Status register bits +#define ISR_RXRDY 0x01 +#define ISR_TXRDY 0x02 +#define ISR_ERROR 0x04 + +// Control register bits +#define LCR_SB1 0x0000 +#define LCR_SB1_5 0x0000 +#define LCR_SB2 0x0004 +#define LCR_PN 0x0000 // Parity mode - none +#define LCR_PS 0x0000 // Forced "space" parity +#define LCR_PM 0x0000 // Forced "mark" parity +#define LCR_PE 0x0018 // Parity mode - even +#define LCR_PO 0x0010 // Parity mode - odd +#define LCR_WL5 0x0001 // not supported - use 7bit +#define LCR_WL6 0x0001 // not supported - use 7bit +#define LCR_WL7 0x0001 // 7 bit chars +#define LCR_WL8 0x0000 // 8 bit chars + +#define LCR_BRG 0x0020 // Select baud rate generator + +#define ICR_RXE 0x0001 // receive enable +#define ICR_TXE 0x0002 // transmit enable + +//------------------------------------------------------------------------- +// Tables to map input values to hardware settings + +static unsigned char select_word_length[] = { + LCR_WL5, // 5 bits / word (char) + LCR_WL6, + LCR_WL7, + LCR_WL8 +}; + +static unsigned char select_stop_bits[] = { + 0, + LCR_SB1, // 1 stop bit + LCR_SB1_5, // 1.5 stop bit + LCR_SB2 // 2 stop bits +}; + +static unsigned char select_parity[] = { + LCR_PN, // No parity + LCR_PE, // Even parity + LCR_PO, // Odd parity + LCR_PM, // Mark parity + LCR_PS, // Space parity +}; + +// The values in this table plug straight into the BRG register +// in the serial driver hardware. They comprise a baud rate divisor +// in the bottom 8 bits and a clock selector in the top 8 bits. +// These figures all come from Toshiba. + +#if (CYGHWR_HAL_MIPS_CPU_FREQ == 50) + +static unsigned short select_baud[] = { + 0, // Unused + 0, // 50 + 0, // 75 + 0, // 110 + 0, // 134.5 + 0, // 150 + 0, // 200 + 0, // 300 + 0x0300|20, // 600 + 0x0300|10, // 1200 + 0, // 1800 + 0x0300|05, // 2400 + 0, // 3600 + 0x0300|10, // 4800 + 0, // 7200 + 0x0200|05, // 9600 + 0, // 14400 + 0x0100|10, // 19200 + 0x0100|05, // 38400 + 0, // 57600 + 0, // 115200 + 0, // 230400 +}; + +#elif (CYGHWR_HAL_MIPS_CPU_FREQ == 66) + +static unsigned short select_baud[] = { + 0, // Unused + 0, // 50 + 0, // 75 + 0, // 110 + 0, // 134.5 + 0, // 150 + 0, // 200 + 0, // 300 + 0x0300|27, // 600 + 0x0200|54, // 1200 + 0, // 1800 + 0x0200|27, // 2400 + 0, // 3600 + 0x0100|54, // 4800 + 0, // 7200 + 0x0100|27, // 9600 + 0, // 14400 + 0x0000|54, // 19200 + 0x0000|27, // 38400 + 0, // 57600 + 0, // 115200 + 0, // 230400 +}; + +#else + +#error Unsupported CPU frequency + +#endif + +//------------------------------------------------------------------------- +// Info for each serial device controlled + +typedef struct tx3904_serial_info { + CYG_ADDRWORD base; + CYG_WORD int_num; + cyg_interrupt interrupt; + cyg_handle_t interrupt_handle; + cyg_uint8 input_char; + cyg_bool input_char_valid; + cyg_bool output_ready; + cyg_uint16 cur_baud; +} tx3904_serial_info; + +//------------------------------------------------------------------------- +// Callback functions exported by this driver + +static SERIAL_FUNS(tx3904_serial_funs, + tx3904_serial_putc, + tx3904_serial_getc, + tx3904_serial_set_config, + tx3904_serial_start_xmit, + tx3904_serial_stop_xmit + ); + +//------------------------------------------------------------------------- +// Hardware info for each serial line + +#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 +static tx3904_serial_info tx3904_serial_info0 = { + 0xFFFFF300, + CYGNUM_HAL_INTERRUPT_SIO_0 +}; +#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE > 0 +static unsigned char tx3904_serial_out_buf0[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE]; +static unsigned char tx3904_serial_in_buf0[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE]; +#endif +#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 + +#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 +static tx3904_serial_info tx3904_serial_info1 = { + 0xFFFFF400, + CYGNUM_HAL_INTERRUPT_SIO_1 +}; +#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE > 0 +static unsigned char tx3904_serial_out_buf1[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE]; +static unsigned char tx3904_serial_in_buf1[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE]; +#endif +#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 + +//------------------------------------------------------------------------- +// Channel descriptions: + +#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE +#define SIZEOF_BUF(_x_) 0 +#else +#define SIZEOF_BUF(_x_) sizeof(_x_) +#endif + +#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 +#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE > 0 +static SERIAL_CHANNEL_USING_INTERRUPTS(tx3904_serial_channel0, + tx3904_serial_funs, + tx3904_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &tx3904_serial_out_buf0[0], + SIZEOF_BUF(tx3904_serial_out_buf0), + &tx3904_serial_in_buf0[0], + SIZEOF_BUF(tx3904_serial_in_buf0) + ); +#else +static SERIAL_CHANNEL(tx3904_serial_channel0, + tx3904_serial_funs, + tx3904_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif +#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 + +#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 +#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE > 0 +static SERIAL_CHANNEL_USING_INTERRUPTS(tx3904_serial_channel1, + tx3904_serial_funs, + tx3904_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &tx3904_serial_out_buf1[0], + SIZEOF_BUF(tx3904_serial_out_buf1), + &tx3904_serial_in_buf1[0], + SIZEOF_BUF(tx3904_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(tx3904_serial_channel1, + tx3904_serial_funs, + tx3904_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif +#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 + +//------------------------------------------------------------------------- +// And finally, the device table entries: + +#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 +DEVTAB_ENTRY(tx3904_serial_io0, + CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL0_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + tx3904_serial_init, + tx3904_serial_lookup, // Serial driver may need initializing + &tx3904_serial_channel0 + ); +#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 + +#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 +DEVTAB_ENTRY(tx3904_serial_io1, + CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL1_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + tx3904_serial_init, + tx3904_serial_lookup, // Serial driver may need initializing + &tx3904_serial_channel1 + ); +#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 + +// ------------------------------------------------------------------------ +// Delay for some number of character times. This is based on the baud +// rate currently set. We use the numbers that plug in to the BRG +// clock select and divider to control two loops. The innermost delay +// loop uses a count that is derived from dividing the CPU frequency +// by the BRG granularity (and we then add 1 to compensate for any +// rounding). This gives the number of cycles that the innermost loop +// must consume. For the sake of simplicity we assume that this loop +// will take 1 cycle per loop, which is roughly true in optimized +// code. + +void delay_char_time(tx3904_serial_info *tx3904_chan, int n) +{ + static cyg_uint16 clock_val[4] = { 4, 16, 64, 256 }; + cyg_uint16 baud_val = select_baud[tx3904_chan->cur_baud]; + cyg_count32 clock_loop = clock_val[baud_val>>8]; + cyg_count32 div_loop = baud_val & 0xFF; + cyg_count32 bit_time = ((CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL)/(2457600)) + 1; + + n *= 11; // allow for start and stop bits and 8 data bits + + while( n-- ) + { + cyg_count32 i,j,k; + + for( i = 0; i < clock_loop; i++ ) + for( j = 0; j < div_loop; j++ ) + for( k = 0; k < bit_time; k++ ) + continue; + } +} + +//------------------------------------------------------------------------- + +static bool +tx3904_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; + cyg_uint16 cr = 0; + cyg_uint16 icr = 0; + cyg_uint16 baud_divisor = select_baud[new_config->baud]; + + if (baud_divisor == 0) + return false; // Invalid baud rate selected + + // set up other config values: + + cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; + cr |= select_stop_bits[new_config->stop]; + cr |= select_parity[new_config->parity]; + + // Source transfer clock from BRG + cr |= LCR_BRG; + +#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE + // Enable RX interrupts only at present +#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 + if ((chan->out_cbuf.len != 0) || (chan == &tx3904_serial_channel0)) { +#else + if (chan->out_cbuf.len != 0) { +#endif + icr |= ICR_RXE; + } +#endif + + // Avoid any interrupts while we are fiddling with the line parameters. + cyg_drv_interrupt_mask(tx3904_chan->int_num); + + + // In theory we should wait here for the transmitter to drain the + // FIFO so we dont change the line parameters with characters + // unsent. Unfortunately the TX39 serial devices do not allow us + // to discover when the FIFO is empty. + + delay_char_time(tx3904_chan, 8); + + // Disable device entirely. +// HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_CR, 0); +// HAL_WRITE_UINT8(tx3904_chan->base+SERIAL_ICR, 0); + + // Reset the FIFOs + + HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_FCR, 7); + HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_FCR, 0); + + // Set up baud rate + + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_BRG, baud_divisor ); + + // Write CR into hardware + HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_CR, cr); + + // Write ICR into hardware + HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_ICR, icr); + + // Re-enable interrupts. + cyg_drv_interrupt_unmask(tx3904_chan->int_num); + + // Save current baud rate + tx3904_chan->cur_baud = new_config->baud; + + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +//------------------------------------------------------------------------- +// Function to initialize the device. Called at bootstrap time. + +bool tx3904_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; + + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + + tx3904_chan->cur_baud = CYGNUM_SERIAL_BAUD_38400; + +#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE + if (chan->out_cbuf.len != 0) { + // Install and enable the interrupt + cyg_drv_interrupt_create(tx3904_chan->int_num, + 4, // Priority + (cyg_addrword_t)chan, // Data item passed to interrupt handler + (cyg_ISR_t *)tx3904_serial_ISR, + tx3904_serial_DSR, + &tx3904_chan->interrupt_handle, + &tx3904_chan->interrupt); + cyg_drv_interrupt_attach(tx3904_chan->interrupt_handle); + cyg_drv_interrupt_unmask(tx3904_chan->int_num); + } +#endif + + tx3904_serial_config_port(chan, &chan->config, true); + + return true; +} + +//------------------------------------------------------------------------- +// This routine is called when the device is "looked" up (i.e. attached) + +static Cyg_ErrNo +tx3904_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +//------------------------------------------------------------------------- +// Return 'true' if character is sent to device + +bool +tx3904_serial_putc(serial_channel *chan, unsigned char c) +{ + tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; + cyg_uint16 isr; + + HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + + if( isr & ISR_TXRDY ) + { + HAL_WRITE_UINT8( tx3904_chan->base+SERIAL_TXB, c ); + + isr &= ~ISR_TXRDY; + + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + + return true; + } + else return false; +} + +//------------------------------------------------------------------------- + +unsigned char +tx3904_serial_getc(serial_channel *chan) +{ + unsigned char c; + tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; + cyg_uint16 isr; + + do + { + HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + + // Eliminate any RX errors + if( isr & ISR_ERROR ) + { + cyg_uint16 sr = 0; + + isr &= ISR_ERROR; + +// HAL_READ_UINT16( tx3904_chan->base+SERIAL_SR, sr ); + + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_SR, sr ); + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + } + + } while( (isr & ISR_RXRDY) != ISR_RXRDY ); + + HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, c ); + + isr &= ~ISR_RXRDY; + + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + + return c; +} + +//------------------------------------------------------------------------- + +bool +tx3904_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return tx3904_serial_config_port(chan, config, false); +} + +//------------------------------------------------------------------------- +// Enable the transmitter on the device + +static void +tx3904_serial_start_xmit(serial_channel *chan) +{ +#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE + tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; + cyg_uint16 icr; + + HAL_READ_UINT16( tx3904_chan->base+SERIAL_ICR, icr ); + + icr |= ICR_TXE; + + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ICR, icr ); +#endif +} + +//------------------------------------------------------------------------- +// Disable the transmitter on the device + +static void +tx3904_serial_stop_xmit(serial_channel *chan) +{ +#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE + tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; + cyg_uint16 icr; + + HAL_READ_UINT16( tx3904_chan->base+SERIAL_ICR, icr ); + + icr &= ~ICR_TXE; + + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ICR, icr ); +#endif +} + +//------------------------------------------------------------------------- +// Serial I/O - low level interrupt handlers (ISR) + +#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE + +static cyg_uint32 +tx3904_serial_ISR(cyg_vector_t vector, cyg_addrword_t data, cyg_addrword_t *regs) +{ + serial_channel *chan = (serial_channel *)data; + tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; + cyg_uint8 isr; + cyg_uint32 result = 0; + + cyg_drv_interrupt_mask(tx3904_chan->int_num); + cyg_drv_interrupt_acknowledge(tx3904_chan->int_num); + + HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + + // Eliminate any RX errors + if( isr & ISR_ERROR ) + { + cyg_uint16 sr = 0; + + isr &= ~ISR_ERROR; + + HAL_READ_UINT16( tx3904_chan->base+SERIAL_SR, sr ); + + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_SR, 0 ); + } + + // Check for a TX interrupt and set the flag if so. + if( isr & ISR_TXRDY ) + { + isr &= ~ISR_TXRDY; + + tx3904_chan->output_ready = true; + + result |= CYG_ISR_CALL_DSR; // Cause DSR to be run + } + + + // Check here for an RX interrupt and fetch the character. If it + // is a ^C then call into GDB stub to handle it. + + if( isr & ISR_RXRDY ) + { + cyg_uint8 rxb; + HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, rxb ); + + isr &= ~ISR_RXRDY; + + if( cyg_hal_is_break( &rxb , 1 ) ) + cyg_hal_user_break( regs ); + else + { + tx3904_chan->input_char = rxb; + tx3904_chan->input_char_valid = true; + result |= CYG_ISR_CALL_DSR; // Cause DSR to be run + } + + } + + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + + return result; +} + + +#endif + +//------------------------------------------------------------------------- +// Serial I/O - high level interrupt handler (DSR) + +#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE + +static void +tx3904_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; + cyg_uint8 isr; + + HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + + if( tx3904_chan->input_char_valid ) + { + (chan->callbacks->rcv_char)(chan, tx3904_chan->input_char); + + tx3904_chan->input_char_valid = false; + +#if 0 + // And while we are here, pull any further characters out of the + // FIFO. This should help to reduce the interrupt rate. + + HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + + while( isr & ISR_RXRDY ) + { + cyg_uint8 rxb; + HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, rxb ); + + (chan->callbacks->rcv_char)(chan, rxb); + + isr &= ~ISR_RXRDY; + + HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); + } +#endif + + } + + if( tx3904_chan->output_ready ) + { + (chan->callbacks->xmt_char)(chan); + + tx3904_chan->output_ready = false; + } + + cyg_drv_interrupt_unmask(tx3904_chan->int_num); +} + +#endif +#endif // CYGPKG_IO_SERIAL_TX39_JMR3904 + +//------------------------------------------------------------------------- +// EOF tx3904_serial.c diff --git a/packages/devs/serial/mips/vrc4373/current/ChangeLog b/packages/devs/serial/mips/vrc4373/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mips/vrc4373/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_mips_vrc4373.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/mips/vrc4373/current/cdl/ser_mips_vrc4373.cdl b/packages/devs/serial/mips/vrc4373/current/cdl/ser_mips_vrc4373.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mips/vrc4373/current/cdl/ser_mips_vrc4373.cdl @@ -0,0 +1,177 @@ +# ==================================================================== +# +# ser_mips_vrc4373.cdl +# +# eCos serial MIPS/VRC4373 configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-14 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_MIPS_VRC4373 { + display "VRC4373 serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_MIPS_VR4300_VRC4373 + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + VRC4373." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a vrc4373_serial.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL0 { + display "VRC4373 serial port 0 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the VRC4373 port 0." + + cdl_option CYGDAT_IO_SERIAL_MIPS_VRC4373_SERIAL0_NAME { + display "Device name for the VRC4373 serial port 0 driver" + flavor data + default_value {"\"/dev/ser0\""} + description " + This option sets the name of the serial device for the VRC4373 + port 0." + } + + cdl_option CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BAUD { + display "Baud rate for the VRC4373 serial port 0 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 9600 + description " + This option specifies the default baud rate (speed) for the + VRC4373 port 0." + } + + cdl_option CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BUFSIZE { + display "Buffer size for the VRC4373 serial port 0 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the VRC4373 port 0." + } +} +cdl_component CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL1 { + display "VRC4373 serial port 1 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the VRC4373 port 1." + + cdl_option CYGDAT_IO_SERIAL_MIPS_VRC4373_SERIAL1_NAME { + display "Device name for the VRC4373 serial port 1 driver" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the name of serial device for the + VRC4373 port 1." + } + + cdl_option CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BAUD { + display "Baud rate for the VRC4373 serial port 1 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 9600 + description " + This option specifies the default baud rate (speed) for the + VRC4373 port 1." + } + + cdl_option CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BUFSIZE { + display "Buffer size for the VRC4373 serial port 1 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used for + the VRC4373 port 1." + } +} + + cdl_component CYGPKG_IO_SERIAL_MIPS_VRC4373_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_MIPS_VRC4373_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_MIPS_VRC4373_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_mips_vrc4373.cdl diff --git a/packages/devs/serial/mips/vrc4373/current/src/vrc4373_serial.c b/packages/devs/serial/mips/vrc4373/current/src/vrc4373_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mips/vrc4373/current/src/vrc4373_serial.c @@ -0,0 +1,466 @@ +//========================================================================== +// +// io/serial/mips/vrc4373_serial.c +// +// Mips VRC4373 Serial I/O Interface Module (interrupt driven) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-04-15 +// Purpose: VRC4373 Serial I/O module (interrupt driven version) +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373 + +#include "vrc4373_serial.h" + +#if defined(CYGPKG_HAL_MIPS_LSBFIRST) +#define VRC4373_SCC_BASE 0xC1000000 +#elif defined(CYGPKG_HAL_MIPS_MSBFIRST) +#define VRC4373_SCC_BASE 0xC1000003 +#else +#error MIPS endianness not defined by configuration +#endif + +#define VRC4373_SCC_INT CYGNUM_HAL_INTERRUPT_DUART +#define SCC_CHANNEL_A 4 +#define SCC_CHANNEL_B 0 + +extern void diag_printf(const char *fmt, ...); + +typedef struct vrc4373_serial_info { + CYG_ADDRWORD base; + unsigned char regs[16]; // Known register state (since hardware is write-only!) +} vrc4373_serial_info; + +static bool vrc4373_serial_init(struct cyg_devtab_entry *tab); +static bool vrc4373_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo vrc4373_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char vrc4373_serial_getc(serial_channel *chan); +static bool vrc4373_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void vrc4373_serial_start_xmit(serial_channel *chan); +static void vrc4373_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 vrc4373_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void vrc4373_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(vrc4373_serial_funs, + vrc4373_serial_putc, + vrc4373_serial_getc, + vrc4373_serial_set_config, + vrc4373_serial_start_xmit, + vrc4373_serial_stop_xmit + ); + +#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL0 +static vrc4373_serial_info vrc4373_serial_info0 = {VRC4373_SCC_BASE+SCC_CHANNEL_A}; +#if CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BUFSIZE > 0 +static unsigned char vrc4373_serial_out_buf0[CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BUFSIZE]; +static unsigned char vrc4373_serial_in_buf0[CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(vrc4373_serial_channel0, + vrc4373_serial_funs, + vrc4373_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &vrc4373_serial_out_buf0[0], sizeof(vrc4373_serial_out_buf0), + &vrc4373_serial_in_buf0[0], sizeof(vrc4373_serial_in_buf0) + ); +#else +static SERIAL_CHANNEL(vrc4373_serial_channel0, + vrc4373_serial_funs, + vrc4373_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(vrc4373_serial_io0, + CYGDAT_IO_SERIAL_MIPS_VRC4373_SERIAL0_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + vrc4373_serial_init, + vrc4373_serial_lookup, // Serial driver may need initializing + &vrc4373_serial_channel0 + ); +#endif // CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL0 + +#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL1 +static vrc4373_serial_info vrc4373_serial_info1 = {VRC4373_SCC_BASE+SCC_CHANNEL_B}; +#if CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BUFSIZE > 0 +static unsigned char vrc4373_serial_out_buf1[CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BUFSIZE]; +static unsigned char vrc4373_serial_in_buf1[CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(vrc4373_serial_channel1, + vrc4373_serial_funs, + vrc4373_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &vrc4373_serial_out_buf1[0], sizeof(vrc4373_serial_out_buf1), + &vrc4373_serial_in_buf1[0], sizeof(vrc4373_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(vrc4373_serial_channel1, + vrc4373_serial_funs, + vrc4373_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(vrc4373_serial_io1, + CYGDAT_IO_SERIAL_MIPS_VRC4373_SERIAL1_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + vrc4373_serial_init, + vrc4373_serial_lookup, // Serial driver may need initializing + &vrc4373_serial_channel1 + ); +#endif // CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL1 + +static cyg_interrupt vrc4373_serial_interrupt; +static cyg_handle_t vrc4373_serial_interrupt_handle; + +// Table which maps hardware channels (A,B) to software ones +struct serial_channel *vrc4373_chans[] = { +#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL0 // Hardware channel A + &vrc4373_serial_channel0, +#else + 0, +#endif +#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL1 // Hardware channel B + &vrc4373_serial_channel1, +#else + 0, +#endif +}; + +// Support functions which access the serial device. Note that this chip requires +// a substantial delay after each access. + +#define SCC_DELAY 100 +inline static void +scc_delay(void) +{ + int i; + for (i = 0; i < SCC_DELAY; i++) ; +} + +inline static void +scc_write_reg(volatile unsigned char *reg, unsigned char val) +{ + scc_delay(); + *reg = val; +} + +inline static unsigned char +scc_read_reg(volatile unsigned char *reg) +{ + unsigned char val; + scc_delay(); + val = *reg; + return (val); +} + +inline static unsigned char +scc_read_ctl(volatile struct serial_port *port, int reg) +{ + if (reg != 0) { + scc_write_reg(&port->scc_ctl, reg); + } + return (scc_read_reg(&port->scc_ctl)); +} + +inline static void +scc_write_ctl(volatile struct serial_port *port, int reg, unsigned char val) +{ + if (reg != 0) { + scc_write_reg(&port->scc_ctl, reg); + } + scc_write_reg(&port->scc_ctl, val); +} + +inline static unsigned char +scc_read_dat(volatile struct serial_port *port) +{ + return (scc_read_reg(&port->scc_dat)); +} + +inline static void +scc_write_dat(volatile struct serial_port *port, unsigned char val) +{ + scc_write_reg(&port->scc_dat, val); +} + +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool +vrc4373_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; + cyg_int32 baud_rate = select_baud[new_config->baud]; + cyg_int32 baud_divisor; + unsigned char *regs = &vrc4373_chan->regs[0]; + if (baud_rate == 0) return false; + // Compute state of registers. The register/control state needs to be kept in + // the shadow variable 'regs' because the hardware registers can only be written, + // not read (in general). + if (init) { + // Insert appropriate resets? + if (chan->out_cbuf.len != 0) { + regs[R1] = WR1_IntAllRx; + regs[R9] = WR9_MIE | WR9_NoVector; + } else { + regs[R1] = 0; + regs[R9] = 0; + } + // Clocks are from the baud rate generator + regs[R11] = WR11_TRxCBR | WR11_TRxCOI | WR11_TxCBR | WR11_RxCBR; + regs[R14] = WR14_BRenable | WR14_BRSRC; + regs[R10] = 0; // Unused in this [async] mode + regs[R15] = 0; + } + regs[R3] = WR3_RxEnable | select_word_length_WR3[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; + regs[R4] = WR4_X16CLK | select_stop_bits[new_config->stop] | select_parity[new_config->parity]; + regs[R5] = WR5_TxEnable | select_word_length_WR5[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; + baud_divisor = BRTC(baud_rate); + regs[R12] = baud_divisor & 0xFF; + regs[R13] = baud_divisor >> 8; + // Now load the registers + scc_write_ctl(port, R4, regs[R4]); + scc_write_ctl(port, R10, regs[R10]); + scc_write_ctl(port, R3, regs[R3] & ~WR3_RxEnable); + scc_write_ctl(port, R5, regs[R5] & ~WR5_TxEnable); + scc_write_ctl(port, R1, regs[R1]); + scc_write_ctl(port, R9, regs[R9]); + scc_write_ctl(port, R11, regs[R11]); + scc_write_ctl(port, R12, regs[R12]); + scc_write_ctl(port, R13, regs[R13]); + scc_write_ctl(port, R14, regs[R14]); + scc_write_ctl(port, R15, regs[R15]); + scc_write_ctl(port, R3, regs[R3]); + scc_write_ctl(port, R5, regs[R5]); + // Update configuration + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +vrc4373_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; + static bool init = false; +#ifdef CYGDBG_IO_INIT + diag_printf("VRC4373 SERIAL init '%s' - dev: %x\n", tab->name, vrc4373_chan->base); +#endif + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (!init && chan->out_cbuf.len != 0) { + init = true; + cyg_drv_interrupt_create(VRC4373_SCC_INT, + 99, + (cyg_addrword_t)VRC4373_SCC_BASE+SCC_CHANNEL_A, + vrc4373_serial_ISR, + vrc4373_serial_DSR, + &vrc4373_serial_interrupt_handle, + &vrc4373_serial_interrupt); + cyg_drv_interrupt_attach(vrc4373_serial_interrupt_handle); + cyg_drv_interrupt_unmask(VRC4373_SCC_INT); + } + vrc4373_serial_config_port(chan, &chan->config, true); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +vrc4373_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +vrc4373_serial_putc(serial_channel *chan, unsigned char c) +{ + vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; + if (scc_read_ctl(port, R0) & RR0_TxEmpty) { +// Transmit buffer is empty + scc_write_dat(port, c); + return true; + } else { +// No space + return false; + } +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +vrc4373_serial_getc(serial_channel *chan) +{ + unsigned char c; + vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; + while ((scc_read_ctl(port, R0) & RR0_RxAvail) == 0) ; // Wait for char + c = scc_read_dat(port); + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +vrc4373_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return vrc4373_serial_config_port(chan, config, false); +} + +// Enable the transmitter on the device +static void +vrc4373_serial_start_xmit(serial_channel *chan) +{ + vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; + if ((vrc4373_chan->regs[R1] & WR1_TxIntEnab) == 0) { + CYG_INTERRUPT_STATE old; + HAL_DISABLE_INTERRUPTS(old); + vrc4373_chan->regs[R1] |= WR1_TxIntEnab; // Enable Tx interrupt + scc_write_ctl(port, R1, vrc4373_chan->regs[R1]); + (chan->callbacks->xmt_char)(chan); // Send first character to start xmitter + HAL_RESTORE_INTERRUPTS(old); + } +} + +// Disable the transmitter on the device +static void +vrc4373_serial_stop_xmit(serial_channel *chan) +{ + vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; + if ((vrc4373_chan->regs[R1] & WR1_TxIntEnab) != 0) { + CYG_INTERRUPT_STATE old; + HAL_DISABLE_INTERRUPTS(old); + vrc4373_chan->regs[R1] &= ~WR1_TxIntEnab; // Disable Tx interrupt + scc_write_ctl(port, R1, vrc4373_chan->regs[R1]); + HAL_RESTORE_INTERRUPTS(old); + } +} + +// Serial I/O - low level interrupt handler (ISR) +static cyg_uint32 +vrc4373_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + cyg_drv_interrupt_mask(VRC4373_SCC_INT); + cyg_drv_interrupt_acknowledge(VRC4373_SCC_INT); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +inline static void +vrc4373_int(serial_channel *chan, unsigned char stat) +{ + vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; + volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; + // Note: 'stat' value is interrupt status register, shifted into "B" position + if (stat & RR3_BRxIP) { + // Receive interrupt + unsigned char c; + c = scc_read_dat(port); + (chan->callbacks->rcv_char)(chan, c); + } + if (stat & RR3_BTxIP) { + // Transmit interrupt + (chan->callbacks->xmt_char)(chan); + } + if (stat & RR3_BExt) { + // Status interrupt (parity error, framing error, etc) + } +} + +// Serial I/O - high level interrupt handler (DSR) +// Note: This device presents a single interrupt for both channels. Thus the +// interrupt handler has to query the device and decide which channel needs service. +// Additionally, more than one interrupt condition may be present so this needs to +// be done in a loop until all interrupt requests have been handled. +// Also note that the hardware is rather broken. The interrupt status needs to +// be read using only channel A (pointed to by 'data') +static void +vrc4373_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan; + volatile struct serial_port *port = (volatile struct serial_port *)data; + unsigned char stat; + while (true) { + stat = scc_read_ctl(port, R3); + if (stat & (RR3_AExt | RR3_ATxIP | RR3_ARxIP)) { + chan = vrc4373_chans[0]; // Hardware channel A + vrc4373_int(chan, stat>>3); // Handle interrupt + } else if (stat & (RR3_BExt | RR3_BTxIP | RR3_BRxIP)) { + chan = vrc4373_chans[1]; // Hardware channel A + vrc4373_int(chan, stat); // Handle interrupt + } else { + // No more interrupts, all done + break; + } + } + cyg_drv_interrupt_unmask(VRC4373_SCC_INT); +} +#endif diff --git a/packages/devs/serial/mips/vrc4373/current/src/vrc4373_serial.h b/packages/devs/serial/mips/vrc4373/current/src/vrc4373_serial.h new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mips/vrc4373/current/src/vrc4373_serial.h @@ -0,0 +1,335 @@ +#ifndef CYGONCE_MIPS_VRC4373_SERIAL_H +#define CYGONCE_MIPS_VRC4373_SERIAL_H + +// ==================================================================== +// +// aeb_serial.h +// +// Device I/O - Description of Mips VRC4373 serial hardware +// +// ==================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +// ==================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-04-15 +// Purpose: Internal interfaces for serial I/O drivers +// Description: +// +//####DESCRIPTIONEND#### +// +// ==================================================================== + +// Description of serial ports on Mips VRC4373 +// Based on Zilog 85C30 SCC + +struct serial_port { + unsigned char _byte[16]; +}; + +#define scc_ctl _byte[0] +#define scc_dat _byte[8] + +#define R0 0 /* Register selects */ +#define R1 1 +#define R2 2 +#define R3 3 +#define R4 4 +#define R5 5 +#define R6 6 +#define R7 7 +#define R8 8 +#define R9 9 +#define R10 10 +#define R11 11 +#define R12 12 +#define R13 13 +#define R14 14 +#define R15 15 + +/* Write Register 0 */ +#define WR0_NullCode 0x00 /* Null Code */ +#define WR0_PointHigh 0x08 /* Select upper half of registers */ +#define WR0_ResExtInt 0x10 /* Reset Ext. Status Interrupts */ +#define WR0_SendAbort 0x18 /* HDLC Abort */ +#define WR0_ResRxIntFC 0x20 /* Reset RxINT on First Character */ +#define WR0_ResTxP 0x28 /* Reset TxINT Pending */ +#define WR0_ErrReset 0x30 /* Error Reset */ +#define WR0_ResHiIUS 0x38 /* Reset highest IUS */ + +#define WR0_ResRxCRC 0x40 /* Reset Rx CRC Checker */ +#define WR0_ResTxCRC 0x80 /* Reset Tx CRC Checker */ +#define WR0_ResEOMlatch 0xC0 /* Reset EOM latch */ + +/* Write Register 1 */ + +#define WR1_ExtIntEnab 0x01 /* Ext Int Enable */ +#define WR1_TxIntEnab 0x02 /* Tx Int Enable */ +#define WR1_ParSpec 0x04 /* Parity is special condition */ + +#define WR1_RxIntDisab 0x00 /* Rx Int Disable */ +#define WR1_RxIntFCE 0x08 /* Rx Int on First Character Only or Error */ +#define WR1_IntAllRx 0x10 /* Int on all Rx Characters or error */ +#define WR1_IntErrRx 0x18 /* Int on error only */ + +#define WR1_WtRdyRT 0x20 /* Wait/Ready on R/T */ +#define WR1_WtFnRdyFn 0x40 /* Wait/FN/Ready FN */ +#define WR1_WtRdyEnab 0x80 /* Wait/Ready Enable */ + +/* Write Register #2 (Interrupt Vector) */ + +/* Write Register 3 */ + +#define WR3_RxEnable 0x01 /* Rx Enable */ +#define WR3_SyncInhibit 0x02 /* Sync Character Load Inhibit */ +#define WR3_AddrSearch 0x04 /* Address Search Mode (SDLC) */ +#define WR3_RxCRC_ENAB 0x08 /* Rx CRC Enable */ +#define WR3_EntHuntMode 0x10 /* Enter Hunt Mode */ +#define WR3_AutoEnab 0x20 /* Auto Enables */ +#define WR3_Rx5 0x00 /* Rx 5 Bits/Character */ +#define WR3_Rx7 0x40 /* Rx 7 Bits/Character */ +#define WR3_Rx6 0x80 /* Rx 6 Bits/Character */ +#define WR3_Rx8 0xc0 /* Rx 8 Bits/Character */ +#define WR3_RxNbitsMask 0xc0 + +/* Write Register 4 */ + +#define WR4_ParityEn 0x01 /* Parity Enable */ +#define WR4_ParityEven 0x02 /* Parity Even/Odd* */ + +#define WR4_SyncEnable 0x00 /* Sync Modes Enable */ +#define WR4_SB1 0x04 /* 1 stop bit/char */ +#define WR4_SB15 0x08 /* 1.5 stop bits/char */ +#define WR4_SB2 0x0c /* 2 stop bits/char */ +#define WR4_SB_MASK 0x0c + +#define WR4_Monsync 0x00 /* 8 Bit Sync character */ +#define WR4_Bisync 0x10 /* 16 bit sync character */ +#define WR4_SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */ +#define WR4_EXtSync 0x30 /* External Sync Mode */ + +#define WR4_X1CLK 0x00 /* x1 clock mode */ +#define WR4_X16CLK 0x40 /* x16 clock mode */ +#define WR4_X32CLK 0x80 /* x32 clock mode */ +#define WR4_X64CLK 0xC0 /* x64 clock mode */ +#define WR4_XCLK_MASK 0xC0 + +/* Write Register 5 */ + +#define WR5_TxCRCEnab 0x01 /* Tx CRC Enable */ +#define WR5_RTS 0x02 /* RTS */ +#define WR5_SDLC_CRC 0x04 /* SDLC/CRC-16 */ +#define WR5_TxEnable 0x08 /* Tx Enable */ +#define WR5_SendBreak 0x10 /* Send Break */ +#define WR5_Tx5 0x00 /* Tx 5 bits (or less)/character */ +#define WR5_Tx7 0x20 /* Tx 7 bits/character */ +#define WR5_Tx6 0x40 /* Tx 6 bits/character */ +#define WR5_Tx8 0x60 /* Tx 8 bits/character */ +#define WR5_TxNbitsMask 0x60 +#define WR5_DTR 0x80 /* DTR */ + +/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */ + +/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ + +/* Write Register 8 (transmit buffer) */ + +/* Write Register 9 (Master interrupt control) */ +#define WR9_VIS 0x01 /* Vector Includes Status */ +#define WR9_NoVector 0x02 /* No Vector */ +#define WR9_DLC 0x04 /* Disable Lower Chain */ +#define WR9_MIE 0x08 /* Master Interrupt Enable */ +#define WR9_StatHi 0x10 /* Status high */ +#define WR9_NoReset 0x00 /* No reset on write to R9 */ +#define WR9_ResetB 0x40 /* Reset channel B */ +#define WR9_ResetA 0x80 /* Reset channel A */ +#define WR9_HwReset 0xc0 /* Force hardware reset */ + +/* Write Register 10 (misc control bits) */ +#define WR10_Bit6 0x01 /* 6 bit/8bit sync */ +#define WR10_LoopMode 0x02 /* SDLC Loop mode */ +#define WR10_AbrtUnder 0x04 /* Abort/flag on SDLC xmit underrun */ +#define WR10_MarkIdle 0x08 /* Mark/flag on idle */ +#define WR10_GAOP 0x10 /* Go active on poll */ +#define WR10_NRZ 0x00 /* NRZ mode */ +#define WR10_NRZI 0x20 /* NRZI mode */ +#define WR10_FM1 0x40 /* FM1 (transition = 1) */ +#define WR10_FM0 0x60 /* FM0 (transition = 0) */ +#define WR10_CRCPS 0x80 /* CRC Preset I/O */ + +/* Write Register 11 (Clock Mode control) */ +#define WR11_TRxCXT 0x00 /* TRxC = Xtal output */ +#define WR11_TRxCTC 0x01 /* TRxC = Transmit clock */ +#define WR11_TRxCBR 0x02 /* TRxC = BR Generator Output */ +#define WR11_TRxCDP 0x03 /* TRxC = DPLL output */ +#define WR11_TRxCOI 0x04 /* TRxC O/I */ +#define WR11_TxCRTxCP 0x00 /* Transmit clock = RTxC pin */ +#define WR11_TxCTRxCP 0x08 /* Transmit clock = TRxC pin */ +#define WR11_TxCBR 0x10 /* Transmit clock = BR Generator output */ +#define WR11_TxCDPLL 0x18 /* Transmit clock = DPLL output */ +#define WR11_RxCRTxCP 0x00 /* Receive clock = RTxC pin */ +#define WR11_RxCTRxCP 0x20 /* Receive clock = TRxC pin */ +#define WR11_RxCBR 0x40 /* Receive clock = BR Generator output */ +#define WR11_RxCDPLL 0x60 /* Receive clock = DPLL output */ +#define WR11_RTxCX 0x80 /* RTxC Xtal/No Xtal */ + +/* Write Register 12 (lower byte of baud rate generator time constant) */ + +/* Write Register 13 (upper byte of baud rate generator time constant) */ + +/* Write Register 14 (Misc control bits) */ +#define WR14_BRenable 0x01 /* Baud rate generator enable */ +#define WR14_BRSRC 0x02 /* Baud rate generator source */ +#define WR14_DTRreq 0x04 /* DTR/Request function */ +#define WR14_AutoEcho 0x08 /* Auto Echo */ +#define WR14_LoopBack 0x10 /* Local loopback */ +#define WR14_Search 0x20 /* Enter search mode */ +#define WR14_RMC 0x40 /* Reset missing clock */ +#define WR14_NoDPLL 0x60 /* Disable DPLL */ +#define WR14_SSBR 0x80 /* Set DPLL source = BR generator */ +#define WR14_SSRTxC 0xa0 /* Set DPLL source = RTxC */ +#define WR14_SFMM 0xc0 /* Set FM mode */ +#define WR14_SNRZI 0xe0 /* Set NRZI mode */ + +/* Write Register 15 (external/status interrupt control) */ +#define WR15_ZCIE 0x02 /* Zero count IE */ +#define WR15_DCDIE 0x08 /* DCD IE */ +#define WR15_SYNCIE 0x10 /* Sync/hunt IE */ +#define WR15_CTSIE 0x20 /* CTS IE */ +#define WR15_TxUIE 0x40 /* Tx Underrun/EOM IE */ +#define WR15_BRKIE 0x80 /* Break/Abort IE */ + +/* Read Register 0 */ +#define RR0_RxAvail 0x01 /* Rx Character Available */ +#define RR0_Zcount 0x02 /* Zero count */ +#define RR0_TxEmpty 0x04 /* Tx Buffer empty */ +#define RR0_DCD 0x08 /* DCD */ +#define RR0_SyncHunt 0x10 /* Sync/hunt */ +#define RR0_CTS 0x20 /* CTS */ +#define RR0_TxEOM 0x40 /* Tx underrun */ +#define RR0_BrkAbort 0x80 /* Break/Abort */ + +/* Read Register 1 */ +#define RR1_AllSent 0x01 /* All sent */ +/* Residue Data for 8 Rx bits/char programmed */ +#define RR1_RES3 0x08 /* 0/3 */ +#define RR1_RES4 0x04 /* 0/4 */ +#define RR1_RES5 0x0c /* 0/5 */ +#define RR1_RES6 0x02 /* 0/6 */ +#define RR1_RES7 0x0a /* 0/7 */ +#define RR1_RES8 0x06 /* 0/8 */ +#define RR1_RES18 0x0e /* 1/8 */ +#define RR1_RES28 0x00 /* 2/8 */ +/* Special Rx Condition Interrupts */ +#define RR1_PariryError 0x10 /* Parity error */ +#define RR1_RxOverrun 0x20 /* Rx Overrun Error */ +#define RR1_FrameError 0x40 /* CRC/Framing Error */ +#define RR1_EndOfFrame 0x80 /* End of Frame (SDLC) */ + +/* Read Register 2 (channel b only) - Interrupt vector */ + +/* Read Register 3 (interrupt pending register) ch a only */ +#define RR3_BExt 0x01 /* Channel B Ext/Stat IP */ +#define RR3_BTxIP 0x02 /* Channel B Tx IP */ +#define RR3_BRxIP 0x04 /* Channel B Rx IP */ +#define RR3_AExt 0x08 /* Channel A Ext/Stat IP */ +#define RR3_ATxIP 0x10 /* Channel A Tx IP */ +#define RR3_ARxIP 0x20 /* Channel A Rx IP */ + +/* Read Register 8 (receive data register) */ + +/* Read Register 10 (misc status bits) */ +#define RR10_OnLoop 0x02 /* On loop */ +#define RR10_LoopSend 0x10 /* Loop sending */ +#define RR10_Clk2Mis 0x40 /* Two clocks missing */ +#define RR10_Clk1Mis 0x80 /* One clock missing */ + +/* Read Register 12 (lower byte of baud rate generator constant) */ + +/* Read Register 13 (upper byte of baud rate generator constant) */ + +/* Read Register 15 (value of WR 15) */ + +#define BRTC(brate) (( ((unsigned) DUART_CLOCK) / (2*(brate)*SCC_CLKMODE_TC)) - 2) +#define DUART_CLOCK 4915200 /* Z8530 duart */ +#define SCC_CLKMODE_TC 16 /* Always run x16 clock for async modes */ + +static unsigned char select_word_length_WR3[] = { + WR3_Rx5, // 5 bits / word (char) + WR3_Rx6, + WR3_Rx7, + WR3_Rx8 +}; + +static unsigned char select_word_length_WR5[] = { + WR5_Tx5, // 5 bits / word (char) + WR5_Tx6, + WR5_Tx7, + WR5_Tx8 +}; + +static unsigned char select_stop_bits[] = { + 0, + WR4_SB1, // 1 stop bit + WR4_SB15, // 1.5 stop bit + WR4_SB2 // 2 stop bits +}; + +static unsigned char select_parity[] = { + 0, // No parity + WR4_ParityEn | WR4_ParityEven, // Even parity + WR4_ParityEn, // Odd parity + 0xFF, // Mark parity + 0xFF, // Space parity +}; + +static cyg_int32 select_baud[] = { + 0, // Unused + 50, // 50 + 75, // 75 + 110, // 110 + 0, // 134.5 + 150, // 150 + 200, // 200 + 300, // 300 + 600, // 600 + 1200, // 1200 + 1800, // 1800 + 2400, // 2400 + 3600, // 3600 + 4800, // 4800 + 7200, // 7200 + 9600, // 9600 + 14400, // 14400 + 19200, // 19200 + 38400, // 38400 + 0, // 57600 + 0, // 115200 + 0, // 230400 +}; + +#endif // CYGONCE_MIPS_VRC4373_SERIAL_H diff --git a/packages/devs/serial/mn10300/mn10300/current/ChangeLog b/packages/devs/serial/mn10300/mn10300/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mn10300/mn10300/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_mn10300.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/mn10300/mn10300/current/cdl/ser_mn10300.cdl b/packages/devs/serial/mn10300/mn10300/current/cdl/ser_mn10300.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mn10300/mn10300/current/cdl/ser_mn10300.cdl @@ -0,0 +1,230 @@ +# ==================================================================== +# +# ser_mn10300.cdl +# +# eCos serial MN10300 configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-07 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_MN10300 { + display "MN10300 serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_MN10300 + + # Note: this is not currently tied to a specific board since the + # ports are "on chip" + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + MN10300." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a mn10300_serial.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +# FIXME: Bad name +cdl_option CYGPKG_IO_SERIAL_MN10300_POLLED_MODE { + display "MN10300 polled mode serial drivers" + flavor bool + default_value 0 + description " + If asserted, this option specifies that the serial device + drivers for the MN10300 should be polled-mode instead of + interrupt driven." +} + +cdl_component CYGPKG_IO_SERIAL_MN10300_SERIAL0 { + display "MN10300 serial port 0 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for port 0 on the + MN10300." + + cdl_option CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME { + display "Device name for MN10300 serial port 0" + flavor data + default_value {"\"/dev/ser0\""} + description " + This option specifies the device name port 0 on the MN10300." + } + + cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD { + display "Baud rate for the MN10300 serial port 0 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + MN10300 port 0." + } + + cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE { + display "Buffer size for the MN10300 serial port 0 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the MN10300 port 0." + } +} + +cdl_component CYGPKG_IO_SERIAL_MN10300_SERIAL1 { + display "MN10300 serial port 1 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for port 1 on + the MN10300." + + cdl_option CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME { + display "Device name for MN10300 serial port 1" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the device name port 1 on the MN10300." + } + + cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD { + display "Baud rate for the MN10300 serial port 1 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + MN10300 port 1." + } + + cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE { + display "Buffer size for the MN10300 serial port 1 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the MN10300 port 1." + } +} +cdl_component CYGPKG_IO_SERIAL_MN10300_SERIAL2 { + display "MN10300 serial port 2 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for port 2 on the + MN10300." + + cdl_option CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME { + display "Device name for MN10300 serial port 2" + flavor data + default_value {"\"/dev/ser2\""} + description " + This option specifies the device name port 2 on the MN10300." + } + + cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD { + display "Baud rate for the MN10300 serial port 2 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + MN10300 port 2." + } + + cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE { + display "Buffer size for the MN10300 serial port 2 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the MN10300 port 2." + } +} + + cdl_component CYGPKG_IO_SERIAL_MN10300_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_MN10300_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_MN10300_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_mn10300.cdl diff --git a/packages/devs/serial/mn10300/mn10300/current/src/mn10300_serial.c b/packages/devs/serial/mn10300/mn10300/current/src/mn10300_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/mn10300/mn10300/current/src/mn10300_serial.c @@ -0,0 +1,1010 @@ +//========================================================================== +// +// mn10300_serial.c +// +// Serial device driver for mn10300 on-chip serial devices +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributors: nickg +// Date: 1999-02-25 +// Purpose: MN10300 serial device driver +// Description: MN10300 serial device driver +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_MN10300 + +#define CYG_HAL_MN10300_SERIAL_RX_FIFO + +//------------------------------------------------------------------------- + +extern void diag_printf(const char *fmt, ...); + +//------------------------------------------------------------------------- +// Forward definitions + +static bool mn10300_serial_init(struct cyg_devtab_entry *tab); +static bool mn10300_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo mn10300_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char mn10300_serial_getc(serial_channel *chan); +static bool mn10300_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void mn10300_serial_start_xmit(serial_channel *chan); +static void mn10300_serial_stop_xmit(serial_channel *chan); + +#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE +static cyg_uint32 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static cyg_uint32 mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); +static void mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); +#endif + +//------------------------------------------------------------------------- + +#define BUFSIZE 128 + +//------------------------------------------------------------------------- +// MN10300 serial line control register values: + +// Offsets to serial control registers from base +#define SERIAL_CTR 0x0 +#define SERIAL_ICR 0x4 +#define SERIAL_TXB 0x8 +#define SERIAL_RXB 0x9 +#define SERIAL_STR 0xc +#define SERIAL_TIM 0xd + +// Status register bits +#define SR_RBF 0x10 +#define SR_TBF 0x20 +#define SR_RXF 0x40 +#define SR_TXF 0x80 + +// Control register bits +#define LCR_SB1 0x00 +#define LCR_SB1_5 0x00 +#define LCR_SB2 0x04 +#define LCR_PN 0x00 // Parity mode - none +#define LCR_PS 0x40 // Forced "space" parity +#define LCR_PM 0x50 // Forced "mark" parity +#define LCR_PE 0x60 // Parity mode - even +#define LCR_PO 0x70 // Parity mode - odd +#define LCR_WL5 0x00 // not supported - use 7bit +#define LCR_WL6 0x00 // not supported - use 7bit +#define LCR_WL7 0x00 // 7 bit chars +#define LCR_WL8 0x80 // 8 bit chars +#define LCR_RXE 0x4000 // receive enable +#define LCR_TXE 0x8000 // transmit enable + +#if defined(CYGPKG_HAL_MN10300_AM31) +#define LCR_TWE 0x0100 // interrupt enable (only on serial2/AM31) +#else +#define LCR_TWE 0x0000 // Bit does not exist in other variants +#endif + +//------------------------------------------------------------------------- +// MN10300 timer registers: + +#undef TIMER_BR +#undef TIMER_MD +#define TIMER_MD 0x00 +#define TIMER_BR 0x10 + +//------------------------------------------------------------------------- +// Serial and timer base registers: + +#if defined(CYGPKG_HAL_MN10300_AM31) + +#define SERIAL0_BASE 0x34000800 +#define SERIAL1_BASE 0x34000810 +#define SERIAL2_BASE 0x34000820 + +#define TIMER0_BASE 0x34001000 +#define TIMER1_BASE 0x34001001 +#define TIMER2_BASE 0x34001002 + +#define SERIAL0_TIMER_SELECT 0x0004 // timer 0 +#define SERIAL1_TIMER_SELECT 0x0004 // timer 1 +#define SERIAL2_TIMER_SELECT 0x0001 // timer 2 + +#ifdef CYGPKG_HAL_MN10300_AM31_STDEVAL1 +// The use of PORT3 to provide CTS/CTR is specific to +// the STDEVAL1 board only. +#define PORT3_MD 0x36008025 +#endif + +#define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan) \ +CYG_MACRO_START \ + if( mn10300_chan->is_serial2 ) \ + cr |= LCR_TWE; \ + else \ + cr |= LCR_TXE; \ +CYG_MACRO_END + +#define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan) \ +CYG_MACRO_START \ + if( mn10300_chan->is_serial2 ) \ + cr &= ~LCR_TWE; \ + else \ + cr &= ~LCR_TXE; \ +CYG_MACRO_END + +#elif defined(CYGPKG_HAL_MN10300_AM33) + +#define SERIAL0_BASE 0xd4002000 +#define SERIAL1_BASE 0xd4002010 +#define SERIAL2_BASE 0xd4002020 + +#define TIMER0_BASE 0xd4003002 +#define TIMER1_BASE 0xd4003001 +#define TIMER2_BASE 0xd4003003 + +#define SERIAL0_TIMER_SELECT 0x0005 // timer 2 +#define SERIAL1_TIMER_SELECT 0x0004 // timer 1 +#define SERIAL2_TIMER_SELECT 0x0003 // timer 3 + +#define HW_TIMER0 0xd4003000 + +#define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan) + +#define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan) + +#else + +#error Unsupported MN10300 variant + +#endif + +//------------------------------------------------------------------------- +// Tables to map input values to hardware settings + +static unsigned char select_word_length[] = { + LCR_WL5, // 5 bits / word (char) + LCR_WL6, + LCR_WL7, + LCR_WL8 +}; + +static unsigned char select_stop_bits[] = { + 0, + LCR_SB1, // 1 stop bit + LCR_SB1_5, // 1.5 stop bit + LCR_SB2 // 2 stop bits +}; + +static unsigned char select_parity[] = { + LCR_PN, // No parity + LCR_PE, // Even parity + LCR_PO, // Odd parity + LCR_PM, // Mark parity + LCR_PS, // Space parity +}; + +#if defined(CYGPKG_HAL_MN10300_AM31) + +static unsigned short select_baud_01[] = { + 0, // Unused + 0, // 50 + 0, // 75 + 0, // 110 + 0, // 134.5 + 0, // 150 + 0, // 200 + 0, // 300 + 0, // 600 + 0, // 1200 + 0, // 1800 + 0, // 2400 + 0, // 3600 + 0, // 4800 + 0, // 7200 + 195, // 9600 + 130, // 14400 + 98, // 19200 + 48, // 38400 + 32, // 57600 + 16, // 115200 + 8, // 230400 +}; + +// Serial 2 has its own timer register in addition to using timer 2 to +// supply the baud rate generator. Both of these must be proframmed to +// get the right baud rate. The following values come from Matsushita +// with some modifications from Cygmon. +static struct +{ + cyg_uint8 serial2_val; + cyg_uint8 timer2_val; +} select_baud_2[] = { + { 0, 0 }, // Unused + { 0, 0 }, // 50 + { 0, 0 }, // 75 + { 0, 0 }, // 110 + { 0, 0 }, // 134.5 + { 0, 0 }, // 150 + { 0, 0 }, // 200 + { 0, 0 }, // 300 + { 126, 196 }, // 600 + { 125, 98 }, // 1200 + { 0, 0 }, // 1800 + { 124, 49 }, // 2400 + { 0, 0 }, // 3600 + { 124, 24 }, // 4800 + { 0, 0 }, // 7200 + { 70, 21 }, // 9600 + { 0, 0 }, // 14400 + { 70, 10 }, // 19200 + { 22, 16 }, // 38400 + { 88, 2 }, // 57600 + { 64, 1 }, // 115200 + { 62, 0 }, // 230400 +}; + +#elif defined(CYGPKG_HAL_MN10300_AM33) + +// The AM33 runs at a different clock rate and therefore has a +// different set of dividers for the baud rate. + +static unsigned short select_baud_01[] = { + 0, // Unused + 0, // 50 + 0, // 75 + 0, // 110 + 0, // 134.5 + 0, // 150 + 0, // 200 + 0, // 300 + 0, // 600 + 3168, // 1200 + 0, // 1800 + 1584, // 2400 + 0, // 3600 + 792, // 4800 + 0, // 7200 + 396, // 9600 + 0, // 14400 + 198, // 19200 + 99, // 38400 + 0, // 57600 + 33, // 115200 + 16, // 230400 +}; + +// Serial 2 has its own timer register in addition to using timer 2 to +// supply the baud rate generator. Both of these must be proframmed to +// get the right baud rate. The following values come from Matsushita +// with some modifications from Cygmon. + +// The values in the following table differ significantly from those +// given in the Matsushita documentation. These have been determined +// by (somewhat exhaustive) experiment, the values in the documentation +// do not appear to work at all. + +static struct +{ + cyg_uint8 serial2_val; + cyg_uint8 timer2_val; +} select_baud_2[] = { + { 0, 0 }, // Unused + { 0, 0 }, // 50 + { 0, 0 }, // 75 + { 0, 0 }, // 110 + { 0, 0 }, // 134.5 + { 0, 0 }, // 150 + { 0, 0 }, // 200 + { 0, 0 }, // 300 + { 0, 0 }, // 600 + { 0, 0 }, // 1200 + { 0, 0 }, // 1800 + { 0, 0 }, // 2400 + { 0, 0 }, // 3600 + { 110, 56 }, // 4800 + { 0, 0 }, // 7200 + { 110, 28 }, // 9600 + { 0, 0 }, // 14400 + { 71, 21 }, // 19200 + { 102, 7 }, // 38400 + { 0, 0 }, // 57600 + { 9, 26 }, // 115200 + { 0, 0 }, // 230400 +}; + +#else + +#error Unsupported MN10300 variant + +#endif + +//------------------------------------------------------------------------- +// Info for each serial device controlled + +typedef struct mn10300_serial_info { + CYG_ADDRWORD base; + CYG_ADDRWORD timer_base; + CYG_WORD timer_select; + CYG_WORD rx_int; + CYG_WORD tx_int; + cyg_bool is_serial2; + cyg_interrupt rx_interrupt; + cyg_interrupt tx_interrupt; + cyg_handle_t rx_interrupt_handle; + cyg_handle_t tx_interrupt_handle; +#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO + volatile cyg_int32 fifo_head; + volatile cyg_int32 fifo_tail; + volatile cyg_uint8 fifo[16]; +#endif +} mn10300_serial_info; + +//------------------------------------------------------------------------- +// Callback functions exported by this driver + +static SERIAL_FUNS(mn10300_serial_funs, + mn10300_serial_putc, + mn10300_serial_getc, + mn10300_serial_set_config, + mn10300_serial_start_xmit, + mn10300_serial_stop_xmit + ); + +//------------------------------------------------------------------------- +// Hardware info for each serial line + +#ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1 +#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 +static mn10300_serial_info mn10300_serial_info0 = { + SERIAL0_BASE, + TIMER0_BASE, + SERIAL0_TIMER_SELECT, + CYGNUM_HAL_INTERRUPT_SERIAL_0_RX, + CYGNUM_HAL_INTERRUPT_SERIAL_0_TX, + false +}; +#if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0 +static unsigned char mn10300_serial_out_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE]; +static unsigned char mn10300_serial_in_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE]; +#endif +#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 +#endif + +#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 +static mn10300_serial_info mn10300_serial_info1 = { + SERIAL1_BASE, + TIMER1_BASE, + SERIAL1_TIMER_SELECT, + CYGNUM_HAL_INTERRUPT_SERIAL_1_RX, + CYGNUM_HAL_INTERRUPT_SERIAL_1_TX, + false +}; +#if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0 +static unsigned char mn10300_serial_out_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE]; +static unsigned char mn10300_serial_in_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE]; +#endif +#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 + +#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 +static mn10300_serial_info mn10300_serial_info2 = { + SERIAL2_BASE, + TIMER2_BASE, + SERIAL2_TIMER_SELECT, + CYGNUM_HAL_INTERRUPT_SERIAL_2_RX, + CYGNUM_HAL_INTERRUPT_SERIAL_2_TX, + true +}; +#if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0 +static unsigned char mn10300_serial_out_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE]; +static unsigned char mn10300_serial_in_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE]; +#endif +#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2 + + +//------------------------------------------------------------------------- +// Channel descriptions: + +#ifdef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE +#define SIZEOF_BUF(_x_) 0 +#else +#define SIZEOF_BUF(_x_) sizeof(_x_) +#endif + +#ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1 +#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 +#if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0 +static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel0, + mn10300_serial_funs, + mn10300_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &mn10300_serial_out_buf0[0], + SIZEOF_BUF(mn10300_serial_out_buf0), + &mn10300_serial_in_buf0[0], + SIZEOF_BUF(mn10300_serial_in_buf0) + ); +#else +static SERIAL_CHANNEL(mn10300_serial_channel0, + mn10300_serial_funs, + mn10300_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif +#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 +#endif + +#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 +#if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0 +static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel1, + mn10300_serial_funs, + mn10300_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &mn10300_serial_out_buf1[0], + SIZEOF_BUF(mn10300_serial_out_buf1), + &mn10300_serial_in_buf1[0], + SIZEOF_BUF(mn10300_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(mn10300_serial_channel1, + mn10300_serial_funs, + mn10300_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif +#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 + +#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 +#if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0 +static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel2, + mn10300_serial_funs, + mn10300_serial_info2, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &mn10300_serial_out_buf2[0], + SIZEOF_BUF(mn10300_serial_out_buf2), + &mn10300_serial_in_buf2[0], + SIZEOF_BUF(mn10300_serial_in_buf2) + ); +#else +static SERIAL_CHANNEL(mn10300_serial_channel2, + mn10300_serial_funs, + mn10300_serial_info2, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif +#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2 + +//------------------------------------------------------------------------- +// And finally, the device table entries: + +#ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1 +#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 +// On the standard eval board serial0 is not connected. If enabled, it +// generates continuous frame error and overrun interrupts. Hence we do +// not touch it. +DEVTAB_ENTRY(mn10300_serial_io0, + CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + mn10300_serial_init, + mn10300_serial_lookup, // Serial driver may need initializing + &mn10300_serial_channel0 + ); +#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 +#endif + +#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 +DEVTAB_ENTRY(mn10300_serial_io1, + CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + mn10300_serial_init, + mn10300_serial_lookup, // Serial driver may need initializing + &mn10300_serial_channel1 + ); +#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 + +#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 +DEVTAB_ENTRY(mn10300_serial_io2, + CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + mn10300_serial_init, + mn10300_serial_lookup, // Serial driver may need initializing + &mn10300_serial_channel2 + ); +#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2 + +//------------------------------------------------------------------------- +// Read the serial line's status register. Serial 2 has an 8 bit status +// register while serials 0 and 1 have 16 bit registers. This function +// uses the correct size access, but passes back a 16 bit quantity for +// both. + +static cyg_uint16 mn10300_read_sr( mn10300_serial_info *mn10300_chan ) +{ + cyg_uint16 sr = 0; + if( mn10300_chan->is_serial2 ) + { + cyg_uint8 sr8; + HAL_READ_UINT8(mn10300_chan->base+SERIAL_STR, sr8); + sr = sr8; + } + else + { + HAL_READ_UINT16(mn10300_chan->base+SERIAL_STR, sr); + } + + return sr; +} + +//------------------------------------------------------------------------- + +static bool +mn10300_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + cyg_uint16 cr = 0; + cyg_uint16 sr; + + // wait for the device to become quiescent. This could take some time + // if the device had been transmitting at a low baud rate. + do { + sr = mn10300_read_sr(mn10300_chan); + } while (sr & (SR_RXF|SR_TXF)); + + // Disable device entirely. + HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, 0); + + // Set up the Interrupt Mode Register + HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_ICR, 0); + + // Set up baud rate + if( mn10300_chan->is_serial2 ) + { + // Serial 2 is a bit different from 0 and 1 in the way that the + // baud rate is controlled. + + cyg_uint8 baud_divisor = select_baud_2[new_config->baud].timer2_val; + + if (baud_divisor == 0) + return false; // Invalid baud rate selected + + HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor); + + HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, 0x80 ); + + baud_divisor = select_baud_2[new_config->baud].serial2_val; + + HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_TIM, baud_divisor); + + cr |= mn10300_chan->timer_select; + } + else + { + cyg_uint16 baud_divisor = select_baud_01[new_config->baud]; + cyg_uint8 timer_mode = 0x80; + + if (baud_divisor == 0) + return false; // Invalid baud rate selected + +#if defined(CYGPKG_HAL_MN10300_AM33) + if( baud_divisor > 255 ) + { + // The AM33 runs at a higher clock rate than the AM31 and + // needs a bigger divisor for low baud rates. We do this by + // using timer 0 as a prescaler. We set it to 198 so we can then + // use it to prescale for both serial0 and serial1 if they need + // it. + static int timer0_initialized = 0; + baud_divisor /= 198; + baud_divisor--; + timer_mode = 0x84; + if( !timer0_initialized ) + { + timer0_initialized = 1; + HAL_WRITE_UINT8(HW_TIMER0+TIMER_BR, 198 ); + HAL_WRITE_UINT8(HW_TIMER0+TIMER_MD, 0x80 ); + } + } +#endif + + HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor); + + HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, timer_mode ); + + cr |= mn10300_chan->timer_select; + } + +#ifdef PORT3_MD + HAL_WRITE_UINT8( PORT3_MD, 0x01 ); +#endif + + // set up other config values: + + cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; + cr |= select_stop_bits[new_config->stop]; + cr |= select_parity[new_config->parity]; + + cr |= LCR_RXE | LCR_TXE; // enable Rx and Tx + +#ifdef CYGPKG_HAL_MN10300_AM31 + if( mn10300_chan->is_serial2 ) + { + // AM31 has an extra TX interrupt enable bit for serial 2. + DISABLE_TRANSMIT_INTERRUPT(mn10300_chan); + } +#endif + + // Write CR into hardware + HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, cr); + + sr = mn10300_read_sr(mn10300_chan); + + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +//------------------------------------------------------------------------- +// Function to initialize the device. Called at bootstrap time. + +bool mn10300_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + +#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE + if (chan->out_cbuf.len != 0) { + // Install and enable the receive interrupt + cyg_drv_interrupt_create(mn10300_chan->rx_int, + 4, // Priority - what goes here? + (cyg_addrword_t)chan, // Data item passed to interrupt handler + mn10300_serial_rx_ISR, + mn10300_serial_rx_DSR, + &mn10300_chan->rx_interrupt_handle, + &mn10300_chan->rx_interrupt); + cyg_drv_interrupt_attach(mn10300_chan->rx_interrupt_handle); + cyg_drv_interrupt_unmask(mn10300_chan->rx_int); + + // Install and enable the transmit interrupt + cyg_drv_interrupt_create(mn10300_chan->tx_int, + 4, // Priority - what goes here? + (cyg_addrword_t)chan, // Data item passed to interrupt handler + mn10300_serial_tx_ISR, + mn10300_serial_tx_DSR, + &mn10300_chan->tx_interrupt_handle, + &mn10300_chan->tx_interrupt); + cyg_drv_interrupt_attach(mn10300_chan->tx_interrupt_handle); + cyg_drv_interrupt_mask(mn10300_chan->tx_int); + } +#endif + + mn10300_serial_config_port(chan, &chan->config, true); + + return true; +} + +//------------------------------------------------------------------------- +// This routine is called when the device is "looked" up (i.e. attached) + +static Cyg_ErrNo +mn10300_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +//------------------------------------------------------------------------- +// Return 'true' if character is sent to device + +bool +mn10300_serial_putc(serial_channel *chan, unsigned char c) +{ + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + cyg_uint8 sr = mn10300_read_sr( mn10300_chan); + + if( (sr & SR_TBF) == 0 ) + { + HAL_WRITE_UINT8( mn10300_chan->base+SERIAL_TXB, c ); + + return true; + } + else return false; +} + +//------------------------------------------------------------------------- + +unsigned char +mn10300_serial_getc(serial_channel *chan) +{ + unsigned char c; + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + do + { + cyg_uint8 sr = mn10300_read_sr( mn10300_chan ); + + if( (sr & SR_RBF) != 0 ) + { + HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c ); + + break; + } + + } while(1); + + return c; +} + +//------------------------------------------------------------------------- + +bool +mn10300_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return mn10300_serial_config_port(chan, config, false); +} + +//------------------------------------------------------------------------- +// Enable the transmitter on the device + +static void +mn10300_serial_start_xmit(serial_channel *chan) +{ +#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + cyg_uint16 cr; + + HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); + + ENABLE_TRANSMIT_INTERRUPT(mn10300_chan); + + HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); + + cyg_drv_interrupt_unmask(mn10300_chan->tx_int); + + (chan->callbacks->xmt_char)(chan); +#endif +} + +//------------------------------------------------------------------------- +// Disable the transmitter on the device + +static void +mn10300_serial_stop_xmit(serial_channel *chan) +{ +#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + cyg_uint16 cr; + cyg_uint16 sr; + + // Wait until the transmitter has actually stopped before turning it off. + + do + { + sr = mn10300_read_sr( mn10300_chan ); + + } while( sr & SR_TXF ); + + HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); + + DISABLE_TRANSMIT_INTERRUPT(mn10300_chan); + + HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); + + cyg_drv_interrupt_mask(mn10300_chan->tx_int); + +#endif +} + +//------------------------------------------------------------------------- +// Serial I/O - low level interrupt handlers (ISR) + +#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE + +#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO + +// This version of the RX ISR implements a simple receive FIFO. The +// MN10300 serial devices do not have hardware FIFOs (as found in +// 16550s for example), and it can be difficult at times to keep up +// with higher baud rates without overrunning. This ISR implements a +// software equivalent of the hardware FIFO, placing recieved +// characters into the FIFO as soon as they arrive. Whenever the DSR +// is run, it collects all the pending characters from the FIFO for +// delivery to the application. Neither the ISR or DSR disable +// interrupts, instead we rely on being able to write the head and +// tail pointers atomically, to implement lock-free synchronization. + +static cyg_uint32 +mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + cyg_uint8 sr = mn10300_read_sr( mn10300_chan); + + while( (sr & SR_RBF) != 0 ) + { + register cyg_int32 head = mn10300_chan->fifo_head; + cyg_uint8 c; + int i; + HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c ); + + mn10300_chan->fifo[head++] = c; + + if( head >= sizeof(mn10300_chan->fifo) ) + head = 0; + + mn10300_chan->fifo_head = head; + + sr = mn10300_read_sr( mn10300_chan); + + } + + cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int); + + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +#else + +static cyg_uint32 +mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + + cyg_drv_interrupt_mask(mn10300_chan->rx_int); + cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int); + + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +#endif + +static cyg_uint32 +mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + + cyg_drv_interrupt_mask(mn10300_chan->tx_int); + cyg_drv_interrupt_acknowledge(mn10300_chan->tx_int); + + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +#endif + +//------------------------------------------------------------------------- +// Serial I/O - high level interrupt handler (DSR) + +#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE + +#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO + +static void +mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + register cyg_int32 head = mn10300_chan->fifo_head; + register cyg_int32 tail = mn10300_chan->fifo_tail; + + while( head != tail ) + { + cyg_uint8 c = mn10300_chan->fifo[tail++]; + + if( tail >= sizeof(mn10300_chan->fifo) ) tail = 0; + + (chan->callbacks->rcv_char)(chan, c); + } + + mn10300_chan->fifo_tail = tail; +} + +#else + +static void +mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + cyg_uint8 sr = mn10300_read_sr( mn10300_chan); + + if( (sr & SR_RBF) != 0 ) + { + cyg_uint8 rxb; + HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, rxb ); + + (chan->callbacks->rcv_char)(chan, rxb); + } + + cyg_drv_interrupt_unmask(mn10300_chan->rx_int); +} + +#endif + +static void +mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; + cyg_uint8 sr = mn10300_read_sr( mn10300_chan); + + if( (sr & SR_TBF) == 0 ) + { + (chan->callbacks->xmt_char)(chan); + } + + cyg_drv_interrupt_unmask(mn10300_chan->tx_int); +} + +#endif + +#endif // CYGPKG_IO_SERIAL_MN10300 + +//------------------------------------------------------------------------- +// EOF mn10300.c diff --git a/packages/devs/serial/powerpc/cogent/current/ChangeLog b/packages/devs/serial/powerpc/cogent/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/powerpc/cogent/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_powerpc_cogent.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/powerpc/cogent/current/cdl/ser_powerpc_cogent.cdl b/packages/devs/serial/powerpc/cogent/current/cdl/ser_powerpc_cogent.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/powerpc/cogent/current/cdl/ser_powerpc_cogent.cdl @@ -0,0 +1,181 @@ +# ==================================================================== +# +# ser_powerpc_cogent.cdl +# +# eCos serial PowerPC/Cogent configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-14 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + +cdl_package CYGPKG_IO_SERIAL_POWERPC_COGENT { + display "Cogent PowerPC serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_POWERPC_COGENT + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + Cogent PowerPC." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a cogent_serial_with_ints.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_A { + display "Cogent PowerPC serial port A driver" + flavor bool + default_value 0 + requires (CYGIMP_KERNEL_INTERRUPTS_CHAIN || \ + !CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B) + description " + This option includes the serial device driver for the Cogent + PowerPC port A. If both drivers need to be enabled, interrupt + chaining must be enabled in the kernel configuration." + + cdl_option CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_A_NAME { + display "Device name for Cogent PowerPC serial port A" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the device name for the Cogent PowerPC + port A." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BAUD { + display "Baud rate for the Cogent PowerPC serial port A driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + Cogent PowerPC port A." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE { + display "Buffer size for the Cogent PowerPC serial port A driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used for + the Cogent PowerPC port A." + } +} +cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B { + display "Cogent PowerPC serial port B driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the Cogent + PowerPC port B." + + cdl_option CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME { + display "Device name for Cogent PowerPC serial port B" + flavor data + default_value {"\"/dev/ser2\""} + description " + This option specifies the device name for the Cogent PowerPC + port B." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BAUD { + display "Baud rate for the Cogent PowerPC serial port B driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + Cogent PowerPC port B." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE { + display "Buffer size for the Cogent PowerPC serial port B driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used + for the Cogent PowerPC port B." + } +} + + cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_POWERPC_COGENT_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_POWERPC_COGENT_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_powerpc_cogent.cdl diff --git a/packages/devs/serial/powerpc/cogent/current/src/cogent_serial.h b/packages/devs/serial/powerpc/cogent/current/src/cogent_serial.h new file mode 100644 --- /dev/null +++ b/packages/devs/serial/powerpc/cogent/current/src/cogent_serial.h @@ -0,0 +1,204 @@ +//========================================================================== +// +// io/serial/powerpc/cogent_serial.h +// +// PowerPC Cogent Serial I/O definitions. +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov, based on ARM driver by gthomas +// Contributors:gthomas, jskov +// Date: 1999-03-02 +// Purpose: Cogent Serial definitions +//####DESCRIPTIONEND#### +//========================================================================== + +// Description of serial ports on Cogent board + +// Interrupt Enable Register +#define IER_RCV 0x01 +#define IER_XMT 0x02 +#define IER_LS 0x04 +#define IER_MS 0x08 + +// Line Control Register +#define LCR_WL5 0x00 // Word length +#define LCR_WL6 0x01 +#define LCR_WL7 0x02 +#define LCR_WL8 0x03 +#define LCR_SB1 0x00 // Number of stop bits +#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words +#define LCR_SB2 0x04 +#define LCR_PN 0x00 // Parity mode - none +#define LCR_PE 0x0C // Parity mode - even +#define LCR_PO 0x08 // Parity mode - odd +#define LCR_PM 0x28 // Forced "mark" parity +#define LCR_PS 0x38 // Forced "space" parity +#define LCR_DL 0x80 // Enable baud rate latch + +// Line Status Register +#define LSR_RSR 0x01 +#define LSR_THE 0x20 + +// Modem Control Register +#define MCR_DTR 0x01 +#define MCR_RTS 0x02 +#define MCR_INT 0x08 // Enable interrupts + +// Interrupt status register +#define ISR_Tx 0x02 +#define ISR_Rx 0x04 + +// FIFO control register +#define FCR_ENABLE 0x01 +#define FCR_CLEAR_RCVR 0x02 +#define FCR_CLEAR_XMIT 0x04 + + +//////////////////////////////////////////////////////////// +// Clean this up. + +//----------------------------------------------------------------------------- +// There are two serial ports. +#define CMA_SER_16550_BASE_A 0xe900047 // port A +#define CMA_SER_16550_BASE_B 0xe900007 // port B +#define SER_16550_BASE CMA_SER_16550_BASE_B + +//----------------------------------------------------------------------------- +// Define the serial registers. The Cogent board is equipped with a 16552 +// serial chip. +#define SER_16550_RBR 0x00 // receiver buffer register, read, dlab = 0 +#define SER_16550_THR 0x00 // transmitter holding register, write, dlab = 0 +#define SER_16550_DLL 0x00 // divisor latch (LS), read/write, dlab = 1 +#define SER_16550_IER 0x08 // interrupt enable register, read/write, dlab = 0 +#define SER_16550_DLM 0x08 // divisor latch (MS), read/write, dlab = 1 +#define SER_16550_IIR 0x10 // interrupt identification reg, read, dlab = 0 +#define SER_16550_FCR 0x10 // fifo control register, write, dlab = 0 +#define SER_16550_AFR 0x10 // alternate function reg, read/write, dlab = 1 +#define SER_16550_LCR 0x18 // line control register, read/write +#define SER_16550_MCR 0x20 // modem control register, read/write +#define SER_16550_LSR 0x28 // line status register, read +#define SER_16550_MSR 0x30 // modem status register, read +#define SER_16550_SCR 0x38 // scratch pad register + +// The interrupt enable register bits. +#define SIO_IER_ERDAI 0x01 // enable received data available irq +#define SIO_IER_ETHREI 0x02 // enable THR empty interrupt +#define SIO_IER_ELSI 0x04 // enable receiver line status irq +#define SIO_IER_EMSI 0x08 // enable modem status interrupt + +// The interrupt identification register bits. +#define SIO_IIR_IP 0x01 // 0 if interrupt pending +#define SIO_IIR_ID_MASK 0x0e // mask for interrupt ID bits + +// The line status register bits. +#define SIO_LSR_DR 0x01 // data ready +#define SIO_LSR_OE 0x02 // overrun error +#define SIO_LSR_PE 0x04 // parity error +#define SIO_LSR_FE 0x08 // framing error +#define SIO_LSR_BI 0x10 // break interrupt +#define SIO_LSR_THRE 0x20 // transmitter holding register empty +#define SIO_LSR_TEMT 0x40 // transmitter register empty +#define SIO_LSR_ERR 0x80 // any error condition + +// The modem status register bits. +#define SIO_MSR_DCTS 0x01 // delta clear to send +#define SIO_MSR_DDSR 0x02 // delta data set ready +#define SIO_MSR_TERI 0x04 // trailing edge ring indicator +#define SIO_MSR_DDCD 0x08 // delta data carrier detect +#define SIO_MSR_CTS 0x10 // clear to send +#define SIO_MSR_DSR 0x20 // data set ready +#define SIO_MSR_RI 0x40 // ring indicator +#define SIO_MSR_DCD 0x80 // data carrier detect + +// The line control register bits. +#define SIO_LCR_WLS0 0x01 // word length select bit 0 +#define SIO_LCR_WLS1 0x02 // word length select bit 1 +#define SIO_LCR_STB 0x04 // number of stop bits +#define SIO_LCR_PEN 0x08 // parity enable +#define SIO_LCR_EPS 0x10 // even parity select +#define SIO_LCR_SP 0x20 // stick parity +#define SIO_LCR_SB 0x40 // set break +#define SIO_LCR_DLAB 0x80 // divisor latch access bit + +// The FIFO control register +#define SIO_FCR_FCR0 0x01 // enable xmit and rcvr fifos +#define SIO_FCR_FCR1 0x02 // clear RCVR FIFO +#define SIO_FCR_FCR2 0x04 // clear XMIT FIFO +///////////////////////////////////////// + + +static unsigned char select_word_length[] = { + LCR_WL5, // 5 bits / word (char) + LCR_WL6, + LCR_WL7, + LCR_WL8 +}; + +static unsigned char select_stop_bits[] = { + 0, + LCR_SB1, // 1 stop bit + LCR_SB1_5, // 1.5 stop bit + LCR_SB2 // 2 stop bits +}; + +static unsigned char select_parity[] = { + LCR_PN, // No parity + LCR_PE, // Even parity + LCR_PO, // Odd parity + LCR_PM, // Mark parity + LCR_PS, // Space parity +}; + +// FIXME: calc all properly +// The Cogent board has a 3.6864 MHz crystal +static unsigned short select_baud[] = { + 0, // Unused + 4608, // 50 + 0, // 75 + 2094, // 110 + 0, // 134.5 + 1536, // 150 + 0, // 200 + 768, // 300 + 384, // 600 + 182, // 1200 + 0, // 1800 + 96, // 2400 + 0, // 3600 + 48, // 4800 + 32, // 7200 + 24, // 9600 + 16, // 14400 + 12, // 19200 + 6, // 38400 + 4, // 57600 + 2, // 115200 + 0, // 230400 +}; + diff --git a/packages/devs/serial/powerpc/cogent/current/src/cogent_serial_with_ints.c b/packages/devs/serial/powerpc/cogent/current/src/cogent_serial_with_ints.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/powerpc/cogent/current/src/cogent_serial_with_ints.c @@ -0,0 +1,387 @@ +//========================================================================== +// +// io/serial/powerpc/cogent_serial_with_ints.c +// +// PowerPC Cogent Serial I/O Interface Module (interrupt driven) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov, based on ARM driver by gthomas +// Contributors:gthomas, jskov +// Date: 1999-03-02 +// Purpose: Cogent Serial I/O module (interrupt driven version) +// Description: +// +// To Do: +// Put in magic to effectively use the FIFOs. Transmitter FIFO fill is a +// problem, and setting receiver FIFO interrupts to happen only after +// n chars may conflict with hal diag. +// +//####DESCRIPTIONEND#### +//========================================================================== + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_POWERPC_COGENT + +#include "cogent_serial.h" + +// Make sure the configuration is sane. +#if defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_A) && \ + defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B) && \ + !defined(CYGIMP_KERNEL_INTERRUPTS_CHAIN) +#error "Need CYGIMP_KERNEL_INTERRUPTS_CHAIN to support both ports" +#endif + + +#define BUFSIZE 128 + +typedef struct cogent_serial_info { + CYG_ADDRWORD base; + CYG_WORD int_num; + cyg_interrupt serial_interrupt; + cyg_handle_t serial_interrupt_handle; +} cogent_serial_info; + +static bool cogent_serial_init(struct cyg_devtab_entry *tab); +static bool cogent_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo cogent_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char cogent_serial_getc(serial_channel *chan); +static bool cogent_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void cogent_serial_start_xmit(serial_channel *chan); +static void cogent_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 cogent_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void cogent_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(cogent_serial_funs, + cogent_serial_putc, + cogent_serial_getc, + cogent_serial_set_config, + cogent_serial_start_xmit, + cogent_serial_stop_xmit + ); + +#ifdef CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_A +static cogent_serial_info cogent_serial_info0 ={CMA_SER_16550_BASE_A, + CYGNUM_HAL_INTERRUPT_SIU_IRQ1}; +#if CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE > 0 +static unsigned char cogent_serial_out_buf0[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE]; +static unsigned char cogent_serial_in_buf0[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(cogent_serial_channel0, + cogent_serial_funs, + cogent_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &cogent_serial_out_buf0[0], + sizeof(cogent_serial_out_buf0), + &cogent_serial_in_buf0[0], + sizeof(cogent_serial_in_buf0) + ); +#else +static SERIAL_CHANNEL(cogent_serial_channel0, + cogent_serial_funs, + cogent_serial_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(cogent_serial_io0, + CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_A_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + cogent_serial_init, + cogent_serial_lookup, // Serial driver may need initializing + &cogent_serial_channel0 + ); +#endif + +#ifdef CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B +static cogent_serial_info cogent_serial_info1 ={CMA_SER_16550_BASE_B, + CYGNUM_HAL_INTERRUPT_SIU_IRQ1}; +#if CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE > 0 +static unsigned char cogent_serial_out_buf1[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE]; +static unsigned char cogent_serial_in_buf1[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(cogent_serial_channel1, + cogent_serial_funs, + cogent_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &cogent_serial_out_buf1[0], + sizeof(cogent_serial_out_buf1), + &cogent_serial_in_buf1[0], + sizeof(cogent_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(cogent_serial_channel1, + cogent_serial_funs, + cogent_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(cogent_serial_io1, + CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + cogent_serial_init, + cogent_serial_lookup, // Serial driver may need initializing + &cogent_serial_channel1 + ); +#endif + + + +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool +cogent_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; + cyg_addrword_t port = cogent_chan->base; + cyg_uint16 baud_divisor = select_baud[new_config->baud]; + cyg_uint8 _lcr, _ier; + + if (baud_divisor == 0) + return false; // Invalid baud rate selected + + // Disable port interrupts while changing hardware + HAL_READ_UINT8(port+SER_16550_IER, _ier); + HAL_WRITE_UINT8(port+SER_16550_IER, 0); + + // Set databits, stopbits and parity. + _lcr = select_word_length[(new_config->word_length - + CYGNUM_SERIAL_WORD_LENGTH_5)] | + select_stop_bits[new_config->stop] | + select_parity[new_config->parity]; + HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr); + + // Set baud rate. + _lcr |= LCR_DL; + HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr); + HAL_WRITE_UINT8(port+SER_16550_DLM, baud_divisor >> 8); + HAL_WRITE_UINT8(port+SER_16550_DLL, baud_divisor & 0xff); + _lcr &= ~LCR_DL; + HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr); + + if (init) { + // Enable and clear FIFO + HAL_WRITE_UINT8(port+SER_16550_FCR, + (FCR_ENABLE | FCR_CLEAR_RCVR | FCR_CLEAR_XMIT)); + + if (chan->out_cbuf.len != 0) { + HAL_WRITE_UINT8(port+SER_16550_IER, SIO_IER_ERDAI); + } else { + HAL_WRITE_UINT8(port+SER_16550_IER, 0); + } + + { + // Special initialization for ST16C552 on CMA102 + cyg_uint8 mcr; + + HAL_READ_UINT8(CMA_SER_16550_BASE_A+SER_16550_MCR, mcr); + mcr |= 8; + HAL_WRITE_UINT8(CMA_SER_16550_BASE_A+SER_16550_MCR, mcr); + + HAL_READ_UINT8(CMA_SER_16550_BASE_B+SER_16550_MCR, mcr); + mcr |= 8; + HAL_WRITE_UINT8(CMA_SER_16550_BASE_B+SER_16550_MCR, mcr); + } + } else { + HAL_WRITE_UINT8(port+SER_16550_IER, _ier); + } + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +cogent_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; +#ifdef CYGDBG_IO_INIT + diag_printf("COGENT SERIAL init - dev: %x.%d\n", cogent_chan->base, cogent_chan->int_num); +#endif + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (chan->out_cbuf.len != 0) { + cyg_drv_interrupt_create(cogent_chan->int_num, + 0, // can change IRQ0 priority + (cyg_addrword_t)chan, // Data item passed to interrupt handler + cogent_serial_ISR, + cogent_serial_DSR, + &cogent_chan->serial_interrupt_handle, + &cogent_chan->serial_interrupt); + cyg_drv_interrupt_attach(cogent_chan->serial_interrupt_handle); + cyg_drv_interrupt_unmask(cogent_chan->int_num); + } + cogent_serial_config_port(chan, &chan->config, true); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +cogent_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +cogent_serial_putc(serial_channel *chan, unsigned char c) +{ + cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; + cyg_addrword_t port = cogent_chan->base; + cyg_uint8 _lsr; + + HAL_READ_UINT8(port+SER_16550_LSR, _lsr); + if (_lsr & SIO_LSR_THRE) { +// Transmit buffer is empty + HAL_WRITE_UINT8(port+SER_16550_THR, c); + return true; + } else { +// No space + return false; + } +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +cogent_serial_getc(serial_channel *chan) +{ + unsigned char c; + cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; + cyg_addrword_t port = cogent_chan->base; + cyg_uint8 _lsr; + + do { + HAL_READ_UINT8(port+SER_16550_LSR, _lsr); + } while ((_lsr & SIO_LSR_DR) == 0); + + HAL_READ_UINT8(port+SER_16550_RBR, c); + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +cogent_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return cogent_serial_config_port(chan, config, false); +} + +// Enable the transmitter on the device +static void +cogent_serial_start_xmit(serial_channel *chan) +{ + cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; + cyg_addrword_t port = cogent_chan->base; + cyg_uint8 _ier; + + HAL_READ_UINT8(port+SER_16550_IER, _ier); + _ier |= IER_XMT; // Enable xmit interrupt + HAL_WRITE_UINT8(port+SER_16550_IER, _ier); + + (chan->callbacks->xmt_char)(chan); +} + +// Disable the transmitter on the device +static void +cogent_serial_stop_xmit(serial_channel *chan) +{ + cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; + cyg_addrword_t port = cogent_chan->base; + cyg_uint8 _ier; + + HAL_READ_UINT8(port+SER_16550_IER, _ier); + _ier &= ~IER_XMT; // Disable xmit interrupt + HAL_WRITE_UINT8(port+SER_16550_IER, _ier); +} + +// Serial I/O - low level interrupt handler (ISR) +static cyg_uint32 +cogent_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(cogent_chan->int_num); + cyg_drv_interrupt_acknowledge(cogent_chan->int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level interrupt handler (DSR) +static void +cogent_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; + cyg_addrword_t port = cogent_chan->base; + cyg_uint8 _iir; + + HAL_READ_UINT8(port+SER_16550_IIR, _iir); + _iir &= SIO_IIR_ID_MASK; + if ( ISR_Tx == _iir ) { + (chan->callbacks->xmt_char)(chan); + } else if ( ISR_Rx == _iir ) { + cyg_uint8 _c; + HAL_READ_UINT8(port+SER_16550_RBR, _c); + (chan->callbacks->rcv_char)(chan, _c); + } + cyg_drv_interrupt_unmask(cogent_chan->int_num); +} +#endif diff --git a/packages/devs/serial/powerpc/quicc/current/ChangeLog b/packages/devs/serial/powerpc/quicc/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/powerpc/quicc/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_quicc_smc.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/powerpc/quicc/current/cdl/ser_quicc_smc.cdl b/packages/devs/serial/powerpc/quicc/current/cdl/ser_quicc_smc.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/powerpc/quicc/current/cdl/ser_quicc_smc.cdl @@ -0,0 +1,280 @@ +# ==================================================================== +# +# ser_quicc_smc.cdl +# +# eCos serial PowerPC/QUICC SMC configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-14 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC { + display "PowerPC QUICC/SMC serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_QUICC + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + PowerPC QUICC/SMC." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a quicc_smc_serial.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 { + display "PowerPC QUICC/SMC serial port 1 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the PowerPC + QUICC/SMC port 1." + + cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME { + display "Device name for PowerPC QUICC/SMC serial port 1" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the device name for the PowerPC + QUICC/SMC port 1." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BAUD { + display "Baud rate for the PowerPC QUICC/SMC serial port 1" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + PowerPC QUICC/SMC port 1." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE { + display "Buffer size for the PowerPC QUICC/SMC serial port 1" + flavor data + legal_values 0 to 8192 + default_value 256 + description " + This option specifies the size of the internal buffers used + for the PowerPC QUICC/SMC port 1." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BRG { + display "Which baud rate generator to use for the PowerPC QUICC/SMC serial port 1" + flavor data + legal_values 1 to 4 + default_value 1 + description " + This option specifies which of the four baud rate generators + to use for the PowerPC QUICC/SMC port 1." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE { + display "Output buffer size for the PowerPC QUICC/SMC serial port 1" + flavor data + legal_values 16 to 128 + default_value 16 + description " + This option specifies the maximum number of characters per + transmit request to be used for the PowerPC QUICC/SMC port 1." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM { + display "Number of output buffers for the PowerPC QUICC/SMC serial port 1" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of output buffer packets + to be used for the PowerPC QUICC/SMC port 1." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE { + display "Input buffer size for the PowerPC QUICC/SMC serial port 1" + flavor data + legal_values 16 to 128 + default_value 16 + description " + This option specifies the maximum number of characters per receive + request to be used for the PowerPC QUICC/SMC port 1." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM { + display "Number of input buffers for the PowerPC QUICC/SMC serial port 1" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of input buffer packets + to be used for the PowerPC QUICC/SMC port 1." + } +} + +cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 { + display "PowerPC QUICC/SMC serial port 2 driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the PowerPC + QUICC/SMC port 2." + + cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_NAME { + display "Device name for PowerPC QUICC/SMC serial port 2" + flavor data + default_value {"\"/dev/ser2\""} + description " + This option specifies the device name for the PowerPC + QUICC/SMC port 2." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BAUD { + display "Baud rate for the PowerPC QUICC/SMC serial port 2" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + PowerPC QUICC/SMC port 2." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE { + display "Buffer size for the PowerPC QUICC/SMC serial port 2" + flavor data + legal_values 0 to 8192 + default_value 256 + description " + This option specifies the size of the internal buffers used + for the PowerPC QUICC/SMC port 2." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BRG { + display "Which baud rate generator to use for the PowerPC QUICC/SMC serial port 2" + flavor data + legal_values 1 to 4 + default_value 2 + description " + This option specifies which of the four baud rate generators + to use for the PowerPC QUICC/SMC port 2." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE { + display "Output buffer size for the PowerPC QUICC/SMC serial port 2" + flavor data + legal_values 16 to 128 + default_value 16 + description " + This option specifies the maximum number of characters per + transmit request to be used for the PowerPC QUICC/SMC port 2." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM { + display "Number of output buffers for the PowerPC QUICC/SMC serial port 2" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of output buffer packets + to be used for the PowerPC QUICC/SMC port 2." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE { + display "Input buffer size for the PowerPC QUICC/SMC serial port 2" + flavor data + legal_values 16 to 128 + default_value 16 + description " + This option specifies the maximum number of characters per receive + request to be used for the PowerPC QUICC/SMC port 2." + } + + cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM { + display "Number of output buffers for the PowerPC QUICC/SMC serial port 2" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of input buffer packets + to be used for the PowerPC QUICC/SMC port 2." + } +} + + cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_quicc_smc.cdl diff --git a/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c b/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.c @@ -0,0 +1,743 @@ +//========================================================================== +// +// io/serial/powerpc/quicc_smc_serial.c +// +// PowerPC QUICC (SMC) Serial I/O Interface Module (interrupt driven) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-06-20 +// Purpose: QUICC SMC Serial I/O module (interrupt driven version) +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include CYGBLD_HAL_PLATFORM_H + +#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC + +// Buffer descriptor control bits +#define QUICC_BD_CTL_Ready 0x8000 // Buffer contains data (tx) or is empty (rx) +#define QUICC_BD_CTL_Wrap 0x2000 // Last buffer in list +#define QUICC_BD_CTL_Int 0x1000 // Generate interrupt when empty (tx) or full (rx) +#define QUICC_BD_CTL_MASK 0xB000 // User settable bits + +// SMC Mode Register +#define QUICC_SMCMR_CLEN(n) ((n+1)<<11) // Character length +#define QUICC_SMCMR_SB(n) ((n-1)<<10) // Stop bits (1 or 2) +#define QUICC_SMCMR_PE(n) (n<<9) // Parity enable (0=disable, 1=enable) +#define QUICC_SMCMR_PM(n) (n<<8) // Parity mode (0=odd, 1=even) +#define QUICC_SMCMR_UART (2<<4) // UART mode +#define QUICC_SMCMR_TEN (1<<1) // Enable transmitter +#define QUICC_SMCMR_REN (1<<0) // Enable receiver + +// SMC Events (interrupts) +#define QUICC_SMCE_BRK 0x10 // Break received +#define QUICC_SMCE_BSY 0x04 // Busy - receive buffer overrun +#define QUICC_SMCE_TX 0x02 // Tx interrupt +#define QUICC_SMCE_RX 0x01 // Rx interrupt + +// SMC Commands +#define QUICC_SMC_CMD_InitTxRx (0<<8) +#define QUICC_SMC_CMD_InitTx (1<<8) +#define QUICC_SMC_CMD_InitRx (2<<8) +#define QUICC_SMC_CMD_StopTx (4<<8) +#define QUICC_SMC_CMD_RestartTx (6<<8) +#define QUICC_SMC_CMD_Reset 0x8000 +#define QUICC_SMC_CMD_Go 0x0001 + +#include "quicc_smc_serial.h" + +typedef struct quicc_smc_serial_info { + CYG_ADDRWORD channel; // Which channel SMC1/SMC2 + CYG_WORD int_num; // Interrupt number + cyg_uint32 *brg; // Which baud rate generator + volatile struct smc_uart_pram *pram; // Parameter RAM pointer + volatile struct smc_regs *ctl; // SMC control registers + volatile struct cp_bufdesc *txbd, *rxbd; // Next Tx,Rx descriptor to use + struct cp_bufdesc *tbase, *rbase; // First Tx,Rx descriptor + int txsize, rxsize; // Length of individual buffers + cyg_interrupt serial_interrupt; + cyg_handle_t serial_interrupt_handle; + bool tx_enabled; +} quicc_smc_serial_info; + +static bool quicc_smc_serial_init(struct cyg_devtab_entry *tab); +static bool quicc_smc_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo quicc_smc_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char quicc_smc_serial_getc(serial_channel *chan); +static bool quicc_smc_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void quicc_smc_serial_start_xmit(serial_channel *chan); +static void quicc_smc_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 quicc_smc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void quicc_smc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(quicc_smc_serial_funs, + quicc_smc_serial_putc, + quicc_smc_serial_getc, + quicc_smc_serial_set_config, + quicc_smc_serial_start_xmit, + quicc_smc_serial_stop_xmit + ); + +#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 +static quicc_smc_serial_info quicc_smc_serial_info1 = { + 0x90, // Channel indicator + CYGNUM_HAL_INTERRUPT_CPM_SMC1 // interrupt +}; +#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE > 0 +static unsigned char quicc_smc_serial_out_buf1[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE]; +static unsigned char quicc_smc_serial_in_buf1[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_smc_serial_channel1, + quicc_smc_serial_funs, + quicc_smc_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &quicc_smc_serial_out_buf1[0], sizeof(quicc_smc_serial_out_buf1), + &quicc_smc_serial_in_buf1[0], sizeof(quicc_smc_serial_in_buf1) + ); +#else +static SERIAL_CHANNEL(quicc_smc_serial_channel1, + quicc_smc_serial_funs, + quicc_smc_serial_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +static unsigned char quicc_smc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE]; +static unsigned char quicc_smc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE]; + +DEVTAB_ENTRY(quicc_smc_serial_io1, + CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + quicc_smc_serial_init, + quicc_smc_serial_lookup, // Serial driver may need initializing + &quicc_smc_serial_channel1 + ); +#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 + +#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 +static quicc_smc_serial_info quicc_smc_serial_info2 = { + 0xD0, // Channel indicator + CYGNUM_HAL_INTERRUPT_CPM_SMC2_PIP // interrupt +}; +#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE > 0 +static unsigned char quicc_smc_serial_out_buf2[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE]; +static unsigned char quicc_smc_serial_in_buf2[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_smc_serial_channel2, + quicc_smc_serial_funs, + quicc_smc_serial_info2, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &quicc_smc_serial_out_buf2[0], sizeof(quicc_smc_serial_out_buf2), + &quicc_smc_serial_in_buf2[0], sizeof(quicc_smc_serial_in_buf2) + ); +#else +static SERIAL_CHANNEL(quicc_smc_serial_channel2, + quicc_smc_serial_funs, + quicc_smc_serial_info2, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif +static unsigned char quicc_smc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE]; +static unsigned char quicc_smc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE]; + +DEVTAB_ENTRY(quicc_smc_serial_io2, + CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + quicc_smc_serial_init, + quicc_smc_serial_lookup, // Serial driver may need initializing + &quicc_smc_serial_channel2 + ); +#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 + +#ifdef CYGDBG_DIAG_BUF +extern int enable_diag_uart; +#endif // CYGDBG_DIAG_BUF + +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool +quicc_smc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; + unsigned int baud_divisor = select_baud[new_config->baud]; + cyg_uint32 _lcr; + EPPC *eppc = eppc_base(); + if (baud_divisor == 0) return false; + // Disable channel during setup + smc_chan->ctl->smc_smcmr = QUICC_SMCMR_UART; // Disabled, UART mode + // Disable port interrupts while changing hardware + _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | + select_stop_bits[new_config->stop] | + select_parity[new_config->parity]; + // Stop transmitter while changing baud rate + eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_StopTx; + // Set baud rate generator + *smc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1); +#ifdef XX_CYGDBG_DIAG_BUF + enable_diag_uart = 0; + diag_printf("Set BAUD RATE[%x], %d = %x, tstate = %x\n", smc_chan->brg, baud_divisor, *smc_chan->brg, smc_chan->pram->tstate); + enable_diag_uart = 1; +#endif // CYGDBG_DIAG_BUF + + // Enable channel with new configuration + smc_chan->ctl->smc_smcmr = QUICC_SMCMR_UART|QUICC_SMCMR_TEN|QUICC_SMCMR_REN|_lcr; + eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_RestartTx; + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +// Function to set up internal tables for device. +static void +quicc_smc_serial_init_info(quicc_smc_serial_info *smc_chan, + volatile struct smc_uart_pram *uart_pram, + volatile struct smc_regs *ctl, + int TxBD, int TxNUM, int TxSIZE, + cyg_uint8 *TxBUF, + int RxBD, int RxNUM, int RxSIZE, + cyg_uint8 *RxBUF, + int portBmask, + int BRG, int SIpos) +{ + EPPC *eppc = eppc_base(); + struct cp_bufdesc *txbd, *rxbd; + cyg_uint32 simode = 0; + int i; + + // Disable channel during setup + ctl->smc_smcmr = QUICC_SMCMR_UART; // Disabled, UART mode + smc_chan->pram = uart_pram; + smc_chan->ctl = ctl; + /* + * SDMA & LCD bus request level 5 + * (Section 16.10.2.1) + */ + eppc->dma_sdcr = 1; + switch (BRG) { + case 1: + smc_chan->brg = (cyg_uint32 *)&eppc->brgc1; + simode = 0; + break; + case 2: + smc_chan->brg = (cyg_uint32 *)&eppc->brgc2; + simode = 1; + break; + case 3: + smc_chan->brg = (cyg_uint32 *)&eppc->brgc3; + simode = 2; + break; + case 4: + smc_chan->brg = (cyg_uint32 *)&eppc->brgc4; + simode = 3; + break; + } + // NMSI mode, BRGn to SMCm (Section 16.12.5.2) + eppc->si_simode = (eppc->si_simode & ~(0xF<pip_pbpar |= portBmask; + eppc->pip_pbdir &= ~portBmask; + /* + * Reset Rx & Tx params + */ + eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_InitTxRx; + /* + * SDMA & LCD bus request level 5 + * (Section 16.10.2.1) + */ + eppc->dma_sdcr = 1; + /* + * Set Rx and Tx function code + * (Section 16.15.4.2) + */ + uart_pram->rfcr = 0x18; + uart_pram->tfcr = 0x18; + /* + * Set pointers to buffer descriptors. + * (Sections 16.15.4.1, 16.15.7.12, and 16.15.7.13) + */ + uart_pram->rbase = RxBD; + uart_pram->tbase = TxBD; + /* tx and rx buffer descriptors */ + txbd = (struct cp_bufdesc *)((char *)eppc + TxBD); + rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD); + smc_chan->txbd = txbd; + smc_chan->tbase = txbd; + smc_chan->txsize = TxSIZE; + smc_chan->rxbd = rxbd; + smc_chan->rbase = rxbd; + smc_chan->rxsize = RxSIZE; + /* max receive buffer length */ + uart_pram->mrblr = RxSIZE; + /* set max_idle feature - generate interrupt after 4 chars idle period */ + uart_pram->max_idl = 4; + /* no last brk char received */ + uart_pram->brkln = 0; + /* no break condition occurred */ + uart_pram->brkec = 0; + /* 1 break char sent on top XMIT */ + uart_pram->brkcr = 1; + /* setup RX buffer descriptors */ + for (i = 0; i < RxNUM; i++) { + rxbd->length = 0; + rxbd->buffer = RxBUF; + rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int; + if (i == (RxNUM-1)) rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer + RxBUF += RxSIZE; + rxbd++; + } + /* setup TX buffer descriptors */ + for (i = 0; i < TxNUM; i++) { + txbd->length = 0; + txbd->buffer = TxBUF; + txbd->ctrl = 0; + if (i == (TxNUM-1)) txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer + TxBUF += TxSIZE; + txbd++; + } + /* + * Clear any previous events. Enable interrupts. + * (Section 16.15.7.14 and 16.15.7.15) + */ + ctl->smc_smce = 0xFF; + ctl->smc_smcm = QUICC_SMCE_BSY|QUICC_SMCE_TX|QUICC_SMCE_RX; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +quicc_smc_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; + volatile EPPC *eppc = (volatile EPPC *)eppc_base(); + int TxBD, RxBD; + static int first_init = 1; + int cache_state; + HAL_DCACHE_IS_ENABLED(cache_state); + HAL_DCACHE_SYNC(); + HAL_DCACHE_DISABLE(); +#ifdef CYGDBG_IO_INIT + diag_printf("QUICC_SMC SERIAL init - dev: %x.%d\n", smc_chan->channel, smc_chan->int_num); +#endif + if (first_init) { + // Set up tables since many fields are dynamic [computed at runtime] + first_init = 0; +#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 + eppc->cp_cr = QUICC_SMC_CMD_Reset | QUICC_SMC_CMD_Go; // Totally reset CP + while (eppc->cp_cr & QUICC_SMC_CMD_Reset) ; + TxBD = 0x2800; // Note: this should be configurable + RxBD = TxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM*8; + quicc_smc_serial_init_info(&quicc_smc_serial_info1, + &eppc->pram[2].scc.pothers.smc_modem.psmc.u, // PRAM + &eppc->smc_regs[0], // Control registers + TxBD, + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM, + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE, + &quicc_smc1_txbuf[0][0], + RxBD, + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM, + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE, + &quicc_smc1_rxbuf[0][0], + 0xC0, // PortB mask + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BRG, + 12 // SI mask position + ); + TxBD = RxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM*8; +#else +#ifdef CYGPKG_HAL_POWERPC_MBX + // Ensure the SMC1 side is initialized first and use shared mem + // above where it plays: + diag_init(); // (pull in constructor that inits diag channel) + TxBD = 0x2830; // Note: this should be inferred from the chip state +#else + // there is no diag device wanting to use the QUICC, so prepare it + // for SMC2 use only. + eppc->cp_cr = QUICC_SMC_CMD_Reset | QUICC_SMC_CMD_Go; // Totally reset CP + while (eppc->cp_cr & QUICC_SMC_CMD_Reset) ; + TxBD = 0x2800; // Note: this should be configurable +#endif +#endif +#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 + RxBD = TxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM*8; + quicc_smc_serial_init_info(&quicc_smc_serial_info2, + &eppc->pram[3].scc.pothers.smc_modem.psmc.u, // PRAM + &eppc->smc_regs[1], // Control registers + TxBD, + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM, + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE, + &quicc_smc2_txbuf[0][0], + RxBD, + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM, + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE, + &quicc_smc2_rxbuf[0][0], + 0xC00, // PortB mask + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BRG, + 28 // SI mask position + ); +#endif + } + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (chan->out_cbuf.len != 0) { + cyg_drv_interrupt_create(smc_chan->int_num, + CYGARC_SIU_PRIORITY_HIGH, // Priority - unused (but asserted) + (cyg_addrword_t)chan, // Data item passed to interrupt handler + quicc_smc_serial_ISR, + quicc_smc_serial_DSR, + &smc_chan->serial_interrupt_handle, + &smc_chan->serial_interrupt); + cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle); + cyg_drv_interrupt_mask(smc_chan->int_num); + smc_chan->tx_enabled = false; + } + quicc_smc_serial_config_port(chan, &chan->config, true); + if (cache_state) + HAL_DCACHE_ENABLE(); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +quicc_smc_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +// Force the current transmit buffer to be sent +static void +quicc_smc_serial_flush(quicc_smc_serial_info *smc_chan) +{ + volatile struct cp_bufdesc *txbd = smc_chan->txbd; + if ((txbd->length > 0) && ((txbd->ctrl & QUICC_BD_CTL_Ready) == 0)) { + txbd->ctrl |= QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int; // Signal buffer ready + if (txbd->ctrl & QUICC_BD_CTL_Wrap) { + txbd = smc_chan->tbase; + } else { + txbd++; + } + smc_chan->txbd = txbd; + } +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +quicc_smc_serial_putc(serial_channel *chan, unsigned char c) +{ + quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; + volatile struct cp_bufdesc *txbd, *txfirst; + EPPC *eppc = eppc_base(); + bool res; + cyg_drv_dsr_lock(); // Avoid race condition testing pointers + txbd = (struct cp_bufdesc *)((char *)eppc + smc_chan->pram->tbptr); + txfirst = txbd; + // Scan for a non-busy buffer + while (txbd->ctrl & QUICC_BD_CTL_Ready) { + // This buffer is busy, move to next one + if (txbd->ctrl & QUICC_BD_CTL_Wrap) { + txbd = smc_chan->tbase; + } else { + txbd++; + } + if (txbd == txfirst) break; // Went all the way around + } + smc_chan->txbd = txbd; + if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == 0) { + // Transmit buffer is not full/busy + txbd->buffer[txbd->length++] = c; + if (txbd->length == smc_chan->txsize) { + // This buffer is now full, tell SMC to start processing it + quicc_smc_serial_flush(smc_chan); + } + res = true; + } else { + // No space + res = false; + } + cyg_drv_dsr_unlock(); + return res; +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +quicc_smc_serial_getc(serial_channel *chan) +{ + unsigned char c; + quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; + volatile struct cp_bufdesc *rxbd = smc_chan->rxbd; + while ((rxbd->ctrl & QUICC_BD_CTL_Ready) != 0) ; + c = rxbd->buffer[0]; + rxbd->length = smc_chan->rxsize; + rxbd->ctrl |= QUICC_BD_CTL_Ready; + if (rxbd->ctrl & QUICC_BD_CTL_Wrap) { + rxbd = smc_chan->rbase; + } else { + rxbd++; + } + smc_chan->rxbd = (struct cp_bufdesc *)rxbd; + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +quicc_smc_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + bool res = quicc_smc_serial_config_port(chan, config, false); + // FIXME - The documentation says that you can't change the baud rate + // again until at least two BRG input clocks have occurred. + return res; +} + +// Enable the transmitter (interrupt) on the device +static void +quicc_smc_serial_start_xmit(serial_channel *chan) +{ + quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; + if (smc_chan->txbd->length == 0) { + // See if there is anything to put in this buffer, just to get it going + cyg_drv_dsr_lock(); + (chan->callbacks->xmt_char)(chan); + cyg_drv_dsr_unlock(); + } + if (smc_chan->txbd->length != 0) { + // Make sure it gets started + quicc_smc_serial_flush(smc_chan); + } + smc_chan->tx_enabled = true; + cyg_drv_interrupt_unmask(smc_chan->int_num); +} + +// Disable the transmitter on the device +static void +quicc_smc_serial_stop_xmit(serial_channel *chan) +{ + quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; + // If anything is in the last buffer, need to get it started + if (smc_chan->txbd->length != 0) { + quicc_smc_serial_flush(smc_chan); + // Note: interrupt will get masked after this buffer finishes + } else { + cyg_drv_interrupt_mask(smc_chan->int_num); + } + smc_chan->tx_enabled = false; +} + +// Serial I/O - low level interrupt handler (ISR) +static cyg_uint32 +quicc_smc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; + cyg_drv_interrupt_mask(smc_chan->int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level interrupt handler (DSR) +static void +quicc_smc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; + volatile struct smc_regs *ctl = smc_chan->ctl; + volatile struct cp_bufdesc *txbd; + volatile struct cp_bufdesc *rxbd = smc_chan->rxbd; + struct cp_bufdesc *rxlast; + int i, cache_state; +#ifdef CYGDBG_DIAG_BUF + int _time, _stime; + externC cyg_tick_count_t cyg_current_time(void); + cyg_drv_isr_lock(); + enable_diag_uart = 0; + HAL_CLOCK_READ(&_time); + _stime = (int)cyg_current_time(); + diag_printf("DSR start - CE: %x, time: %x.%x\n", ctl->smc_smce, _stime, _time); + enable_diag_uart = 1; +#endif // CYGDBG_DIAG_BUF + if (ctl->smc_smce & QUICC_SMCE_TX) { +#ifdef XX_CYGDBG_DIAG_BUF + enable_diag_uart = 0; + txbd = smc_chan->tbase; + for (i = 0; i < CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM; i++, txbd++) { + diag_printf("Tx BD: %x, length: %d, ctl: %x\n", txbd, txbd->length, txbd->ctrl); + } + enable_diag_uart = 1; +#endif // CYGDBG_DIAG_BUF + // Transmit interrupt + ctl->smc_smce = QUICC_SMCE_TX; // Reset interrupt state; + txbd = smc_chan->tbase; // First buffer + while (true) { + if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) { +#ifdef XX_CYGDBG_DIAG_BUF + enable_diag_uart = 0; + HAL_CLOCK_READ(&_time); + _stime = (int)cyg_current_time(); + diag_printf("TX Done - Tx: %x, length: %d, time: %x.%x\n", txbd, txbd->length, _stime, _time); + enable_diag_uart = 1; +#endif // CYGDBG_DIAG_BUF + txbd->length = 0; + txbd->ctrl &= ~QUICC_BD_CTL_Int; // Reset interrupt bit + } + if (txbd->ctrl & QUICC_BD_CTL_Wrap) { + txbd = smc_chan->tbase; + break; + } else { + txbd++; + } + } + (chan->callbacks->xmt_char)(chan); + } + while (ctl->smc_smce & QUICC_SMCE_RX) { + // Receive interrupt + ctl->smc_smce = QUICC_SMCE_RX; // Reset interrupt state; + rxlast = (struct cp_bufdesc *) ( + (char *)eppc_base() + smc_chan->pram->rbptr ); +#ifdef CYGDBG_DIAG_BUF + enable_diag_uart = 0; + HAL_CLOCK_READ(&_time); + _stime = (int)cyg_current_time(); + diag_printf("Scan RX - rxbd: %x, rbptr: %x, time: %x.%x\n", rxbd, rxlast, _stime, _time); +#endif // CYGDBG_DIAG_BUF + while (rxbd != rxlast) { + if ((rxbd->ctrl & QUICC_BD_CTL_Ready) == 0) { +#ifdef CYGDBG_DIAG_BUF + diag_printf("rxbuf: %x, flags: %x, length: %d\n", rxbd, rxbd->ctrl, rxbd->length); + diag_dump_buf(rxbd->buffer, rxbd->length); +#endif // CYGDBG_DIAG_BUF + for (i = 0; i < rxbd->length; i++) { + (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]); + } + // Note: the MBX860 does not seem to snoop/invalidate the data cache properly! + HAL_DCACHE_IS_ENABLED(cache_state); + if (cache_state) { + HAL_DCACHE_INVALIDATE(rxbd->buffer, smc_chan->rxsize); // Make sure no stale data + } + rxbd->length = 0; + rxbd->ctrl |= QUICC_BD_CTL_Ready; + } + if (rxbd->ctrl & QUICC_BD_CTL_Wrap) { + rxbd = smc_chan->rbase; + } else { + rxbd++; + } + } +#ifdef CYGDBG_DIAG_BUF + enable_diag_uart = 1; +#endif // CYGDBG_DIAG_BUF + smc_chan->rxbd = (struct cp_bufdesc *)rxbd; + } + if (ctl->smc_smce & QUICC_SMCE_BSY) { +#ifdef CYGDBG_DIAG_BUF + enable_diag_uart = 0; + diag_printf("RX BUSY interrupt\n"); + enable_diag_uart = 1; +#endif // CYGDBG_DIAG_BUF + ctl->smc_smce = QUICC_SMCE_BSY; // Reset interrupt state; + } +#ifdef CYGDBG_DIAG_BUF + enable_diag_uart = 0; + HAL_CLOCK_READ(&_time); + _stime = (int)cyg_current_time(); + diag_printf("DSR done - CE: %x, time: %x.%x\n", ctl->smc_smce, _stime, _time); + enable_diag_uart = 1; +#endif // CYGDBG_DIAG_BUF + cyg_drv_interrupt_acknowledge(smc_chan->int_num); + cyg_drv_interrupt_unmask(smc_chan->int_num); +#ifdef CYGDBG_DIAG_BUF + cyg_drv_isr_unlock(); +#endif // CYGDBG_DIAG_BUF +} + +void +show_rxbd(int dump_all) +{ +#ifdef CYGDBG_DIAG_BUF + EPPC *eppc = eppc_base(); + struct smc_uart_pram *pram = &eppc->pram[2].scc.pothers.smc_modem.psmc.u; + struct cp_bufdesc *rxbd = (struct cp_bufdesc *)((char *)eppc+pram->rbase); + int _enable = enable_diag_uart; + enable_diag_uart = 0; +#if 1 + diag_printf("SMC Mask: %x, Events: %x, Rbase: %x, Rbptr: %x\n", + eppc->smc_regs[0].smc_smcm, eppc->smc_regs[0].smc_smce, + pram->rbase, pram->rbptr); + while (true) { + diag_printf("Rx BD: %x, ctl: %x, length: %d\n", rxbd, rxbd->ctrl, rxbd->length); + if (rxbd->ctrl & QUICC_BD_CTL_Wrap) break; + rxbd++; + } +#endif + enable_diag_uart = _enable; + if (dump_all) dump_diag_buf(); +#endif // CYGDBG_DIAG_BUF +} +#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC + +// ------------------------------------------------------------------------ +// EOF powerpc/quicc_smc_serial.c diff --git a/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.h b/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.h new file mode 100644 --- /dev/null +++ b/packages/devs/serial/powerpc/quicc/current/src/quicc_smc_serial.h @@ -0,0 +1,103 @@ +#ifndef CYGONCE_POWERPC_QUICC_SMC_SERIAL_H +#define CYGONCE_POWERPC_QUICC_SMC_SERIAL_H + +// ==================================================================== +// +// quicc_smc_serial.h +// +// Device I/O - Description of PowerPC QUICC/SMC serial hardware +// +// ==================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +// ==================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-06-21 +// Purpose: Internal interfaces for serial I/O drivers +// Description: +// +//####DESCRIPTIONEND#### +// +// ==================================================================== + +// Description of serial ports using QUICC/SMC + +#include // QUICC structure definitions + +static unsigned int select_word_length[] = { + QUICC_SMCMR_CLEN(5), // 5 bits / word (char) + QUICC_SMCMR_CLEN(6), + QUICC_SMCMR_CLEN(7), + QUICC_SMCMR_CLEN(8) +}; + +static unsigned int select_stop_bits[] = { + 0, + QUICC_SMCMR_SB(1), // 1 stop bit + QUICC_SMCMR_SB(1), // 1.5 stop bit + QUICC_SMCMR_SB(2) // 2 stop bits +}; + +static unsigned int select_parity[] = { + QUICC_SMCMR_PE(0), // No parity + QUICC_SMCMR_PE(1)|QUICC_SMCMR_PM(1), // Even parity + QUICC_SMCMR_PE(1)|QUICC_SMCMR_PM(0), // Odd parity + 0, // Mark parity + 0, // Space parity +}; + +// Baud rate values, based on board clock + +static cyg_int32 select_baud[] = { + 0, // Unused + 50, // 50 + 75, // 75 + 110, // 110 + 0, // 134.5 + 150, // 150 + 200, // 200 + 300, // 300 + 600, // 600 + 1200, // 1200 + 1800, // 1800 + 2400, // 2400 + 3600, // 3600 + 4800, // 4800 + 7200, // 7200 + 9600, // 9600 + 14400, // 14400 + 19200, // 19200 + 38400, // 38400 + 57600, // 57600 + 115200, // 115200 + 0, // 230400 +}; + +#define UART_BITRATE(n) (((CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000)/16)/n) +#define UART_SLOW_BITRATE(n) ((CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000)/n)) + +#endif // CYGONCE_POWERPC_QUICC_SMC_SERIAL_H diff --git a/packages/devs/serial/sh/edk7708/current/ChangeLog b/packages/devs/serial/sh/edk7708/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/sh/edk7708/current/ChangeLog @@ -0,0 +1,1168 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_sh_edk7708.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-11 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Move compile statement into a + sub-component. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/sh/edk7708/current/cdl/ser_sh_edk7708.cdl b/packages/devs/serial/sh/edk7708/current/cdl/ser_sh_edk7708.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/sh/edk7708/current/cdl/ser_sh_edk7708.cdl @@ -0,0 +1,136 @@ +# ==================================================================== +# +# ser_sh_edk7708.cdl +# +# eCos serial SH/EDK7708 configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Contributors: +# Date: 1999-07-08 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + + +cdl_package CYGPKG_IO_SERIAL_SH_EDK7708 { + display "SH3 EDK7708 serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_SH_EDK7708 + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + Hitachi SH3 EDK7708 board." + doc redirect/ecos-device-drivers.html + + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_SH_EDK7708_SCI { + display "SH3 EDK7708 SCI device driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the SCI port." + + compile -library=libextras.a sh_sci_serial.c + + cdl_option CYGDAT_IO_SERIAL_SH_EDK7708_SCI_NAME { + display "Device name for SH3 EDK7708 SCI" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the device name for the SCI port." + } + + cdl_option CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BAUD { + display "Baud rate for the SH SCI driver" + flavor data + legal_values { 4800 9600 14400 19200 38400 57600 115200 } + default_value 38400 + description " + This option specifies the default baud rate (speed) for the + SCI port." + } + + cdl_option CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BUFSIZE { + display "Buffer size for the SH SCI driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used for + the SCI port." + } +} + + cdl_component CYGPKG_IO_SERIAL_SH_EDK7708_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_SH_EDK7708_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_SH_EDK7708_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_sh_edk7708.cdl diff --git a/packages/devs/serial/sh/edk7708/current/src/sh_sci_7708.inl b/packages/devs/serial/sh/edk7708/current/src/sh_sci_7708.inl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/sh/edk7708/current/src/sh_sci_7708.inl @@ -0,0 +1,97 @@ +//========================================================================== +// +// io/serial/sh/sh_sci_7708.c +// +// Serial I/O Interface Module definitions for SH3/7708 +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov +// Contributors:jskov +// Date: 1999-06-16 +// Purpose: Defines SCI serial resources for SH3/7708. +// Description: +// +//####DESCRIPTIONEND#### +//========================================================================== + +// Controller bases in the SH3/7708 (only one) +#define SH_SERIAL_SCI_BASE 0xfffffe80 + +// The SCI controller register layout on the SH3/7708. +#define SCI_SCSMR 0 // serial mode register +#define SCI_SCBRR 2 // bit rate register +#define SCI_SCSCR 4 // serial control register +#define SCI_SCTDR 6 // transmit data register +#define SCI_SCSSR 8 // serial status register +#define SCI_SCRDR 10 // receive data register +#define SCI_SCSPTR -4 // serial port register + +static sh_sci_info sh_serial_info = {CYGARC_REG_SCSPTR, + CYGNUM_HAL_INTERRUPT_SCI_ERI, + CYGNUM_HAL_INTERRUPT_SCI_RXI, + CYGNUM_HAL_INTERRUPT_SCI_TXI, + SH_SERIAL_SCI_BASE}; + +#if CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BUFSIZE > 0 +static unsigned char sh_serial_out_buf[CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BUFSIZE]; +static unsigned char sh_serial_in_buf[CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(sh_serial_channel, + sh_serial_funs, + sh_serial_info, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &sh_serial_out_buf[0], + sizeof(sh_serial_out_buf), + &sh_serial_in_buf[0], + sizeof(sh_serial_in_buf) + ); +#else +static SERIAL_CHANNEL(sh_serial_channel, + sh_serial_funs, + sh_serial_info, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(sh_serial_io, + CYGDAT_IO_SERIAL_SH_EDK7708_SCI_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + sh_serial_init, + sh_serial_lookup, // Serial driver may need initializing + &sh_serial_channel + ); diff --git a/packages/devs/serial/sh/edk7708/current/src/sh_sci_serial.c b/packages/devs/serial/sh/edk7708/current/src/sh_sci_serial.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/sh/edk7708/current/src/sh_sci_serial.c @@ -0,0 +1,496 @@ +//========================================================================== +// +// io/serial/sh/sh_sci_serial.c +// +// SH Serial SCI I/O Interface Module (interrupt driven) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov +// Contributors:gthomas, jskov +// Date: 1999-05-24 +// Purpose: SH Serial I/O module (interrupt driven version) +// Description: +// +// Note: Since interrupt sources from the same SCI channel share the same +// interrupt level, there is no risk of races when altering the +// channel's control register from ISRs and DSRs. However, when +// altering the control register from user-level code, interrupts +// must be disabled while the register is being accessed. +// +// FIXME: Receiving in polled mode prevents duplex transfers from working for +// some reason. +//####DESCRIPTIONEND#### +//========================================================================== + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef CYGPKG_IO_SERIAL_SH_EDK7708 +#define __CYGPKG_IO_SERIAL_SH_SCI_INL "sh_sci_7708.inl" +#endif + + +// Only compile driver if an inline file with driver details was selected. +#ifdef __CYGPKG_IO_SERIAL_SH_SCI_INL + +static short select_word_length[] = { + -1, + -1, + CYGARC_REG_SCSMR_CHR, // 7 bits + 0 // 8 bits +}; + +static short select_stop_bits[] = { + -1, + 0, // 1 stop bit + -1, + CYGARC_REG_SCSMR_STOP // 2 stop bits +}; + +static short select_parity[] = { + 0, // No parity + CYGARC_REG_SCSMR_PE, // Even parity + CYGARC_REG_SCSMR_PE|CYGARC_REG_SCSMR_OE, // Odd parity + -1, + -1 +}; + +static unsigned short select_baud[] = { + 0, // Unused + CYGARC_SCBRR_CKSx(50)<<8 | CYGARC_SCBRR_N(50), + CYGARC_SCBRR_CKSx(75)<<8 | CYGARC_SCBRR_N(75), + CYGARC_SCBRR_CKSx(110)<<8 | CYGARC_SCBRR_N(110), + CYGARC_SCBRR_CKSx(134)<<8 | CYGARC_SCBRR_N(134), + CYGARC_SCBRR_CKSx(150)<<8 | CYGARC_SCBRR_N(150), + CYGARC_SCBRR_CKSx(200)<<8 | CYGARC_SCBRR_N(200), + CYGARC_SCBRR_CKSx(300)<<8 | CYGARC_SCBRR_N(300), + CYGARC_SCBRR_CKSx(600)<<8 | CYGARC_SCBRR_N(600), + CYGARC_SCBRR_CKSx(1200)<<8 | CYGARC_SCBRR_N(1200), + CYGARC_SCBRR_CKSx(1800)<<8 | CYGARC_SCBRR_N(1800), + CYGARC_SCBRR_CKSx(2400)<<8 | CYGARC_SCBRR_N(2400), + CYGARC_SCBRR_CKSx(3600)<<8 | CYGARC_SCBRR_N(3600), + CYGARC_SCBRR_CKSx(4800)<<8 | CYGARC_SCBRR_N(4800), + CYGARC_SCBRR_CKSx(7200)<<8 | CYGARC_SCBRR_N(7200), + CYGARC_SCBRR_CKSx(9600)<<8 | CYGARC_SCBRR_N(9600), + CYGARC_SCBRR_CKSx(14400)<<8 | CYGARC_SCBRR_N(14400), + CYGARC_SCBRR_CKSx(19200)<<8 | CYGARC_SCBRR_N(19200), + CYGARC_SCBRR_CKSx(38400)<<8 | CYGARC_SCBRR_N(38400), + CYGARC_SCBRR_CKSx(57600)<<8 | CYGARC_SCBRR_N(57600), + CYGARC_SCBRR_CKSx(115200)<<8 | CYGARC_SCBRR_N(115200), + CYGARC_SCBRR_CKSx(230400)<<8 | CYGARC_SCBRR_N(230400) +}; + + +typedef struct sh_sci_info { + CYG_ADDRWORD data; // Pointer to data register + + CYG_WORD er_int_num, // Error interrupt number + rx_int_num, // Receive interrupt number + tx_int_num; // Transmit interrupt number + + CYG_ADDRWORD ctrl_base; // Base address of SCI controller + + cyg_interrupt serial_er_interrupt, + serial_rx_interrupt, + serial_tx_interrupt; + cyg_handle_t serial_er_interrupt_handle, + serial_rx_interrupt_handle, + serial_tx_interrupt_handle; + + bool tx_enabled; +} sh_sci_info; + +static bool sh_serial_init(struct cyg_devtab_entry *tab); +static bool sh_serial_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo sh_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char sh_serial_getc(serial_channel *chan); +static bool sh_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void sh_serial_start_xmit(serial_channel *chan); +static void sh_serial_stop_xmit(serial_channel *chan); + +static cyg_uint32 sh_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void sh_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, + cyg_addrword_t data); +static cyg_uint32 sh_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void sh_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, + cyg_addrword_t data); +static cyg_uint32 sh_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void sh_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count, + cyg_addrword_t data); + +static SERIAL_FUNS(sh_serial_funs, + sh_serial_putc, + sh_serial_getc, + sh_serial_set_config, + sh_serial_start_xmit, + sh_serial_stop_xmit + ); + +#include __CYGPKG_IO_SERIAL_SH_SCI_INL + +// Internal function to actually configure the hardware to desired baud rate, +// etc. +static bool +sh_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, + bool init) +{ + cyg_uint16 baud_divisor = select_baud[new_config->baud]; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + cyg_uint8 _scr, _smr; + + // Check configuration request + if ((-1 == select_word_length[(new_config->word_length - + CYGNUM_SERIAL_WORD_LENGTH_5)]) + || -1 == select_stop_bits[new_config->stop] + || -1 == select_parity[new_config->parity] + || baud_divisor == 0) + return false; + + // Disable SCI interrupts while changing hardware + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, 0); + + // Set databits, stopbits and parity. + _smr = select_word_length[(new_config->word_length - + CYGNUM_SERIAL_WORD_LENGTH_5)] | + select_stop_bits[new_config->stop] | + select_parity[new_config->parity]; + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSMR, _smr); + + // Set baud rate. + _smr &= ~CYGARC_REG_SCSMR_CKSx_MASK; + _smr |= baud_divisor >> 8; + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSMR, _smr); + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCBRR, baud_divisor & 0xff); + + // Clear the status register. + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, 0); + + if (init) { + // Always enable transmitter and receiver. + _scr = CYGARC_REG_SCSCR_TE | CYGARC_REG_SCSCR_RE; + + if (chan->out_cbuf.len != 0) + _scr |= CYGARC_REG_SCSCR_TIE; // enable tx interrupts + + if (chan->in_cbuf.len != 0) + _scr |= CYGARC_REG_SCSCR_RIE; // enable rx interrupts + } + + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + + if (new_config != &chan->config) { + chan->config = *new_config; + } + return true; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +sh_serial_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; +#ifdef CYGDBG_IO_INIT + diag_printf("SH SERIAL init - dev: %x.%d\n", + sh_chan->data, sh_chan->rx_int_num); +#endif + // Really only required for interrupt driven devices + (chan->callbacks->serial_init)(chan); + + if (chan->out_cbuf.len != 0) { + cyg_drv_interrupt_create(sh_chan->tx_int_num, + 3, + (cyg_addrword_t)chan, // Data item passed to interrupt handler + sh_serial_tx_ISR, + sh_serial_tx_DSR, + &sh_chan->serial_tx_interrupt_handle, + &sh_chan->serial_tx_interrupt); + cyg_drv_interrupt_attach(sh_chan->serial_tx_interrupt_handle); + cyg_drv_interrupt_unmask(sh_chan->tx_int_num); + sh_chan->tx_enabled = false; + } + if (chan->in_cbuf.len != 0) { + // Receive interrupt + cyg_drv_interrupt_create(sh_chan->rx_int_num, + 3, + (cyg_addrword_t)chan, // Data item passed to interrupt handler + sh_serial_rx_ISR, + sh_serial_rx_DSR, + &sh_chan->serial_rx_interrupt_handle, + &sh_chan->serial_rx_interrupt); + cyg_drv_interrupt_attach(sh_chan->serial_rx_interrupt_handle); + // Receive error interrupt + cyg_drv_interrupt_create(sh_chan->er_int_num, + 3, + (cyg_addrword_t)chan, // Data item passed to interrupt handler + sh_serial_er_ISR, + sh_serial_er_DSR, + &sh_chan->serial_er_interrupt_handle, + &sh_chan->serial_er_interrupt); + cyg_drv_interrupt_attach(sh_chan->serial_er_interrupt_handle); + // This unmasks both interrupt sources. + cyg_drv_interrupt_unmask(sh_chan->rx_int_num); + } + sh_serial_config_port(chan, &chan->config, true); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +sh_serial_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + + // Really only required for interrupt driven devices + (chan->callbacks->serial_init)(chan); + return ENOERR; +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +sh_serial_putc(serial_channel *chan, unsigned char c) +{ + cyg_uint8 _ssr; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr); + if (_ssr & CYGARC_REG_SCSSR_TDRE) { +// Transmit buffer is empty + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCTDR, c); + // Clear empty flag. + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, + CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_TDRE); + return true; + } else { +// No space + return false; + } +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +sh_serial_getc(serial_channel *chan) +{ + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + unsigned char c; + cyg_uint8 _ssr; + + do { + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr); + } while ((_ssr & CYGARC_REG_SCSSR_RDRF) == 0); + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCRDR, c); + + // Clear buffer full flag. + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, + CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF); + + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +sh_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return sh_serial_config_port(chan, config, false); +} + +// Enable the transmitter on the device +static void +sh_serial_start_xmit(serial_channel *chan) +{ + cyg_uint8 _scr; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + + sh_chan->tx_enabled = true; + + // Mask the interrupts (all sources of the unit) while changing + // the CR since a rx interrupt in the middle of this would result + // in a bad CR state. + cyg_drv_interrupt_mask(sh_chan->rx_int_num); + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + _scr |= CYGARC_REG_SCSCR_TIE; // Enable xmit interrupt + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + + cyg_drv_interrupt_unmask(sh_chan->rx_int_num); +} + +// Disable the transmitter on the device +static void +sh_serial_stop_xmit(serial_channel *chan) +{ + cyg_uint8 _scr; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + + sh_chan->tx_enabled = false; + + // Mask the interrupts (all sources of the unit) while changing + // the CR since a rx interrupt in the middle of this would result + // in a bad CR state. + cyg_drv_interrupt_mask(sh_chan->rx_int_num); + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + _scr &= ~CYGARC_REG_SCSCR_TIE; // Disable xmit interrupt + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + + cyg_drv_interrupt_unmask(sh_chan->rx_int_num); +} + +// Serial I/O - low level tx interrupt handler (ISR) +static cyg_uint32 +sh_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + cyg_uint8 _scr; + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + _scr &= ~CYGARC_REG_SCSCR_TIE; // mask out tx interrupts + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level tx interrupt handler (DSR) +static void +sh_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + + (chan->callbacks->xmt_char)(chan); + + if (sh_chan->tx_enabled) { + cyg_uint8 _scr; + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + _scr |= CYGARC_REG_SCSCR_TIE; // unmask tx interrupts + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + } +} + +// Serial I/O - low level RX interrupt handler (ISR) +static cyg_uint32 +sh_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + cyg_uint8 _scr; + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + _scr &= ~CYGARC_REG_SCSCR_RIE; // mask rx interrupts + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level rx interrupt handler (DSR) +static void +sh_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + cyg_uint8 _ssr, _scr; + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr); + if (_ssr & CYGARC_REG_SCSSR_RDRF) { + cyg_uint8 _c; + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCRDR, _c); + // Clear buffer full flag. + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, + CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF); + + (chan->callbacks->rcv_char)(chan, _c); + } + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + _scr |= CYGARC_REG_SCSCR_RIE; // unmask rx interrupts + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); +} + +static volatile int sh_serial_error_orer = 0; +static volatile int sh_serial_error_fer = 0; +static volatile int sh_serial_error_per = 0; + +// Serial I/O - low level error interrupt handler (ISR) +static cyg_uint32 +sh_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + cyg_uint8 _scr; + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + _scr &= ~CYGARC_REG_SCSCR_RIE; // mask rx interrupts + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level error interrupt handler (DSR) +static void +sh_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; + cyg_uint8 _ssr, _ssr2; + + HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr); + _ssr2 = CYGARC_REG_SCSSR_CLEARMASK; + + if (_ssr & CYGARC_REG_SCSSR_ORER) { + _ssr2 &= ~CYGARC_REG_SCSSR_ORER; + sh_serial_error_orer++; + } + if (_ssr & CYGARC_REG_SCSSR_FER) { + _ssr2 &= ~CYGARC_REG_SCSSR_FER; + sh_serial_error_fer++; + } + if (_ssr & CYGARC_REG_SCSSR_PER) { + _ssr2 &= ~CYGARC_REG_SCSSR_PER; + sh_serial_error_per++; + } + HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr2); +} + +#endif // ifdef __CYGPKG_IO_SERIAL_SH_SCI + diff --git a/packages/devs/serial/sparclite/sleb/current/ChangeLog b/packages/devs/serial/sparclite/sleb/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/devs/serial/sparclite/sleb/current/ChangeLog @@ -0,0 +1,1163 @@ +2000-04-11 Hugo Tyson + + * cdl/ser_sparclite_sleb.cdl: Change the parent from CYGPKG_IO_SERIAL + (which is enabled most of the time) to CYGPKG_IO_SERIAL_DEVICES + (which is not...) thus allowing convenient control independent of + platform. Also enable all individual devices by default, now, so + that they can be enabled simply by enabling the above new parent. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-05 Jonathan Larmour + + * src/common/tty.c (tty_read): CRLF conversion should use \r\n not \n\r + (tty_write): Similarly + + * include/ttyio.h: Update CYG_TTY_IN_FLAGS_CRLF and + CYG_TTY_IN_FLAGS_CRLF to match + +2000-03-31 Jesper Skov + + * cdl/ser_sh_edk7708.cdl: Limit legal baud rate range. + * src/sh/sh_sci_serial.c: Use baud rate macro instead of hardwired + constants. + +2000-03-28 John Dallaway + + * cdl/io_serial.cdl, + cdl/ser_arm_aeb.cdl, + cdl/ser_arm_cma230.cdl, + cdl/ser_arm_edb7xxx.cdl, + cdl/ser_arm_pid.cdl, + cdl/ser_i386_pc.cdl, + cdl/ser_mips_jmr3904.cdl, + cdl/ser_mips_vrc4373.cdl, + cdl/ser_mn10300.cdl, + cdl/ser_powerpc_cogent.cdl, + cdl/ser_quicc_smc.cdl, + cdl/ser_sh_edk7708.cdl, + cdl/ser_sparclite_sleb.cdl, + cdl/tty.cdl: + + Adjust documentation URLs. + +2000-03-07 Jesper Skov + + * cdl/ser_mips_jmr3904.cdl: Rename devices to match CDL naming. + +2000-02-29 Jonathan Larmour + + * include/serialio.h: Correct baud rate typo: 230400 rather than + 234000. Thanks to Grant Edwards for the report. + +2000-02-28 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Use standard 'diag_dump_buf()'. + +2000-02-28 Jesper Skov + + * tests/ser_test_protocol.inl: Allow 115200 baud on Cogent + again. Fixed interrupt problem. + +2000-02-22 Jesper Skov + + * tests/ser_test_protocol.inl: Don't use 115200 baud on + Cogent. Our slower boards can't keep up. + +2000-02-17 Gary Thomas + + * cdl/ser_powerpc_cogent.cdl: Fix incorrect dependency. + +2000-02-16 Nick Garnett + + * include/pkgconf/io_serial.h: + Added configury for PC serial device drivers. + + * cdl/ser_i386_pc.cdl: + * src/i386/pc_serial.c: + * src/i386/pc_serial.h: + Added these files to implement PC serial line drivers. + + * cdl/io_serial.cdl: + Added CYGPKG_IO_SERIAL_I386_PC. + + * tests/ser_test_protocol.inl: + Added support for PC serial line testing. + +2000-02-11 Jesper Skov + + * src/sh/sh_sci_7708.inl (DEVTAB_ENTRY): + * src/sparclite/sleb_sdtr.c: + serial_devio => cyg_io_serial_devio + +2000-02-10 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: Ensure all CYG_HAL_MN10300_* + preprocessor conditionals use the correct CYGPKG_HAL_MN10300_AM3* form + now. + +2000-02-03 Jesper Skov + + * src/powerpc/quicc_smc_serial.c: CYG_HAL_POWERPC_x->CYGPKG_... + +2000-02-02 Jonathan Larmour + + * src/arm/aeb_serial.h: Rename lower case register macros to REG_ upper + case macros + + * src/arm/aeb_serial.c: Update to reflect above + +2000-01-31 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Simon FitzMaurice + * cdl/*.cdl: + + Adjust help URLs in line with new doc layout. + +2000-01-28 Gary Thomas + + * src/common/tty.c (tty_read): Fix problem with backspace at start + of line (size must be 'signed' for compare to work). + +2000-01-19 Hugo Tyson + + * cdl/*.cdl: Add descriptions to a number of options &c which were + lacking same, also tidied up other typos as noticed en passant. + +2000-01-17 Gary Thomas + + * src/common/tty.c (tty_read): Avoid echoing "backspace/erase" at + start of line. + +2000-01-05 Gary Thomas + + * src/common/serial.c (serial_write): Avoid potential deadlock if + transmit start actually sends enough characters to signal cond wait. + +2000-01-03 Gary Thomas + + * include/serial.h: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + serial_callbacks => cyg_io_serial_callbacks + + * src/mips/tx3904_serial.c: + * src/mips/vrc4373_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/quicc_smc_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/edb7xxx_serial.c: + * src/arm/cma230_serial.c: + * src/arm/ebsa285_serial.c: + * src/common/haldiag.c: + * src/common/serial.c: Fix namespace pollution - + serial_devio => cyg_io_serial_devio + +1999-12-06 Gary Thomas + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Add loop to handle + case where an interrupt represents multiple events. + +1999-11-19 Gary Thomas + + * src/powerpc/quicc_smc_serial.c: Channel select for SMC2 was wrong. + +1999-11-18 Gary Thomas + + * include/pkgconf/io_serial.h: Remove mention of 7209/7212. + +1999-11-03 John Dallaway + + * cdl/io_serial.cdl: Define build options. + +1999-10-26 Jesper Skov + * tests/serial5.c (serial_test): Reduce speed in thumb mode. + + * src/arm/pid_serial.h: Added BE support. + + * src/PKGconf.mak: Use CYGPKG_<> instead of CYG_<> to control what + needs to be compiled. + +1999-10-25 Gary Thomas + + * src/arm/pid_serial.h (ISR_RxTO): Define - character received but + not handled "promptly". + + * src/arm/pid_serial_with_ints.c (pid_serial_DSR): Handle rcv interrupts + properly (can't ignore them even with TO bit set). + + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Need to handle all + input (empty input FIFO) otherwise characters get dropped. + +1999-10-15 Jesper Skov + + * tests/ser_test_protocol.inl: Removed AEB rev C change. Was bogus. + +1999-10-11 Nick Garnett + + * tests/ser_test_protocol.inl: Added configury for VR4300 testing. + + * src/mips/vrc4373_serial.c: Added Bi-endian support. + + * include/pkgconf/io_serial.h: Adjusted default baud rates to + 38400. + +1999-10-06 Jesper Skov + + * tests/ser_test_protocol.inl: Run tests on AEB rev C as well. + +1999-09-28 Hugo Tyson + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): Correct + value supplied for interrupt priority - it may be unused, but it + is asserted for range. Initialize the diagnostic channel if on an + MBX and if NOT using SMC1 ourselves, to ensure that diag output + and built-in stubs work correctly; otherwise reset the quicc and + ignore SMC1 as before. Fix various warnings, mostly about + casting/arg-passing/assigning away volatile. + +1999-08-31 Jesper Skov + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov + + * tests/README: Added. + +1999-08-18 Jesper Skov + + * tests/tty1.c: + * tests/tty2.c: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/PKGconf.mak: + Require kernel and kernel C API. + +1999-08-17 Nick Garnett + + * src/mn10300/mn10300_serial.c: Added a simple implementation of a + receive FIFO to try and reduce the overhead of receiving bytes. + +1999-08-16 Jonathan Larmour + + * src/PKGconf.mak: + * src/mn10300/mn10300_serial.c: + * tests/ser_test_protocol.inl: + Rename all am32 -> am31 + +1999-08-12 Nick Garnett + + Imported following changes from development branch: + + 1999-08-11 Nick Garnett + + * tests/serial5.c: Modified config test for boards that need a lower + speed for this test. + + * tests/ser_test_protocol.inl: Removed 14400 baud tests for all + MN10300 variants. The MN10300 cannot currently do this speed. + + * src/mn10300/mn10300_serial.c: Tidied up the transmit interrupt + enable/disable code to be variant specific. + + * include/pkgconf/io_serial.h: Undid Jonathan's change, since the + same options are used for all MN10300 variants. + + 1999-08-10 Jonathan Larmour + + * include/pkgconf/io_serial.h: + Reparent CYGPKG_IO_SERIAL_MN10300 from under CYGPKG_HAL_MN10300 to + CYGPKG_HAL_MN10300_AM32_STDEVAL1 since it's stdeval1 specific + + 1999-08-04 Nick Garnett + + * tests/ser_test_protocol.inl: + Changed names of MN10300 defines tested. Added AM33 definitions. + + * src/mn10300/mn10300_serial.c: + Modified driver to work on am33 too. This simply requires some + alternate definitions of things like register addresses and some + bits in them plus some extra parameterization of some register + values. + + * src/PKGconf.mak: + Added am33 to list of architectures supporting serial lines. + +1999-07-28 Gary Thomas + + * include/pkgconf/io_serial.h: Update descriptions to be more + generic (CL7x11 instead of CL7211). + +1999-07-28 Jonathan Larmour + + * include/pkgconf/io_serial.h: Correct typos in CDL description + for serial port 2 driver + +1999-07-26 Hugo Tyson + + * src/arm/ebsa285_serial.c: New file: device driver for the serial + device of the Intel StrongARM EBSA-285 evaluation board. + + * include/pkgconf/io_serial.h (CYGPKG_IO_SERIAL_ARM_EBSA285): + Config for it. + + * src/PKGconf.mak (EXTRAS_COMPILE): Compile it. + + * tests/ser_test_protocol.inl (TEST_SER_DEV): Enable testing of it. + +1999-07-08 Jesper Skov + + * tests/ser_test_protocol.inl (change_config): Changed implementation. + +1999-06-27 Gary Thomas + + * src/powerpc/quicc_smc_serial.c (quicc_smc_serial_init): More robust + initialization, with data cache disabled. This seems to fix the + random failures described below. + + * tests/ser_test_protocol.inl: Add configuration for QUICC/MBX860. + Added some delays in the configuration change code to make QUICC + happy [didn't help much although the manual says they are required]. + + * src/powerpc/quicc_smc_serial.h (UART_BITRATE): Rewrote macro to + match what the Linux driver uses - still doesn't work well, though. + + * src/powerpc/quicc_smc_serial.c: Lots of changes trying to get the + serial driver working and robust. At this point it works quite well, + using the default buffer sizes. Changing from the defaults seem to + easily break it though, certainly on input. Also, changing the baud + rate seems to not work reliably. + + * src/common/serial.c: Add some tracing/debug info to try and debug + problems with QUICC serial driver. These are hard disabled with + "XX_" prepended to "CYGDBG_DIAG_BUF". Enabling them gives information + about how/when data are delivered from the serial driver. + + * include/pkgconf/io_serial.h: Adjust limits and defaults on number and + size of buffers with values that seem to work. + +1999-06-21 Jesper Skov + + * src/sh/sh_sci_serial.c: Rearranged inclusion of .inl file a bit + to avoid compiler warnings. + +1999-06-21 Gary Thomas + + * include/pkgconf/io_serial.h: Fix CDL for number of buffers. + + * src/powerpc/quicc_smc_serial.c: Force number of buffers = 1. + +1999-06-20 Gary Thomas + + * include/pkgconf/io_serial.h: Some clean up (removed commented + obsolete CDL parenting structure). + Add support for Motorola PowerPC QUICC/SMC. + + * src/arm/cma230_serial.c: + * src/arm/cl7211_serial.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use #include to get 'diag_printf()' + prototypes. + +1999-06-17 Gary Thomas + + * src/arm/cl7211_serial.c (cl7211_serial_start_xmit): Fix race which + cause xmitter to get stuck. + +1999-06-16 Jesper Skov + + * src/sh/sh_serial.c: [removed] + * src/sh/sh_sci_serial.c: [added] + * src/sh/sh_sci_7708.inl: [added] + * include/pkgconf/io_serial.h: + * src/PKGconf.mak (EXTRAS_COMPILE): + * tests/ser_test_protocol.inl: + Renamed CDL options and restructered driver. + Fixed CDL typo. + +1999-06-04 Jesper Skov + + * include/pkgconf/io_serial.h: Fixed CDL string for BAUD rate option. + +1999-06-04 Gary Thomas + + * tests/ser_test_protocol.inl: Disable testing at 115200 + for Cogent CMA230 (ARM). + + * src/arm/cma230_serial.c: Fix interrupt for port B. + +1999-05-31 Jesper Skov + + * src/sh/sh_serial.c: Fixed receive interrupts and added handler for + error interrupts. + +1999-05-28 Jesper Skov + + * io/serial/current/src/PKGconf.mak: + * io/serial/current/tests/ser_test_protocol.inl: + * include/pkgconf/io_serial.h: + Renamed SH platform package to edk7708. + +1999-05-27 Jesper Skov + + * tests/ser_test_protocol.inl: Added ability to change options in + host software. + +1999-05-27 Jonathan Larmour + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + Wait for the serial device to become acquiescent before disabling + it. This prevents cygmon's outgoing characters getting corrupted + due to transmission being disabled. + Fix for PR 20047 + +1999-05-26 Gary Thomas + + * include/pkgconf/io_serial.h: + * tests/ser_test_protocol.inl: Add Cogent CMA230 setup. + + * src/arm/cma230_serial.c: Make names compatible with Cogent + PowerPC board. + +1999-05-26 Gary Thomas + + * tests/ser_test_protocol.inl: Add Cirrus Logic CL7211 setup. +1999-05-26 Jesper Skov + + * src/sh/sh_serial.c: Added more baud rate values. Disabled + interrupt driven receive. Fixed config_port to enable proper + interrupt flags. + +1999-05-25 Jonathan Larmour + + * tests/ser_test_protocol.inl: + Change all mentions of CYGPKG_HAL_TX39_JMR3904 to + CYGPKG_HAL_MIPS_TX39_JMR3904 + +1999-05-25 Jonathan Larmour + + * src/PKGconf.mak (EXTRAS_COMPILE): Change CYG_HAL_TX39 to + CYG_HAL_MIPS_TX39 +1999-05-25 Jesper Skov + + * tests/ser_test_protocol.inl: Added sh entry. + +1999-05-24 Jesper Skov + + * src/PKGconf.mak: + * include/pkgconf/io_serial.h: + * src/sh/sh_serial.c: + Added sh driver. + +1999-05-18 Jesper Skov + PR 19926 + * src/sparclite/sleb_sdtr.c (sleb_sdtr_rx_DSR): Only read chan if + there is one. + +1999-05-18 Jesper Skov + PR 19926 + * src/arm/cl7211_serial.c (cl7211_serial_rx_DSR): Only read char + if there is one. + +1999-05-16 Gary Thomas + + * src/arm/cl7211_serial.c: Clean up, first working version. + +1999-05-14 Jesper Skov + + * tests/ser_test_protocol.inl: Removed workaround for spurious + Cogent reads. + + * src/arm/aeb_serial.c: + * src/arm/aeb_serial.h: + * src/arm/pid_serial_with_ints.c: + * src/arm/pid_serial.h: + * src/powerpc/cogent_serial.h: + * src/powerpc/cogent_serial_with_ints.c: + Check for receive interrupt before reading. + +1999-05-13 Nick Garnett + + The follow changes were made in a branch an have now been merged: + + 1999-04-21 Gary Thomas + + * src/mips/vrc4373_serial.c: Small changes to get working with + interrupts. + + 1999-04-20 John Dallaway + + * include/pkgconf/io_serial.h: Fix CYGPKG_IO_SERIAL_TX39_JMR3904 + parent attribute. + +1999-05-11 Gary Thomas + + * src/arm/cl7211_serial.c: Fix compile problems from merged code. + +1999-05-05 Jesper Skov + + * tests/ser_test_protocol.inl: Tidied up a bit and added + description of protocol. + +1999-05-05 Jesper Skov + + * src/common/serial.c (serial_write, serial_read): Clear abort + flag at entry. + +1999-05-05 Jesper Skov + + * tests/serial4.c (serial_test): Handle config fails correctly. + + * tests/ser_test_protocol.inl: Better change_config + handling. Simple recovery and negotiation isn't timing + dependant. + +1999-05-05 Jesper Skov + + * tests/timeout.inl: Updated with the below changes. + +1999-05-05 Gary Thomas + + * misc/timeout.inl (timeout): Timeouts are relative, but alarms + need absolute time values. + +1999-05-04 Jesper Skov + PR 20018 + * tests/serial1.c (serial_test): Always PASS, regardless of + configuration. + +1999-05-04 Jesper Skov + + * tests/ser_test_protocol.inl: Reverse order of configurations - + run tests with slow baud rate first. + Only check CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT for SLEB on RAM startup. + +1999-05-04 Jesper Skov + * src/mn10300/mn10300_serial.c: + Use interrupt enable/disable feature of serial port2 to allow + coexistence with CygMon/hal_diag. + + * tests/ser_test_protocol.inl: Use port2 for MN10300. + +1999-04-28 Bart Veer + + * src/PKGconf.mak (EXTRAS_COMPILE): + Use the new rules for generating libextras.a + +1999-04-26 Gary Thomas + + * include/pkgconf/io_serial.h: Add support for Cirrus Logic CL7211. + + +1999-04-20 Gary Thomas + + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Fix default baud rate if unbuffered. +1999-04-20 Jesper Skov + + * tests/ser_test_protocol.inl: Added some comments. Disabled 38400 + for SLEB. Only run test on SLEB if CygMon isn't used for diag + output. + +1999-04-15 Jesper Skov + PR 19752 + * tests/serial3.c: + * tests/serial5.c: + Run these tests at a lower baud rate on ARM AEB. + +1999-04-14 Jesper Skov + PR 19839 + * src/mn10300/mn10300_serial.c: + Fix compiler warnings. + +1999-04-14 Bart Veer + + * include/pkgconf/io_serial.h: + Reparent the board-specific serial devices below the actual boards. + +1999-04-13 Jesper Skov + + * tests/ser_test_protocol.inl: + NA when run from simulator. + +1999-04-12 Jesper Skov + + * tests/ser_test_protocol.inl: + Disabled 115200 for MN10300. + Reclaim interrupt vectors from CygMon when testing on SLEB. + +1999-04-09 Gary Thomas + + * include/serial.h: Change SERIAL_CHANNEL setup so all channels + have serial callbacks, regardless of buffering. + +1999-04-09 Jesper Skov + + * src/common/tty.c: + * include/pkgconf/io_serial.h: + Added new ttydiag device layered on top of haldiag, so that tty0 + can be layered on top of ser0. + +1999-04-08 Jesper Skov + + * tests/tty1.c: [added] + * tests/tty2.c: [added] + * tests/PKGconf.mak: + * tests/ser_test_protocol.inl: + Added two simple TTY tests. + +1999-04-07 Hugo Tyson + + * src/sparclite/sleb_sdtr.h: Include cyg/hal/hal_io.h for I/O + macros instead of hal_diag.h where they had evolved before. + +1999-04-06 Jesper Skov + + * tests/serial4.c (serial_test): + * tests/serial3.c (serial_test): + Reduce packet sizes. + +1999-03-31 Jesper Skov + + * tests/ser_test_protocol.inl: Added remaining targets to the + test. + +1999-03-31 Gary Thomas + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_start_xmit): Fix timing race + when enabling xmit interrupts. + +1999-03-26 Gary Thomas + + * src/sparclite/sleb_sdtr.c: Change how the port is set up. The transmitter + is now always enabled, just the interrupts are masked/unmasked to control it. + This lets the serial driver cooperate with Cygmon on the port used for GDB. + Note that currently serial input does not work for CON1 since Cygmon is + taking all of the receive interrupts for itself. + (sleb_sdtr_tx_DSR): Need to keep track whether xmit interrupt should be + enabled - otherwise it can get enabled incorrectly and we get interrupted + to death! + +1999-03-26 Jesper Skov + + * tests/ser_test_protocol.inl: Send a DONE message after a no-echo + binary packet. + +1999-03-26 Hugo Tyson + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Make these build when no kernel present; include of testcase + was the wrong side of the ifdef. + +1999-03-26 Jesper Skov + + * tests/serial5.c: + * tests/serial4.c: + * tests/serial3.c: + * tests/serial2.c: + * tests/serial1.c: + Moved NOP check to ser_test_protocol open call. + + * tests/ser_test_protocol.inl: Make sure the proper device is + selected for testing. Do NOP check in open call. + +1999-03-25 Gary Thomas + + * include/pkgconf/io_serial.h: + * misc/console.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/tty.c: + * src/mips/tx3904_serial.c: + * src/mn10300/mn10300_serial.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: Update CDL to follow naming conventions. + + * src/mips/tx3904_serial.c (tx3904_serial_config_port): + Make sure port is enabled (CDL) before using it. + + * src/mn10300/mn10300_serial.c (mn10300_serial_config_port): + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + * src/arm/aeb_serial.c (aeb_serial_config_port): + * src/arm/pid_serial_with_ints.c (pid_serial_config_port): Change so that + the physical port is not modified unless the provided configuration is valid. + + * src/sparclite/sleb_sdtr.c (sleb_sdtr_config_port): + Using wrong config data. + + * include/serialio.h: Add macros to support baud rate from CDL. + + * include/pkgconf/io_serial.h: + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c (tx3904_serial_ISR): + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Add configury for baud rate and buffer size. + +1999-03-24 Nick Garnett + + * src/mips/tx3904_serial.c: + Now uses CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL to get CPU + frequency. This is a little more accurate than using + CYGHWR_HAL_MIPS_CPU_FREQ. + +1999-03-24 Gary Thomas + + * include/serialio.h (CYGNUM_SERIAL_BAUD_MIN/MAX): Add for completeness. + + * src/arm/aeb_serial.c (aeb_serial_stop_xmit): + * src/arm/pid_serial_with_ints.c (pid_serial_stop_xmit): Fix typo in comment. + +1999-03-24 Jesper Skov + + * tests/ser_test_protocol.inl: Weeded out configs TX39 doesn't + like. + + * src/powerpc/cogent_serial.h: + Added copyright header. + + * tests/ser_test_protocol.inl: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + Don't try to run tests when no IO device has been specified. + +1999-03-23 Jesper Skov + + * misc/serial1.c, misc/serial2.c, misc/serial3.c, misc/serial4.c, + * misc/serial5.c, misc/ser_test_protocol.inl + Deleted. + +1999-03-23 Jesper Skov + + * misc/PKGconf.mak: + * tests/timeout.inl: + * tests/PKGconf.mak: + * tests/serial1.c: + * tests/serial2.c: + * tests/serial3.c: + * tests/serial4.c: + * tests/serial5.c: + * tests/ser_test_protocol.inl: + Moved the serial tests from the misc directory to the tests + directory. + +1999-03-23 Nick Garnett + + * src/mn10300/mn10300_serial.c: Now initially mask TX interrupts + at initialization and unmask/remask in start/stop xmit + routines. This has no real effect on the hardware, but the + simulator does not implement the LCR_TXE bit properly, resulting + in spurious TX interrupts during diagnostic output. + This was the cause of the slow output reported in PR 19559. + +1999-03-23 Gary Thomas + + * include/pkgconf/io_serial.h: Fix "display" strings to have appropriate + case - mostly lower case. + +1999-03-22 Hugo Tyson + + * misc/console.c: + * misc/serial.c: + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of + CYGNUM_HAL_MINIMUM_STACK_SIZE. + +1999-03-22 Gary Thomas + + * src/mn10300/mn10300_serial.c: + * src/mips/tx3904_serial.c: Add CDL configury. + + * include/pkgconf/io_serial.h: Update CDL to add device name + configurability for all devices. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Use CDL configured device names. + +1999-03-22 Jesper Skov + + * misc/serial1.c: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + * misc/serial5.c: + Requires kernel as well. + +1999-03-22 Jesper Skov + + * src/sparclite/sleb_sdtr.c: + Moved include statement to avoid warnings. + +1999-03-19 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial5.c: + * misc/PKGconf.mak: + Replace complex and not very stable duplex test with a simpler + test that works better. + Added serial5 using that test. + +1999-03-19 Jesper Skov + + * misc/PKGconf.mak: + * misc/serial1.c: + * misc/serial2.c: + Added API test and made serial2 do simple string output. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Changed ToDo comment. + +1999-03-19 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + Moved include statement to avoid warnings. + +1999-03-19 Gary Thomas + + * include/pkgconf/io_serial.h: More CDL problems. + +1999-03-18 Gary Thomas + + * include/pkgconf/io_serial.h: Add CDL for SPARClite SLEB. + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/pid_serial_with_ints.c: + * src/arm/aeb_serial.c: Update device names to match CDL. + + * include/pkgconf/io_serial.h: Change names for serial ports to + be CYGPKG_IO_SERIAL___. + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: + * misc/serial2.c: + First stab at the duplex binary test. Still much fun to be had... + +1999-03-18 Jesper Skov + + * misc/ser_test_protocol.inl: Added timeout for PING. + +1999-03-18 Gary Thomas + + * src/common/serial.c: Change ABORT functionality to be DSR safe. + (serial_get_config): Fix typo! + + * include/pkgconf/io_serial.h: Small change in CDL to make serial + devices tied to the platform and not the serial I/O package. This + means that only the devices appropriate to a given platform can be + enabled. + + * misc/serial.c: Better use of alarms - only trigger at the time of + the next timeout. Moved timeout functions to new file "timeout.inl". + + * src/common/serial.c (serial_get_config): Add support for + CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_ABORT. + + * misc/serial.c: Add simple timeout mechanisms. + +1999-03-17 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Conditionalize based on CDL. + + * include/pkgconf/io_serial.h: Add some CDL configury - not perfect + because of current ~CDL limitations. + +1999-03-17 Jesper Skov + + * misc/serial2.c: Cleaned up a bit. Used for hacking new tests. + +1999-03-17 Jesper Skov + + * misc/PKGconf.mak: + * misc/ser_test_protocol.inl: + * misc/serial2.c: + * misc/serial3.c: + * misc/serial4.c: + Put testing protocol implementation in a separate file. Split the + tests in serial2 into separate files. + +1999-03-16 Nick Garnett + + * src/mn10300/mn10300_serial.c: Fixed some compiler warnings. + +1999-03-15 Gary Thomas + + * include/pkgconf/io_serial.h: Change default configurations. + No serial drivers enabled for PID port A or AEB. + + * src/sparclite/sleb_sdtr.c: + * src/powerpc/cogent_serial_with_ints.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: + * src/common/haldiag.c: + * src/common/tty.c: + * src/common/serial.c: Add 'CYGDBG_IO_INIT' for control of init + messages. + + * src/powerpc/cogent_serial_with_ints.c: + * src/sparclite/sleb_sdtr.c: + * src/arm/aeb_serial.c: + * src/arm/pid_serial_with_ints.c: Don't include + +1999-03-15 Jesper Skov + + * misc/serial2.c (serial_test): Fix use of strlen. Fix DONE part + of binary protocol. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Play a bit with timing. Think I broke it :( + Added DONE to BINARY packet. + Proper call to DRAIN. + +1999-03-12 Nick Garnett + + * src/mips/tx3904_serial.c: Tidied away some debugging code. + +1999-03-12 Jesper Skov + + * misc/serial2.c: Removed bogus config changes. + +1999-03-12 Jesper Skov + + * misc/serial2.c (serial_test): Check for ser_filter on host (PING + packet). + +1999-03-11 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Added note. + + * misc/serial2.c: + Added (almost) proper configuration handling. + Run tests on varying configurations. + +1999-03-11 Nick Garnett + + * src/mips/tx3904_serial.c: + Many changes to get working. + + * misc/console.c (console_test): Fixed compiler warning. + + * misc/serial2.c: + Added device name for TX39 testing. + Fixed some bugs in Tcyg_io_write() macro. + +1999-03-10 Jesper Skov + + * misc/serial2.c: Added target specific test device name. + +1999-03-10 John Dallaway + + * include/pkgconf/io_serial.h: Correct CDL description spelling. + +1999-03-10 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + * misc/console.c: + Fixed compiler warnings. + +1999-03-10 Gary Thomas + + * include/pkgconf/io_serial.h: Improve CDL descriptions. + +1999-03-10 Jesper Skov + + * misc/serial2.c (serial_test): Do some more tests with changed + baud rates. + +1999-03-09 Jesper Skov + + * misc/serial2.c (serial_test): Added workaround for spurious byte + problem. Added a few more tests to run. + + * src/powerpc/cogent_serial_with_ints.c + (cogent_serial_config_port): Remove interrupt enabling. + +1999-03-09 Nick Garnett + + * src/PKGconf.mak: + * src/mips/tx3904_serial.c: + Added initial version of TX39 device driver. Currently untested + but eliminates PR19445. + +1999-03-09 Jesper Skov + + * misc/serial2.c: DRAIN function works now. + +1999-03-09 Jesper Skov + + * include/pkgconf/io_serial.h: Only enable one serial driver per + default. + +1999-03-08 Jesper Skov + + * misc/serial2.c (serial_test): Be a bit more aggressive. + + * src/powerpc/cogent_serial_with_ints.c: Check that configuration + is sensible. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: + Added support for both ports. + + * include/pkgconf/io_serial.h: Added simple defines for cogent + serial ports. No CDL yet. + +1999-03-08 Jesper Skov + + * misc/serial.c: Removed PID references. Fixed compiler warnings. + +1999-03-08 Jesper Skov + + * src/powerpc/cogent_serial_with_ints.c: Cleaned up a + bit. Actually works now. + +1999-03-08 Gary Thomas + + * src/common/serial.c: Change in cyg_drv_cond_wait() behaviour + means DSR lock should be left alone. + +1999-03-08 Jesper Skov + PR 19400 + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_init): Set + valid interrupt priority. + +1999-03-05 Nick Garnett + + * src/mn10300/mn10300_serial.c (mn10300_serial_init): + Added extra test to avoid initializing serial 2 when CYGMON is + present. + Include hal_intr.h explicitly for use in non-kernel + configurations. + + * src/common/serial.c: + Added extra test before calls to cyg_drv_cond_wait() to avoid race + condition. This is not, however, a complete solution to this + problem. A better solution will be forthcoming. + + * include/serial.h: + Changed include files used to permit non-kernel configurations to + be built. + +1999-03-05 Jesper Skov + + * src/common/haldiag.c: Removed diag_printf declaration. + +1999-03-05 Jonathan Larmour + + * src/mn10300/mn10300_serial.c: + Change CYG_VECTOR_* to CYGNUM_HAL_INTERRUPT_* to get it to compile! + +1999-03-05 Gary Thomas + + * src/powerpc/cogent_serial_with_ints.c (cogent_serial_config_port): + Fix renaming of interrupt vectors. + +1999-03-05 Gary Thomas + + * src/arm/pid_serial_with_ints.c: Fix interrupt vectors. + +1999-03-03 Gary Thomas + + * serial/current/src/arm/pid_serial_with_ints.c: + New [somewhat] configurable drivers for PID. + +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== diff --git a/packages/devs/serial/sparclite/sleb/current/cdl/ser_sparclite_sleb.cdl b/packages/devs/serial/sparclite/sleb/current/cdl/ser_sparclite_sleb.cdl new file mode 100644 --- /dev/null +++ b/packages/devs/serial/sparclite/sleb/current/cdl/ser_sparclite_sleb.cdl @@ -0,0 +1,178 @@ +# ==================================================================== +# +# ser_sparclite_sleb.cdl +# +# eCos serial SPARClite/SLEB configuration data +# +# ==================================================================== +#####COPYRIGHTBEGIN#### +# +# ------------------------------------------- +# The contents of this file are subject to the Red Hat eCos Public License +# Version 1.1 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.redhat.com/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations under +# the License. +# +# The Original Code is eCos - Embedded Configurable Operating System, +# released September 30, 1998. +# +# The Initial Developer of the Original Code is Red Hat. +# Portions created by Red Hat are +# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): jskov +# Original data: gthomas +# Contributors: +# Date: 1999-07-14 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + +cdl_package CYGPKG_IO_SERIAL_SPARCLITE_SLEB { + display "SPARClite SLEB serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_SPARCLITE_SLEB + + requires CYGPKG_ERROR + include_dir cyg/io +# include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + SPARClite SLEB." + doc redirect/ecos-device-drivers.html + + compile -library=libextras.a sleb_sdtr.c + + define_proc { + puts $::cdl_system_header "/***** serial driver proc output start *****/" + puts $::cdl_system_header "#define CYGDAT_IO_SERIAL_DEVICE_HEADER " + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1 { + display "SPARClite SLEB serial CON1 port driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the SPARClite + SLEB CON1 port." + + cdl_option CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME { + display "Device name for SPARClite SLEB serial CON1 port" + flavor data + default_value {"\"/dev/ser0\""} + description " + This option specifies the device name for the SPARClite SLEB + CON1 port." + } + + cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BAUD { + display "Baud rate for the SPARClite SLEB serial CON1 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 19200 + description " + This option specifies the default baud rate (speed) for the + SPARClite SLEB CON1." + } + + cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE { + display "Buffer size for the SPARClite SLEB serial CON1 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used for + the SPARClite SLEB CON1." + } +} +cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON2 { + display "SPARClite SLEB serial CON2 port driver" + flavor bool + default_value 1 + description " + This option includes the serial device driver for the SPARClite + SLEB CON2 port." + + cdl_option CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON2_NAME { + display "Device name for SPARClite SLEB serial CON2 port" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the device name for the SPARClite SLEB + CON2 port." + } + + cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BAUD { + display "Baud rate for the SPARClite SLEB serial CON2 driver" + flavor data + legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 + 4800 7200 9600 14400 19200 38400 57600 115200 234000 + } + default_value 19200 + description " + This option specifies the default baud rate (speed) for the + SPARClite SLEB CON2." + } + + cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE { + display "Buffer size for the SPARClite SLEB serial CON2 driver" + flavor data + legal_values 0 to 8192 + default_value 128 + description " + This option specifies the size of the internal buffers used for + the SPARClite SLEB CON2." + } +} + + cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB_OPTIONS { + display "Serial device driver build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package, + and details of which tests are built." + + + cdl_option CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are used in addition + to the set of global flags." + } + + cdl_option CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building these serial device drivers. These flags are removed from + the set of global flags if present." + } + } +} + +# EOF ser_sparclite_sleb.cdl diff --git a/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.c b/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.c new file mode 100644 --- /dev/null +++ b/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.c @@ -0,0 +1,375 @@ +//========================================================================== +// +// io/serial/sparclite/sleb_sdtr.c +// +// Serial I/O interface module for SPARClite Eval Board (SLEB) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-04 +// Purpose: SLEB serial I/O module +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include +#include +#include +#include +#include + +#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB + +#include "sleb_sdtr.h" + +extern void diag_printf(const char *fmt, ...); + +#define BUFSIZE 128 + +typedef struct sleb_sdtr_info { + CYG_ADDRWORD base; + CYG_WORD tx_int_num; + CYG_WORD rx_int_num; + cyg_interrupt tx_serial_interrupt; + cyg_handle_t tx_serial_interrupt_handle; + cyg_interrupt rx_serial_interrupt; + cyg_handle_t rx_serial_interrupt_handle; + cyg_uint8 cmd_reg; + bool xmit_enabled; +} sleb_sdtr_info; + +static bool sleb_sdtr_init(struct cyg_devtab_entry *tab); +static bool sleb_sdtr_putc(serial_channel *chan, unsigned char c); +static Cyg_ErrNo sleb_sdtr_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name); +static unsigned char sleb_sdtr_getc(serial_channel *chan); +static bool sleb_sdtr_set_config(serial_channel *chan, cyg_serial_info_t *config); +static void sleb_sdtr_start_xmit(serial_channel *chan); +static void sleb_sdtr_stop_xmit(serial_channel *chan); + +static cyg_uint32 sleb_sdtr_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void sleb_sdtr_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); +static cyg_uint32 sleb_sdtr_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); +static void sleb_sdtr_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); + +static SERIAL_FUNS(sleb_sdtr_funs, + sleb_sdtr_putc, + sleb_sdtr_getc, + sleb_sdtr_set_config, + sleb_sdtr_start_xmit, + sleb_sdtr_stop_xmit + ); + +#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1 +static sleb_sdtr_info sleb_sdtr_info0 = {SLEB_SDTR0_BASE, SLEB_SDTR0_TX_INT, SLEB_SDTR0_RX_INT}; +#if CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE > 0 +static unsigned char sleb_sdtr_out_buf0[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE]; +static unsigned char sleb_sdtr_in_buf0[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(sleb_sdtr_channel0, + sleb_sdtr_funs, + sleb_sdtr_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &sleb_sdtr_out_buf0[0], sizeof(sleb_sdtr_out_buf0), + &sleb_sdtr_in_buf0[0], sizeof(sleb_sdtr_in_buf0) + ); +#else +static SERIAL_CHANNEL(sleb_sdtr_channel0, + sleb_sdtr_funs, + sleb_sdtr_info0, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(sleb_sdtr_io0, + CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + sleb_sdtr_init, + sleb_sdtr_lookup, // Serial driver may need initializing + &sleb_sdtr_channel0 + ); +#endif // CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1 + +#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON2 +static sleb_sdtr_info sleb_sdtr_info1 = {SLEB_SDTR1_BASE, SLEB_SDTR1_TX_INT, SLEB_SDTR1_RX_INT}; +#if CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE > 0 +static unsigned char sleb_sdtr_out_buf1[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE]; +static unsigned char sleb_sdtr_in_buf1[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(sleb_sdtr_channel1, + sleb_sdtr_funs, + sleb_sdtr_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT, + &sleb_sdtr_out_buf1[0], sizeof(sleb_sdtr_out_buf1), + &sleb_sdtr_in_buf1[0], sizeof(sleb_sdtr_in_buf1) + ); +#else +static SERIAL_CHANNEL(sleb_sdtr_channel1, + sleb_sdtr_funs, + sleb_sdtr_info1, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BAUD), + CYG_SERIAL_STOP_DEFAULT, + CYG_SERIAL_PARITY_DEFAULT, + CYG_SERIAL_WORD_LENGTH_DEFAULT, + CYG_SERIAL_FLAGS_DEFAULT + ); +#endif + +DEVTAB_ENTRY(sleb_sdtr_io1, + CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON2_NAME, + 0, // Does not depend on a lower level interface + &cyg_io_serial_devio, + sleb_sdtr_init, + sleb_sdtr_lookup, // Serial driver may need initializing + &sleb_sdtr_channel1 + ); +#endif // CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON2 + +// Internal function to actually configure the hardware to desired baud rate, etc. +static bool +sleb_sdtr_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) +{ + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; + CYG_ADDRWORD port = sdtr_chan->base; + cyg_int32 baud_divisor; + cyg_int32 clk, tval; + unsigned char mode; +#if 0 + if ((new_config->baud < CYGNUM_SERIAL_BAUD_MIN) || (new_config->baud > CYGNUM_SERIAL_BAUD_MAX)) + return false; // Invalid baud rate +#endif + baud_divisor = select_baud[new_config->baud]; + if (baud_divisor == 0) + return false; // Unsupported baud rate + // Reset the port + HAL_SPARC_86940_WRITE(SDTR_CONTROL(port), SDTR_CMD_RST); + // Write the mode + mode = SDTR_MODE_MODE_ASYNC16 | + select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | + select_stop_bits[new_config->stop] | + select_parity[new_config->parity]; + HAL_SPARC_86940_WRITE(SDTR_CONTROL(port), mode); + // Set baud rate clock. + // ***** CAUTION! Both ports use the same time, thus they must both run at the same baud rate! + clk = *SLEB_CLOCK_SWITCH; // Compute board speed + if (clk & 0x80) clk = 10; + clk = (clk & 0x3F) * 1000000; // in MHz + tval = (clk / (baud_divisor * 32)) - 1; + HAL_SPARC_86940_WRITE(SLEB_TIMER3_RELOAD, tval); + // Set up control register + sdtr_chan->cmd_reg = SDTR_CMD_RTS | SDTR_CMD_DTR | SDTR_CMD_TxEN; +#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1 + // Cygmon needs the receiver + if ((chan->out_cbuf.len != 0) || (chan == &sleb_sdtr_channel0)) { +#else + if (chan->out_cbuf.len != 0) { +#endif + sdtr_chan->cmd_reg |= SDTR_CMD_RxEN; + } + if (init) { + sdtr_chan->xmit_enabled = false; + } + HAL_SPARC_86940_WRITE(SDTR_CONTROL(port), sdtr_chan->cmd_reg); + if (new_config != &chan->config) + chan->config = *new_config; + return true; +} + +// Function to initialize the device. Called at bootstrap time. +static bool +sleb_sdtr_init(struct cyg_devtab_entry *tab) +{ + serial_channel *chan = (serial_channel *)tab->priv; + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; +#ifdef CYGDBG_IO_INIT + diag_printf("SLEB SERIAL init - dev: %x.%d.%d\n", sdtr_chan->base, sdtr_chan->tx_int_num, sdtr_chan->rx_int_num); +#endif + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + if (chan->out_cbuf.len != 0) { + cyg_drv_interrupt_create(sdtr_chan->tx_int_num, + 99, // Priority - unused + (cyg_addrword_t)chan, // Data item passed to interrupt handler + sleb_sdtr_tx_ISR, + sleb_sdtr_tx_DSR, + &sdtr_chan->tx_serial_interrupt_handle, + &sdtr_chan->tx_serial_interrupt); + cyg_drv_interrupt_attach(sdtr_chan->tx_serial_interrupt_handle); + cyg_drv_interrupt_mask(sdtr_chan->tx_int_num); + cyg_drv_interrupt_create(sdtr_chan->rx_int_num, + 99, // Priority - unused + (cyg_addrword_t)chan, // Data item passed to interrupt handler + sleb_sdtr_rx_ISR, + sleb_sdtr_rx_DSR, + &sdtr_chan->rx_serial_interrupt_handle, + &sdtr_chan->rx_serial_interrupt); + cyg_drv_interrupt_attach(sdtr_chan->rx_serial_interrupt_handle); + cyg_drv_interrupt_unmask(sdtr_chan->rx_int_num); + } + sleb_sdtr_config_port(chan, &chan->config, true); + return true; +} + +// This routine is called when the device is "looked" up (i.e. attached) +static Cyg_ErrNo +sleb_sdtr_lookup(struct cyg_devtab_entry **tab, + struct cyg_devtab_entry *sub_tab, + const char *name) +{ + serial_channel *chan = (serial_channel *)(*tab)->priv; + (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices + return ENOERR; +} + +// Send a character to the device output buffer. +// Return 'true' if character is sent to device +static bool +sleb_sdtr_putc(serial_channel *chan, unsigned char c) +{ + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; + CYG_ADDRWORD port = sdtr_chan->base; + cyg_uint8 status; + HAL_SPARC_86940_READ(SDTR_STATUS(port), status); + if (status & SDTR_STAT_TxRDY) { +// Transmit buffer is empty + HAL_SPARC_86940_WRITE(SDTR_TXDATA(port), c); + return true; + } else { +// No space + return false; + } +} + +// Fetch a character from the device input buffer, waiting if necessary +static unsigned char +sleb_sdtr_getc(serial_channel *chan) +{ + unsigned char c; + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; + CYG_ADDRWORD port = sdtr_chan->base; + cyg_uint8 status; + HAL_SPARC_86940_READ(SDTR_STATUS(port), status); + while ((status & SDTR_STAT_RxRDY) == 0) + HAL_SPARC_86940_READ(SDTR_STATUS(port), status); // Wait for char + HAL_SPARC_86940_READ(SDTR_RXDATA(port), c); + return c; +} + +// Set up the device characteristics; baud rate, etc. +static bool +sleb_sdtr_set_config(serial_channel *chan, cyg_serial_info_t *config) +{ + return sleb_sdtr_config_port(chan, config, false); +} + +// Enable the transmitter on the device +static void +sleb_sdtr_start_xmit(serial_channel *chan) +{ + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; + sdtr_chan->xmit_enabled = true; + cyg_drv_interrupt_unmask(sdtr_chan->tx_int_num); +} + +// Disable the transmitter on the device +static void +sleb_sdtr_stop_xmit(serial_channel *chan) +{ + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; + cyg_drv_interrupt_mask(sdtr_chan->tx_int_num); + sdtr_chan->xmit_enabled = false; +} + +// Serial I/O - low level interrupt handler (ISR) +static cyg_uint32 +sleb_sdtr_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; + cyg_drv_interrupt_mask(sdtr_chan->tx_int_num); + cyg_drv_interrupt_acknowledge(sdtr_chan->tx_int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level interrupt handler (DSR) +static void +sleb_sdtr_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; + (chan->callbacks->xmt_char)(chan); + if (sdtr_chan->xmit_enabled) + cyg_drv_interrupt_unmask(sdtr_chan->tx_int_num); +} + +// Serial I/O - low level interrupt handler (ISR) +static cyg_uint32 +sleb_sdtr_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; + cyg_drv_interrupt_mask(sdtr_chan->rx_int_num); + return CYG_ISR_CALL_DSR; // Cause DSR to be run +} + +// Serial I/O - high level interrupt handler (DSR) +static void +sleb_sdtr_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + serial_channel *chan = (serial_channel *)data; + sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; + CYG_ADDRWORD port = sdtr_chan->base; + cyg_uint8 status, c; + HAL_SPARC_86940_READ(SDTR_STATUS(port), status); + if ((status & SDTR_STAT_RxRDY) != 0) { + HAL_SPARC_86940_READ(SDTR_RXDATA(port), c); + (chan->callbacks->rcv_char)(chan, c); + } + cyg_drv_interrupt_acknowledge(sdtr_chan->rx_int_num); + cyg_drv_interrupt_unmask(sdtr_chan->rx_int_num); +} + +#endif // CYGPKG_IO_SERIAL_SPARCLITE_SLEB diff --git a/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.h b/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.h new file mode 100644 --- /dev/null +++ b/packages/devs/serial/sparclite/sleb/current/src/sleb_sdtr.h @@ -0,0 +1,158 @@ +#ifndef CYGONCE_SLEB_SDTR_H +#define CYGONCE_SLEB_SDTR_H +//========================================================================== +// +// io/serial/sparclite/sleb_sdtr.c +// +// Serial I/O interface module for SPARClite Eval Board (SLEB) +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1999-02-04 +// Purpose: SLEB serial I/O module +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include // For I/O macros + +#define reg(n) ((n)*4) + +// SDTR Registers +#define SDTR_TXDATA(base) base+reg(0) +#define SDTR_RXDATA(base) base+reg(0) +#define SDTR_STATUS(base) base+reg(1) +#define SDTR_CONTROL(base) base+reg(1) + +// Mode register +#define SDTR_MODE_MODE_MASK 0x03 // Mode selection bits (mask) +#define SDTR_MODE_MODE_SYNC 0x00 // Synchronous mode +#define SDTR_MODE_MODE_ASYNC1 0x01 // Async - clock/1 +#define SDTR_MODE_MODE_ASYNC16 0x02 // Async - clock/16 +#define SDTR_MODE_MODE_ASYNC64 0x03 // Async - clock/64 +#define SDTR_MODE_DTB_MASK 0x0C // Number of data bits (mask) +#define SDTR_MODE_DTB_5 0x00 // 5 bits / char +#define SDTR_MODE_DTB_6 0x04 // 6 bits / char +#define SDTR_MODE_DTB_7 0x08 // 7 bits / char +#define SDTR_MODE_DTB_8 0x0C // 8 bits / char +#define SDTR_MODE_PARITY_MASK 0x30 // Parity modes (mask) +#define SDTR_MODE_PARITY_ENABLE 0x10 // Enable parity +#define SDTR_MODE_PARITY_NONE 0x00 // No parity (parity disabled) +#define SDTR_MODE_PARITY_ODD 0x00 // Odd parity +#define SDTR_MODE_PARITY_EVEN 0x20 // Even parity +#define SDTR_MODE_STOP_BITS_MASK 0xC0 // Number of stop bits (mask) +#define SDTR_MODE_STOP_BITS_1 0x40 // 1 stop bit +#define SDTR_MODE_STOP_BITS_1_5 0x80 // 1.5 stop bits +#define SDTR_MODE_STOP_BITS_2 0xC0 // 2 stop bits + +// Command register +#define SDTR_CMD_TxEN 0x01 // Enable transmitter +#define SDTR_CMD_DTR 0x02 // Assert DTR +#define SDTR_CMD_RxEN 0x04 // Enable receiver +#define SDTR_CMD_BREAK 0x08 // Send break +#define SDTR_CMD_EFR 0x10 // Error flag reset +#define SDTR_CMD_RTS 0x20 // Assert RTS +#define SDTR_CMD_RST 0x40 // Internal RESET +#define SDTR_CMD_EHM 0x80 // Enable Hunt mode + +// Status register +#define SDTR_STAT_TxRDY 0x01 // Transmitter ready +#define SDTR_STAT_RxRDY 0x02 // Receiver ready +#define SDTR_STAT_TxEMP 0x04 // Transmitter empty +#define SDTR_STAT_PERR 0x08 // Parity error +#define SDTR_STAT_OERR 0x10 // Overrun error +#define SDTR_STAT_FERR 0x20 // Framing error +#define SDTR_STAT_SYBRK 0x40 // Break +#define SDTR_STAT_DSR 0x80 // State of DSR signal + +// Offsets to standard SDTR elements +#define SLEB_SDTR0_BASE (8*4) +#define SLEB_SDTR0_TX_INT 9 +#define SLEB_SDTR0_RX_INT 10 +#define SLEB_SDTR1_BASE (12*4) +#define SLEB_SDTR1_TX_INT 6 +#define SLEB_SDTR1_RX_INT 7 +#define SLEB_TIMER3_CONTROL reg(29) +#define SLEB_TIMER3_RELOAD reg(30) + +// On-board switch, used to determine baud rate +#define SLEB_CLOCK_SWITCH (volatile unsigned char *)0x01000003 + +static unsigned char select_word_length[] = { + SDTR_MODE_DTB_5, // 5 bits / word (char) + SDTR_MODE_DTB_6, + SDTR_MODE_DTB_7, + SDTR_MODE_DTB_8 +}; + +static unsigned char select_stop_bits[] = { + 0, + SDTR_MODE_STOP_BITS_1, // 1 stop bit + SDTR_MODE_STOP_BITS_1_5, // 1.5 stop bit + SDTR_MODE_STOP_BITS_2 // 2 stop bits +}; + +static unsigned char select_parity[] = { + SDTR_MODE_PARITY_NONE, // No parity + SDTR_MODE_PARITY_ENABLE|SDTR_MODE_PARITY_EVEN, // Even parity + SDTR_MODE_PARITY_ENABLE|SDTR_MODE_PARITY_ODD, // ODD parity + 0xFF, // Mark parity + 0xFF, // Space parity +}; + +static cyg_int32 select_baud[] = { + 0, // Unused + 50, // 50 + 75, // 75 + 110, // 110 + 0, // 134.5 + 150, // 150 + 200, // 200 + 300, // 300 + 600, // 600 + 1200, // 1200 + 1800, // 1800 + 2400, // 2400 + 3600, // 3600 + 4800, // 4800 + 7200, // 7200 + 9600, // 9600 + 14400, // 14400 + 19200, // 19200 + 38400, // 38400 + 57600, // 57600 + 115200, // 115200 + 230400, // 230400 +}; + +#endif // CYGONCE_SLEB_SDTR_H + diff --git a/packages/devs/wallclock/sh3/current/cdl/wallclock_sh3.cdl b/packages/devs/wallclock/sh3/current/cdl/wallclock_sh3.cdl --- a/packages/devs/wallclock/sh3/current/cdl/wallclock_sh3.cdl +++ b/packages/devs/wallclock/sh3/current/cdl/wallclock_sh3.cdl @@ -81,7 +81,7 @@ cdl_package CYGPKG_DEVICES_WALLCLOCK_SH3 } cdl_option CYGPKG_DEVICES_WALLCLOCK_SH3_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/devs/watchdog/current/cdl/watchdog.cdl b/packages/devs/watchdog/current/cdl/watchdog.cdl --- a/packages/devs/watchdog/current/cdl/watchdog.cdl +++ b/packages/devs/watchdog/current/cdl/watchdog.cdl @@ -93,7 +93,7 @@ cdl_package CYGPKG_DEVICES_WATCHDOG { } cdl_option CYGPKG_DEVICES_WATCHDOG_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/ecos.db b/packages/ecos.db --- a/packages/ecos.db +++ b/packages/ecos.db @@ -82,12 +82,134 @@ package CYGPKG_IO_SERIAL { alias { "Serial device drivers" serial io_serial } directory io/serial script io_serial.cdl - hardware description " This package contains drivers for basic I/O services on serial devices." } +package CYGPKG_IO_SERIAL_ARM_EBSA285 { + alias { "Intel EBSA285 serial driver" + devs_serial_arm_ebsa285 ebsa285_serial_driver } + hardware + directory devs/serial/arm/ebsa285 + script ser_arm_ebsa285.cdl + description "Intel StrongARM/EBSA285 serial device drivers" +} + +package CYGPKG_IO_SERIAL_ARM_PID { + alias { "ARM PID serial device drivers" + devs_serial_arm_pid pid_serial_driver } + hardware + directory devs/serial/arm/pid + script ser_arm_pid.cdl + description "ARM PID serial device drivers" +} + +package CYGPKG_IO_SERIAL_ARM_AEB { + alias { "ARM AEB-1 serial device drivers" + devs_serial_arm_aeb aeb_serial_driver } + hardware + directory devs/serial/arm/aeb + script ser_arm_aeb.cdl + description "ARM AEB-1 serial device drivers" +} + +package CYGPKG_IO_SERIAL_ARM_EDB7XXX { + alias { "ARM EDB7XXX serial device drivers" + devs_serial_arm_edb7xxx edb7xxx_serial_driver } + hardware + directory devs/serial/arm/edb7xxx + script ser_arm_edb7xxx.cdl + description "ARM EDB7XXX serial device drivers" +} + +package CYGPKG_IO_SERIAL_ARM_CMA230 { + alias { "Cogent ARM/CMA230 serial device drivers" + devs_serial_arm_cma230 cma230_serial_driver } + hardware + directory devs/serial/arm/cma230 + script ser_arm_cma230.cdl + description "Cogent ARM/CMA230 serial device drivers" +} + +package CYGPKG_IO_SERIAL_POWERPC_COGENT { + alias { "Cogent PowerPC serial device drivers" + devs_serial_powerpc_cogent cogent_serial_driver } + hardware + directory devs/serial/powerpc/cogent + script ser_powerpc_cogent.cdl + description "Cogent PowerPC serial device drivers" +} + +package CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC { + alias { "PowerPC QUICC/SMC serial device drivers" + devs_serial_quicc_smc quicc_smc_serial_driver + devs_serial_powerpc_quicc_smc + devs_serial_powerpc_quicc quicc_serial_driver } + hardware + directory devs/serial/powerpc/quicc + script ser_quicc_smc.cdl + description "PowerPC QUICC/SMC serial device drivers" +} + +package CYGPKG_IO_SERIAL_SPARCLITE_SLEB { + alias { "SPARClite SLEB serial device drivers" + devs_serial_sparclite_sleb sleb_serial_driver } + hardware + directory devs/serial/sparclite/sleb + script ser_sparclite_sleb.cdl + description "SPARClite SLEB serial device drivers" +} + +package CYGPKG_IO_SERIAL_TX39_JMR3904 { + alias { "TX39 JMR3904 serial device drivers" + devs_serial_tx39_jmr3904 jmr3904_serial_driver + devs_serial_mips_jmr3904 tx3904_serial_driver } + hardware + directory devs/serial/mips/jmr3904 + script ser_mips_jmr3904.cdl + description "TX39 JMR3904 serial device drivers" +} + +package CYGPKG_IO_SERIAL_MIPS_VRC4373 { + alias { "VRC4373 serial device drivers" + devs_serial_mips_vrc4373 vrc4373_serial_driver } + hardware + directory devs/serial/mips/vrc4373 + script ser_mips_vrc4373.cdl + description "VRC4373 serial device drivers" +} + +package CYGPKG_IO_SERIAL_MN10300 { + alias { "MN10300 serial device drivers" + devs_serial_mn10300_mn10300 + devs_serial_mn10300 mn10300_serial_driver } + hardware + directory devs/serial/mn10300/mn10300 + script ser_mn10300.cdl + description "MN10300 serial device drivers" +} + +package CYGPKG_IO_SERIAL_I386_PC { + alias { "PC serial device drivers" + devs_serial_i386_pc pc_serial_driver } + hardware + directory devs/serial/i386/pc + script ser_i386_pc.cdl + description "PC serial device drivers" +} + +package CYGPKG_IO_SERIAL_SH_EDK7708 { + alias { "SH3 EDK7708 serial device drivers" + devs_serial_sh3_edk7708 + devs_serial_sh_edk7708 edk7708_serial_driver } + hardware + directory devs/serial/sh/edk7708 + script ser_sh_edk7708.cdl + description "SH3 EDK7708 serial device drivers" +} + + package CYGPKG_IO_PCI { alias { "PCI configuration library" io_pci } directory io/pci @@ -599,7 +721,7 @@ target pid { alias { "ARM development board (PID)" PID } packages { CYGPKG_HAL_ARM CYGPKG_HAL_ARM_PID - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_ARM_PID } description " The pid target provides the packages needed to run eCos on an ARM @@ -610,7 +732,7 @@ target aeb { alias { "ARM evaluation board (AEB-1)" aeb1 } packages { CYGPKG_HAL_ARM CYGPKG_HAL_ARM_AEB - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_ARM_AEB } description " The aeb target provides the packages needed to run eCos on an ARM @@ -621,8 +743,9 @@ target ebsa285 { alias { "Intel EBSA285 StrongARM board" ebsa } packages { CYGPKG_HAL_ARM CYGPKG_HAL_ARM_EBSA285 - CYGPKG_IO_SERIAL CYGPKG_IO_PCI + CYGPKG_DEVS_ETH_ARM_EBSA285 + CYGPKG_IO_SERIAL_ARM_EBSA285 } description " The ebsa285 target provides the packages needed to run @@ -633,7 +756,8 @@ target edb7xxx { alias { "Cirrus Logic development board" edb7211 eb7xxx eb7211 } packages { CYGPKG_HAL_ARM CYGPKG_HAL_ARM_EDB7XXX - CYGPKG_IO_SERIAL + CYGPKG_DEVS_ETH_ARM_EDB7XXX + CYGPKG_IO_SERIAL_ARM_EDB7XXX } description " The edb7xxx target provides the packages needed to run eCos on Cirrus Logic development boards." @@ -643,7 +767,7 @@ target cma230 { alias { "Cogent CMA230/222 board" cma222 } packages { CYGPKG_HAL_ARM CYGPKG_HAL_ARM_CMA230 - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_ARM_CMA230 } description " The cma230 target provides the packages needed to run eCos on a Cogent @@ -657,8 +781,8 @@ target sh7708 { alias { "Hitachi EDK/SH7708 board" edk7708 } packages { CYGPKG_HAL_SH CYGPKG_HAL_SH_EDK7708 - CYGPKG_IO_SERIAL CYGPKG_DEVICES_WALLCLOCK_SH3 + CYGPKG_IO_SERIAL_SH_EDK7708 } enable { CYGPKG_HAL_SH_7708 } description " @@ -674,7 +798,6 @@ target linux { alias { "Linux synthetic target" } packages { CYGPKG_HAL_I386 CYGPKG_HAL_I386_LINUX - CYGPKG_IO_SERIAL } description " The linux target provides the @@ -686,7 +809,7 @@ target pc { alias { "i386 PC target" } packages { CYGPKG_HAL_I386 CYGPKG_HAL_I386_PC - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_I386_PC } description " The pc target provides the @@ -701,7 +824,7 @@ target sleb { alias { "Fujitsu MB86800-MA01 board" } packages { CYGPKG_HAL_SPARCLITE CYGPKG_HAL_SPARCLITE_SLEB - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_SPARCLITE_SLEB } description " The sleb target provides the packages need to run eCos @@ -712,7 +835,6 @@ target sparclite_sim { alias { "SPARClite simulator" sl_sim sparcl_sim } packages { CYGPKG_HAL_SPARCLITE CYGPKG_HAL_SPARCLITE_SIM - CYGPKG_IO_SERIAL } description " The sparclite_sim target provides the packages need to run eCos @@ -727,7 +849,7 @@ target cma28x { packages { CYGPKG_HAL_POWERPC CYGPKG_HAL_POWERPC_MPC8xx CYGPKG_HAL_POWERPC_COGENT - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_POWERPC_COGENT } description " The cma28x target provides the packages needed to run @@ -739,7 +861,6 @@ target fads { packages { CYGPKG_HAL_POWERPC CYGPKG_HAL_POWERPC_MPC8xx CYGPKG_HAL_POWERPC_FADS - CYGPKG_IO_SERIAL } description " The fads target provides the packages needed to run @@ -752,7 +873,8 @@ target mbx { CYGPKG_HAL_POWERPC_MPC8xx CYGPKG_HAL_POWERPC_MBX CYGPKG_HAL_QUICC - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC + CYGPKG_DEVS_ETH_POWERPC_QUICC } description " The mbx target provides the packages needed to run @@ -764,7 +886,6 @@ target psim { packages { CYGPKG_HAL_POWERPC CYGPKG_HAL_POWERPC_PPC60x CYGPKG_HAL_POWERPC_SIM - CYGPKG_IO_SERIAL } description " The psim target provides the packages needed to run @@ -779,7 +900,7 @@ target jmr3904 { packages { CYGPKG_HAL_MIPS CYGPKG_HAL_MIPS_TX39 CYGPKG_HAL_MIPS_TX39_JMR3904 - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_TX39_JMR3904 } description " The jmr3904 target provides the packages needed to run @@ -810,7 +931,7 @@ target vrc4373 { packages { CYGPKG_HAL_MIPS CYGPKG_HAL_MIPS_VR4300 CYGPKG_HAL_MIPS_VR4300_VRC4373 - CYGPKG_IO_SERIAL CYGPKG_IO_PCI + CYGPKG_IO_SERIAL_MIPS_VRC4373 } description " The vrc4373 target provides the packages needed to run @@ -838,7 +959,7 @@ target stdeval1 { packages { CYGPKG_HAL_MN10300 CYGPKG_HAL_MN10300_AM31_STDEVAL1 CYGPKG_HAL_MN10300_AM31 - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_MN10300 } description " The stdeval1 target provides the packages needed to run @@ -852,7 +973,7 @@ target stb { packages { CYGPKG_HAL_MN10300 CYGPKG_HAL_MN10300_AM33_STB CYGPKG_HAL_MN10300_AM33 - CYGPKG_IO_SERIAL + CYGPKG_IO_SERIAL_MN10300 } description " The stb target provides the packages needed to run diff --git a/packages/hal/arm/arch/current/ChangeLog b/packages/hal/arm/arch/current/ChangeLog --- a/packages/hal/arm/arch/current/ChangeLog +++ b/packages/hal/arm/arch/current/ChangeLog @@ -1,3 +1,11 @@ +2000-04-10 Hugo Tyson + + * include/arm_stub.h (CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION): Only + use this complex version if we have + CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT ie. the place_break &c routines + existed anyway. This is an artificial limitation, somewhat, but + not so painful in reality. + 2000-04-04 Jesper Skov * src/context.S: diff --git a/packages/hal/arm/arch/current/include/arm_stub.h b/packages/hal/arm/arch/current/include/arm_stub.h --- a/packages/hal/arm/arch/current/include/arm_stub.h +++ b/packages/hal/arm/arch/current/include/arm_stub.h @@ -109,6 +109,10 @@ extern void __clear_breakpoints (void); //------------------------------------------------------------------------ // Special definition of CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION + +#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT +// we can only do this at all if break support is enabled: + #ifdef __thumb__ // If this macro is used from Thumb code, we need to pass this information // along to the place_break function so it can do the right thing. @@ -126,8 +130,8 @@ do { cyg_hal_gdb_place_break((target_register_t)&&cyg_hal_gdb_break_place ); \ } while ( 0 ) -#endif - +#endif // __thumb_ +#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT #ifdef __cplusplus diff --git a/packages/hal/arm/cma230/current/cdl/hal_arm_cma230.cdl b/packages/hal/arm/cma230/current/cdl/hal_arm_cma230.cdl --- a/packages/hal/arm/cma230/current/cdl/hal_arm_cma230.cdl +++ b/packages/hal/arm/cma230/current/cdl/hal_arm_cma230.cdl @@ -191,7 +191,7 @@ cdl_package CYGPKG_HAL_ARM_CMA230 { } cdl_option CYGPKG_HAL_ARM_CMA2XX_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/hal/arm/ebsa285/current/cdl/hal_arm_ebsa285.cdl b/packages/hal/arm/ebsa285/current/cdl/hal_arm_ebsa285.cdl --- a/packages/hal/arm/ebsa285/current/cdl/hal_arm_ebsa285.cdl +++ b/packages/hal/arm/ebsa285/current/cdl/hal_arm_ebsa285.cdl @@ -212,7 +212,7 @@ cdl_package CYGPKG_HAL_ARM_EBSA285 { } cdl_option CYGPKG_HAL_ARM_EBSA285_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/hal/arm/edb7xxx/current/ChangeLog b/packages/hal/arm/edb7xxx/current/ChangeLog --- a/packages/hal/arm/edb7xxx/current/ChangeLog +++ b/packages/hal/arm/edb7xxx/current/ChangeLog @@ -1,3 +1,7 @@ +2000-04-07 Gary Thomas + + * cdl/hal_arm_edb7xxx.cdl: Fix build of i2s audio test. + 2000-02-29 Jonathan Larmour * include/pkgconf/mlt_arm_cl7111_ram.h: diff --git a/packages/hal/arm/edb7xxx/current/cdl/hal_arm_edb7xxx.cdl b/packages/hal/arm/edb7xxx/current/cdl/hal_arm_edb7xxx.cdl --- a/packages/hal/arm/edb7xxx/current/cdl/hal_arm_edb7xxx.cdl +++ b/packages/hal/arm/edb7xxx/current/cdl/hal_arm_edb7xxx.cdl @@ -365,7 +365,7 @@ cdl_package CYGPKG_HAL_ARM_EDB7XXX { @echo >> $(notdir $@).deps # warning: no proper deps here $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(CFLAGS) -o misc/i2s_audio_fiq.o $(REPOSITORY)/$(PACKAGE)/misc/i2s_audio_fiq.S - $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ misc/lcd_test.o misc/i2s_audio_fiq.o + $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ misc/i2s_audio_test.o misc/i2s_audio_fiq.o } } @@ -396,7 +396,7 @@ cdl_package CYGPKG_HAL_ARM_EDB7XXX { } cdl_option CYGPKG_HAL_ARM_EDB7XXX_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/hal/common/current/ChangeLog b/packages/hal/common/current/ChangeLog --- a/packages/hal/common/current/ChangeLog +++ b/packages/hal/common/current/ChangeLog @@ -1,3 +1,11 @@ +2000-04-12 Jesper Skov + + * cdl/debugging.cdl: Don't let interfaces define anything. + +2000-04-07 Jesper Skov + + * cdl/hal.cdl: Fix dependencies for stub. + 2000-03-28 Jesper Skov * src/generic-stub.c (__process_packet): Added 'z' packet reply. diff --git a/packages/hal/common/current/cdl/debugging.cdl b/packages/hal/common/current/cdl/debugging.cdl --- a/packages/hal/common/current/cdl/debugging.cdl +++ b/packages/hal/common/current/cdl/debugging.cdl @@ -42,6 +42,7 @@ cdl_interface CYGINT_HAL_DEBUG_GDB_STUBS { display "Support for GDB stubs" + no_define description " The HAL implements GDB stubs for the target." } @@ -62,6 +63,7 @@ cdl_option CYGDBG_HAL_DEBUG_GDB_INCLUDE_ cdl_interface CYGINT_HAL_DEBUG_GDB_STUBS_BREAK { display "Support for external break support in GDB stubs" + no_define description " The HAL implements external break (or asynchronous interrupt) in the GDB stubs for the target." diff --git a/packages/hal/common/current/cdl/hal.cdl b/packages/hal/common/current/cdl/hal.cdl --- a/packages/hal/common/current/cdl/hal.cdl +++ b/packages/hal/common/current/cdl/hal.cdl @@ -145,7 +145,7 @@ cdl_package CYGPKG_HAL { appropriate, controls the building of the common stub." make -priority 315 { - /bin/gdb_module.img : /src/stubrom/stubrom.c + /bin/gdb_module.img : /src/stubrom/stubrom.c /lib/extras.o /lib/libtarget.a /lib/target.ld /lib/vectors.o @sh -c "mkdir -p src/stubrom $(dir $@)" $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o src/stubrom/gdb_module.o $< @echo $@ ": \\" > $(notdir $@).deps diff --git a/packages/hal/powerpc/arch/current/ChangeLog b/packages/hal/powerpc/arch/current/ChangeLog --- a/packages/hal/powerpc/arch/current/ChangeLog +++ b/packages/hal/powerpc/arch/current/ChangeLog @@ -1,3 +1,20 @@ +2000-04-14 Jesper Skov + + * src/hal_misc.c (hal_idle_thread_action): Moved some of the code + to variant idle functions which now get called. + (hal_enable_caches): Moved serialization code to 8xx variant init. + + * src/vectors.S (restore_state): Use hal_fpu_load and + hal_variant_load. Reported by Sergei Organov (osv at javad.ru). + +2000-04-11 Jesper Skov + + * src/powerpc.ld: VSR table location is controlled by CDL. + + * cdl/hal_powerpc.cdl: Added new options to control vector base + and MMU activation. Based on a patch from Sergei Organov (osv at + javad.ru). + 2000-04-06 Jonathan Larmour * include/hal_intr.h (HAL_CLOCK_RESET): Prevent warning @@ -151,6 +168,10 @@ 2000-02-03 Jesper Skov CYGPKG_... +2000-01-28 Gary Thomas + + * src/powerpc.ld: Add support for network package. + 2000-01-26 Jesper Skov * include/hal_cache.h: Include plf_cache.h diff --git a/packages/hal/powerpc/arch/current/cdl/hal_powerpc.cdl b/packages/hal/powerpc/arch/current/cdl/hal_powerpc.cdl --- a/packages/hal/powerpc/arch/current/cdl/hal_powerpc.cdl +++ b/packages/hal/powerpc/arch/current/cdl/hal_powerpc.cdl @@ -54,6 +54,7 @@ cdl_package CYGPKG_HAL_POWERPC { cdl_interface CYGINT_HAL_POWERPC_VARIANT { display "Number of variant implementations in this configuration" + no_define requires 1 == CYGINT_HAL_POWERPC_VARIANT } @@ -98,15 +99,51 @@ cdl_package CYGPKG_HAL_POWERPC { requires ! CYGSEM_HAL_USE_ROM_MONITOR description " Enable this option to force exception vectors to be copied - to address 0 on startup. For RAM startup this is normally + to the vector base on startup. For RAM startup this is normally disabled since the vectors would already have been provided by the GDB stubs - but it's possible to override, thus taking full control of the target. For ROM startup it is desirable to - enable this option for performance reasons (accessing vectors - in ROM is normally slower) - but if memory is tight the vectors - can be left in ROM." + enable this option if the vector base is set to RAM since + accessing vectors in ROM is normally slower. But if memory is + tight the vectors can be left in ROM." + } + + cdl_option CYGHWR_HAL_POWERPC_NEED_VECTORS { + display "Exception vectors inclusion" + description " + If eCos can rely on the target environment to provide + eCos compatible vector code, there is no reason to include + the additional data in application images. This option controls + the inclusion of the vector code." + # Platform HALs and startup configuration controls this setting. + calculated { ((CYGHWR_HAL_POWERPC_FORCE_VECTORS || + CYG_HAL_STARTUP != "RAM" || + CYGSEM_HAL_POWERPC_COPY_VECTORS) && + ! CYGSEM_HAL_USE_ROM_MONITOR) + ? 1 : 0 } } + cdl_option CYGHWR_HAL_POWERPC_VECTOR_BASE { + display "Exception vectors location" + description " + PowerPC exception vectors can reside either at 0x00000000 or + 0xfff00000. The startup type and platform HAL controls which + is used." + flavor data + calculated { (CYGHWR_HAL_POWERPC_FORCE_VECTOR_BASE_HIGH || + (CYG_HAL_STARTUP != "RAM" && + ! CYGSEM_HAL_POWERPC_COPY_VECTORS)) + ? 0xfff00000 : 0x00000000 } + } + + cdl_option CYGHWR_HAL_POWERPC_ENABLE_MMU { + display "Enable MMU" + calculated { !CYGHWR_HAL_POWERPC_DISABLE_MMU } + description " + Some platforms do not want the MMU enabled." + } + + cdl_option CYGDBG_HAL_POWERPC_FRAME_WALLS { display "Exception stack-frame walls" default_value 0 @@ -119,6 +156,7 @@ cdl_package CYGPKG_HAL_POWERPC { cdl_component CYGPKG_HAL_POWERPC_OPTIONS { display "PowerPC build options" flavor none + no_define description " Package specific build options including control over compiler flags used only in building this package, @@ -137,7 +175,7 @@ cdl_package CYGPKG_HAL_POWERPC { } cdl_option CYGPKG_HAL_POWERPC_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/hal/powerpc/arch/current/src/hal_misc.c b/packages/hal/powerpc/arch/current/src/hal_misc.c --- a/packages/hal/powerpc/arch/current/src/hal_misc.c +++ b/packages/hal/powerpc/arch/current/src/hal_misc.c @@ -226,25 +226,26 @@ hal_default_decrementer_isr(CYG_ADDRWORD //--------------------------------------------------------------------------- // Idle thread action +externC bool hal_variant_idle_thread_action(cyg_uint32); + void hal_idle_thread_action( cyg_uint32 count ) { -#if 0 -#ifdef CYGPKG_HAL_POWERPC_MPC860 - register cyg_uint32 result; + // Execute variant idle thread action, while allowing it to control + // whether to run any of the architecture action code. + if (!hal_variant_idle_thread_action(count)) + return; - cyg_uint32 *psivec = (cyg_uint32*)CYGARC_REG_IMM_SIVEC ; - cyg_uint32 *psimask = (cyg_uint32*)CYGARC_REG_IMM_SIMASK; - cyg_uint32 *psipend = (cyg_uint32*)CYGARC_REG_IMM_SIPEND; - cyg_uint16 *ptbscr = (cyg_uint16*)CYGARC_REG_IMM_TBSCR; +#if 0 + do { + register cyg_uint32 dec; - asm volatile( - "mfdec %0;" - : "=r"(result) - ); - diag_printf( "Dec %08x, TBSCR %04x, vec %d: sivec %08x, simask %08x, sipend %08x\n", - result, (cyg_uint32)(*ptbscr), (*psivec)>>26, *psivec, *psimask, *psipend ); -#endif + asm volatile( + "mfdec %0;" + : "=r"(dec) + ); + diag_printf( "Decrementer %08x\n", dec); + } while (0); #endif } @@ -292,16 +293,6 @@ hal_enable_caches(void) HAL_DCACHE_ENABLE(); #endif #endif - -#ifdef CYGPKG_HAL_POWERPC_MPC8xx - // Disable serialization - { - cyg_uint32 ictrl; - CYGARC_MFSPR (ICTRL, ictrl); - ictrl |= ICTRL_NOSERSHOW; - CYGARC_MTSPR (ICTRL, ictrl); - } -#endif } //--------------------------------------------------------------------------- diff --git a/packages/hal/powerpc/arch/current/src/powerpc.ld b/packages/hal/powerpc/arch/current/src/powerpc.ld --- a/packages/hal/powerpc/arch/current/src/powerpc.ld +++ b/packages/hal/powerpc/arch/current/src/powerpc.ld @@ -140,7 +140,6 @@ GROUP(libtarget.a libgcc.a) #include #include CYGHWR_MEMORY_LAYOUT_LDI -// Define VSR table to reside at fixed address. This address will -// probably have to be variant specific for optimal memory usage, but -// for now just put it above the PPC family reserved exception space. -hal_vsr_table = 0x3000; +// Define VSR table to reside at fixed address. +#include CYGBLD_HAL_TARGET_H +hal_vsr_table = CYGHWR_HAL_VSR_TABLE; diff --git a/packages/hal/powerpc/arch/current/src/vectors.S b/packages/hal/powerpc/arch/current/src/vectors.S --- a/packages/hal/powerpc/arch/current/src/vectors.S +++ b/packages/hal/powerpc/arch/current/src/vectors.S @@ -127,24 +127,22 @@ # DR = data address translation # RI = recoverable interrupt -#define CYG_MSR_COMMON (MSR_FP | MSR_ME | MSR_IR | MSR_DR | MSR_RI) -#if defined(CYG_HAL_STARTUP_ROM) -# ifdef CYGSEM_HAL_POWERPC_COPY_VECTORS -# define CYG_MSR CYG_MSR_COMMON -# else -# define CYG_MSR (CYG_MSR_COMMON | MSR_IP) -# endif -#elif defined(CYG_HAL_STARTUP_RAM) -# define CYG_MSR CYG_MSR_COMMON +#define CYG_MSR_COMMON (MSR_FP | MSR_ME | MSR_RI) + +#if (CYGHWR_HAL_POWERPC_VECTOR_BASE == 0xfff00000) +# define IP_BIT MSR_IP +#else +# define IP_BIT 0 #endif -#ifdef CYGPKG_HAL_POWERPC_SIM -# When building for SIM, don~t enable MMU -- it~s not needed since caches -# are disabled, and there is a runtime simulation overhead. -#undef CYG_MSR -#define CYG_MSR (CYG_MSR_COMMON & ~(MSR_IR | MSR_DR)) +#ifdef CYGHWR_HAL_POWERPC_ENABLE_MMU +# define IR_DR_BITS (MSR_IR | MSR_DR) +#else +# define IR_DR_BITS 0 #endif +#define CYG_MSR (CYG_MSR_COMMON | IP_BIT | IR_DR_BITS) + # Include variant macros after MSR definition. #include #include @@ -162,9 +160,7 @@ #endif -#if defined(CYG_HAL_STARTUP_ROM) || \ - defined(CYGPKG_HAL_POWERPC_SIM) || \ - defined(CYGSEM_HAL_POWERPC_COPY_VECTORS) +#if defined(CYGHWR_HAL_POWERPC_NEED_VECTORS) #=========================================================================== # Start by defining the exceptions vectors that must be placed at @@ -237,7 +233,7 @@ rom_vectors: rom_vectors_end: -#else // CYG_HAL_STARTUP_ROM || CYGSEM_HAL_POWERPC_COPY_VECTORS +#else // CYGHWR_HAL_POWERPC_NEED_VECTORS # When vectors are not included this is the primary entry point. .globl __exception_reset @@ -246,7 +242,7 @@ rom_vectors_end: mtlr r3 blr -#endif // CYG_HAL_STARTUP_ROM || CYGSEM_HAL_POWERPC_COPY_VECTORS +#endif // CYGHWR_HAL_POWERPC_NEED_VECTORS @@ -263,7 +259,7 @@ rom_vectors_end: #if !defined(CYG_HAL_STARTUP_ROM) && defined(CYGSEM_HAL_POWERPC_COPY_VECTORS) lwi r3,rom_vectors-4 - lwi r4,0x0000-4 + lwi r4,(CYGHWR_HAL_POWERPC_VECTOR_BASE - 4) lwi r5,rom_vectors_end-4 0: lwzu r0,4(r3) stwu r0,4(r4) @@ -348,6 +344,13 @@ 2: stw r0,8(sp) # zero return pc stwu sp,-CYGARC_PPC_STACK_FRAME_SIZE(sp) # create new stack frame + # Variant HALs may need to do something special before we continue + bl hal_variant_init + + # MMU and cache are controlled by the same option since caching + # on the PPC does not make sense without the MMU to mark regions + # which should not be cached. +#ifdef CYGHWR_HAL_POWERPC_ENABLE_MMU # Initialize MMU. bl hal_MMU_init @@ -359,6 +362,7 @@ 2: # Enable caches bl hal_enable_caches +#endif // CYGHWR_HAL_POWERPC_ENABLE_MMU # call c++ constructors bl cyg_hal_invoke_constructors @@ -728,7 +732,14 @@ 2: restore_state: # All done, restore CPU state and continue - addi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE*2 # retrieve CPU state pointer + # retrieve CPU state pointer + addi sp,sp,CYGARC_PPC_STACK_FRAME_SIZE*2 + + # Restore FPU registers + hal_fpu_load sp + + # Restore variant registers + hal_variant_load sp # get sprs we want to restore # stuff some of them into the CPU diff --git a/packages/hal/powerpc/mbx/current/cdl/hal_powerpc_mbx.cdl b/packages/hal/powerpc/mbx/current/cdl/hal_powerpc_mbx.cdl --- a/packages/hal/powerpc/mbx/current/cdl/hal_powerpc_mbx.cdl +++ b/packages/hal/powerpc/mbx/current/cdl/hal_powerpc_mbx.cdl @@ -212,7 +212,7 @@ cdl_package CYGPKG_HAL_POWERPC_MBX { } cdl_option CYGPKG_HAL_POWERPC_MBX_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/hal/powerpc/mpc8xx/current/ChangeLog b/packages/hal/powerpc/mpc8xx/current/ChangeLog --- a/packages/hal/powerpc/mpc8xx/current/ChangeLog +++ b/packages/hal/powerpc/mpc8xx/current/ChangeLog @@ -1,3 +1,13 @@ +2000-04-14 Jesper Skov + + * src/var_misc.c (hal_variant_init): Moved serialization disable + code to here. + * src/var_misc.c (hal_variant_idle_thread_action): Added. + +2000-04-11 Jesper Skov + + * cdl/hal_powerpc_mpc8xx.cdl: Define VSR table location. + 2000-03-02 Jesper Skov * cdl/hal_powerpc_mpc8xx.cdl: Further restrictions on diff --git a/packages/hal/powerpc/mpc8xx/current/cdl/hal_powerpc_mpc8xx.cdl b/packages/hal/powerpc/mpc8xx/current/cdl/hal_powerpc_mpc8xx.cdl --- a/packages/hal/powerpc/mpc8xx/current/cdl/hal_powerpc_mpc8xx.cdl +++ b/packages/hal/powerpc/mpc8xx/current/cdl/hal_powerpc_mpc8xx.cdl @@ -76,6 +76,11 @@ cdl_package CYGPKG_HAL_POWERPC_MPC8xx { exception handling to the ROM monitor." } + # Note: This should be sub-variant specific to reduce memory use. + define_proc { + puts $cdl_header "#define CYGHWR_HAL_VSR_TABLE (CYGHWR_HAL_POWERPC_VECTOR_BASE + 0x3000)" + } + cdl_component CYGPKG_HAL_POWERPC_MPC823 { display "PowerPC 823 microprocessor" implements CYGINT_HAL_POWERPC_VARIANT diff --git a/packages/hal/powerpc/mpc8xx/current/src/var_misc.c b/packages/hal/powerpc/mpc8xx/current/src/var_misc.c --- a/packages/hal/powerpc/mpc8xx/current/src/var_misc.c +++ b/packages/hal/powerpc/mpc8xx/current/src/var_misc.c @@ -46,13 +46,42 @@ #define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS #include -#include +#include // types +#include // diag_printf -#include +#include // some of the functions defined here //-------------------------------------------------------------------------- -void hal_variant_init(void) +void +hal_variant_init(void) { + // Disable serialization + { + cyg_uint32 ictrl; + CYGARC_MFSPR (ICTRL, ictrl); + ictrl |= ICTRL_NOSERSHOW; + CYGARC_MTSPR (ICTRL, ictrl); + } +} + +//-------------------------------------------------------------------------- +// Variant specific idle thread action. +bool +hal_variant_idle_thread_action( cyg_uint32 count ) +{ +#if 0 + cyg_uint32 *psivec = (cyg_uint32*)CYGARC_REG_IMM_SIVEC ; + cyg_uint32 *psimask = (cyg_uint32*)CYGARC_REG_IMM_SIMASK; + cyg_uint32 *psipend = (cyg_uint32*)CYGARC_REG_IMM_SIPEND; + cyg_uint16 *ptbscr = (cyg_uint16*)CYGARC_REG_IMM_TBSCR; + + diag_printf( "TBSCR %04x, vec %d: sivec %08x, simask %08x, sipend %08x\n", + (cyg_uint32)(*ptbscr), (*psivec)>>26, *psivec, + *psimask, *psipend ); +#endif + + // Let architecture idle thread action run + return true; } //--------------------------------------------------------------------------- diff --git a/packages/hal/powerpc/ppc60x/current/ChangeLog b/packages/hal/powerpc/ppc60x/current/ChangeLog --- a/packages/hal/powerpc/ppc60x/current/ChangeLog +++ b/packages/hal/powerpc/ppc60x/current/ChangeLog @@ -1,3 +1,11 @@ +2000-04-13 Jesper Skov + + * src/var_misc.c (hal_variant_idle_thread_action): Added. + +2000-04-11 Jesper Skov + + * cdl/hal_powerpc_ppc60x.cdl: Define VSR table location. + 2000-03-01 Jesper Skov * include/variant.inc: Forgot conditionals on vector copy code in diff --git a/packages/hal/powerpc/ppc60x/current/cdl/hal_powerpc_ppc60x.cdl b/packages/hal/powerpc/ppc60x/current/cdl/hal_powerpc_ppc60x.cdl --- a/packages/hal/powerpc/ppc60x/current/cdl/hal_powerpc_ppc60x.cdl +++ b/packages/hal/powerpc/ppc60x/current/cdl/hal_powerpc_ppc60x.cdl @@ -50,6 +50,11 @@ cdl_package CYGPKG_HAL_POWERPC_PPC60x { for this processor variant. It is also necessary to select a specific target platform HAL package." + # Note: This should be sub-variant specific to reduce memory use. + define_proc { + puts $cdl_header "#define CYGHWR_HAL_VSR_TABLE (CYGHWR_HAL_POWERPC_VECTOR_BASE + 0x3000)" + } + cdl_component CYGPKG_HAL_POWERPC_PPC603 { display "PowerPC 603 microprocessor" default_value 1 diff --git a/packages/hal/powerpc/ppc60x/current/src/var_misc.c b/packages/hal/powerpc/ppc60x/current/src/var_misc.c --- a/packages/hal/powerpc/ppc60x/current/src/var_misc.c +++ b/packages/hal/powerpc/ppc60x/current/src/var_misc.c @@ -55,6 +55,16 @@ void hal_variant_init(void) { } + +//-------------------------------------------------------------------------- +// Variant specific idle thread action. +bool +hal_variant_idle_thread_action( cyg_uint32 count ) +{ + // Let architecture idle thread action run + return true; +} + //--------------------------------------------------------------------------- // Use MMU resources to map memory regions. // Takes and returns an int used to ID the MMU resource to use. This ID diff --git a/packages/hal/powerpc/sim/current/ChangeLog b/packages/hal/powerpc/sim/current/ChangeLog --- a/packages/hal/powerpc/sim/current/ChangeLog +++ b/packages/hal/powerpc/sim/current/ChangeLog @@ -1,3 +1,8 @@ +2000-04-11 Jesper Skov + + * cdl/hal_powerpc_sim.cdl: Force inclusion of vectors, disable + MMU. + 2000-03-06 Jesper Skov * include/pkgconf/mlt_powerpc_sim_ram.mlt: diff --git a/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl b/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl --- a/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl +++ b/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl @@ -71,6 +71,21 @@ cdl_package CYGPKG_HAL_POWERPC_SIM { Only RAM startup is supported at the moment." } + cdl_option CYGHWR_HAL_POWERPC_FORCE_VECTORS { + display "Force creation of vectors section." + calculated 1 + } + + cdl_option CYGHWR_HAL_POWERPC_DISABLE_MMU { + display "Run with MMU disabled." + calculated 1 + no_define + description " + When building for SIM, don't enable MMU -- it's not needed + since caches are disabled, and there is a runtime simulation + overhead." + } + # Real-time clock/counter specifics cdl_component CYGNUM_HAL_RTC_CONSTANTS { display "Real-time clock constants." diff --git a/packages/hal/sh/arch/current/ChangeLog b/packages/hal/sh/arch/current/ChangeLog --- a/packages/hal/sh/arch/current/ChangeLog +++ b/packages/hal/sh/arch/current/ChangeLog @@ -1,3 +1,20 @@ +2000-04-12 Jesper Skov + + * src/vectors.S: Entry code rewritten to allow ROMRAM startups. + + * src/sh.ld: Change LMA alignment to 16 (workaround + 902557-CR). Provide vector LMA address. + + * include/sh_sci.inl: Replaced hardcoded baud rate constant with + macro function. + + * cdl/hal_sh.cdl: Don't let interface define anything. + +2000-04-10 Jesper Skov + + * include/hal_intr.h: Mask/unmask functions handle entire ISR + range now. + 2000-04-06 Jesper Skov * src/sh.ld (_hal_vsr_table): Get address from platform CDL. diff --git a/packages/hal/sh/arch/current/cdl/hal_sh.cdl b/packages/hal/sh/arch/current/cdl/hal_sh.cdl --- a/packages/hal/sh/arch/current/cdl/hal_sh.cdl +++ b/packages/hal/sh/arch/current/cdl/hal_sh.cdl @@ -54,6 +54,7 @@ cdl_package CYGPKG_HAL_SH { cdl_interface CYGINT_HAL_SH_VARIANT { display "Number of variant implementations in this configuration" + no_define requires 1 == CYGINT_HAL_SH_VARIANT } diff --git a/packages/hal/sh/arch/current/include/hal_intr.h b/packages/hal/sh/arch/current/include/hal_intr.h --- a/packages/hal/sh/arch/current/include/hal_intr.h +++ b/packages/hal/sh/arch/current/include/hal_intr.h @@ -457,7 +457,7 @@ externC cyg_uint8 cyg_hal_ILVL_table[]; case CYGNUM_HAL_INTERRUPT_LVL0...CYGNUM_HAL_INTERRUPT_LVL14: \ /* Can only be masked by fiddling Imask in SR. */ \ break; \ - case CYGNUM_HAL_INTERRUPT_TMU0_TUNI0...CYGNUM_HAL_INTERRUPT_REF_ROVI: \ + case CYGNUM_HAL_INTERRUPT_TMU0_TUNI0...CYGNUM_HAL_ISR_MAX: \ HAL_INTERRUPT_SET_LEVEL((_vector_), 0); \ break; \ case CYGNUM_HAL_INTERRUPT_RESERVED_1E0: \ @@ -478,7 +478,7 @@ externC cyg_uint8 cyg_hal_ILVL_table[]; case CYGNUM_HAL_INTERRUPT_LVL0...CYGNUM_HAL_INTERRUPT_LVL14: \ /* Can only be unmasked by fiddling Imask in SR. */ \ break; \ - case CYGNUM_HAL_INTERRUPT_TMU0_TUNI0...CYGNUM_HAL_INTERRUPT_REF_ROVI: \ + case CYGNUM_HAL_INTERRUPT_TMU0_TUNI0...CYGNUM_HAL_ISR_MAX: \ HAL_INTERRUPT_SET_LEVEL((_vector_), 1); \ break; \ case CYGNUM_HAL_INTERRUPT_RESERVED_1E0: \ diff --git a/packages/hal/sh/arch/current/include/sh3_scif.inl b/packages/hal/sh/arch/current/include/sh3_scif.inl --- a/packages/hal/sh/arch/current/include/sh3_scif.inl +++ b/packages/hal/sh/arch/current/include/sh3_scif.inl @@ -113,6 +113,8 @@ int cyg_hal_gdb_isr( target_register_t CYG_SCIF_PUBLIC void NC(init_serial)( void ) { + cyg_uint16 sr; + // Disable interrupts. #ifdef CYG_SCIF_IRDA // Note: This affects out all IRDA sources, not only RXI1. @@ -158,6 +160,10 @@ CYG_SCIF_PUBLIC void NC(init_serial)( vo // just move on and hope for the best (this is unlikely to cause // problems since the CPU has just come out of reset anyway). + // Clear status register (read back first). + HAL_READ_UINT16(_SCSSR, sr); + HAL_WRITE_UINT16(_SCSSR, 0); + // Bring FIFO out of reset and set to trigger on every char in // FIFO (or C-c input would not be processed). HAL_WRITE_UINT8(_SCFCR, CYGARC_REG_SCFCR2_RTRG_1|CYGARC_REG_SCFCR2_TTRG_1); @@ -169,7 +175,7 @@ CYG_SCIF_PUBLIC void NC(init_serial)( vo CYG_SCIF_PUBLIC int NC(get_char)( void ) { cyg_uint8 c; - cyg_uint16 fdr; + cyg_uint16 fdr, sr; do { HAL_READ_UINT16(_SCFDR, fdr); @@ -177,8 +183,9 @@ CYG_SCIF_PUBLIC int NC(get_char)( void ) HAL_READ_UINT8(_SCFRDR, c); - // Clear FIFO full flag. - HAL_WRITE_UINT8(_SCSSR, + // Clear FIFO full flag (read before clearing) + HAL_READ_UINT16(_SCSSR, sr); + HAL_WRITE_UINT16(_SCSSR, CYGARC_REG_SCSSR2_CLEARMASK & ~CYGARC_REG_SCSSR2_RDF); return c; @@ -186,22 +193,23 @@ CYG_SCIF_PUBLIC int NC(get_char)( void ) CYG_SCIF_PUBLIC void NC(put_char)( int c ) { - cyg_uint16 fdr; + cyg_uint16 fdr, sr; do { HAL_READ_UINT16(_SCFDR, fdr); - } while ((fdr & CYGARC_REG_SCFDR2_TCOUNT_MASK >> CYGARC_REG_SCFDR2_TCOUNT_shift) < 16); + } while (((fdr & CYGARC_REG_SCFDR2_TCOUNT_MASK) >> CYGARC_REG_SCFDR2_TCOUNT_shift) == 16); HAL_WRITE_UINT8(_SCFTDR, c); - // Clear FIFO-empty/transmit end flags. - HAL_WRITE_UINT8(_SCSSR, CYGARC_REG_SCSSR2_CLEARMASK + // Clear FIFO-empty/transmit end flags (read back SR first) + HAL_READ_UINT16(_SCSSR, sr); + HAL_WRITE_UINT16(_SCSSR, CYGARC_REG_SCSSR2_CLEARMASK & ~(CYGARC_REG_SCSSR2_TDFE | CYGARC_REG_SCSSR2_TEND )); // Hang around until the character has been safely sent. do { HAL_READ_UINT16(_SCFDR, fdr); - } while ((fdr & CYGARC_REG_SCFDR2_TCOUNT_MASK) == 0); + } while ((fdr & CYGARC_REG_SCFDR2_TCOUNT_MASK) != 0); } @@ -253,15 +261,16 @@ void NC(init_break_irq)( void ) int cyg_hal_gdb_isr( target_register_t pc ) { cyg_uint8 c; - cyg_uint16 fdr; + cyg_uint16 fdr, sr; HAL_READ_UINT16(_SCFDR, fdr); if ((fdr & CYGARC_REG_SCFDR2_RCOUNT_MASK) != 0) { HAL_READ_UINT8(_SCFRDR, c); - // Clear buffer full flag. - HAL_WRITE_UINT8(_SCSSR, - CYGARC_REG_SCSSR2_CLEARMASK & ~CYGARC_REG_SCSSR2_RDF); + // Clear buffer full flag (read back first). + HAL_READ_UINT16(_SCSSR, sr); + HAL_WRITE_UINT16(_SCSSR, + CYGARC_REG_SCSSR2_CLEARMASK & ~CYGARC_REG_SCSSR2_RDF); if ( 3 == c ) { diff --git a/packages/hal/sh/arch/current/include/sh_sci.inl b/packages/hal/sh/arch/current/include/sh_sci.inl --- a/packages/hal/sh/arch/current/include/sh_sci.inl +++ b/packages/hal/sh/arch/current/include/sh_sci.inl @@ -113,9 +113,9 @@ CYG_SCI_PUBLIC void NC(init_serial)( voi cyg_uint8 tmp; HAL_READ_UINT8(CYGARC_REG_SCSMR, tmp); tmp &= ~CYGARC_REG_SCSMR_CKSx_MASK; - tmp |= CYGARC_REG_CKSx_38400; + tmp |= CYGARC_SCBRR_CKSx(38400); HAL_WRITE_UINT8(CYGARC_REG_SCSMR, tmp); - HAL_WRITE_UINT8(CYGARC_REG_SCBRR, CYGARC_REG_SCBRR_38400); + HAL_WRITE_UINT8(CYGARC_REG_SCBRR, CYGARC_SCBRR_N(38400)); } #endif } diff --git a/packages/hal/sh/arch/current/src/sh.ld b/packages/hal/sh/arch/current/src/sh.ld --- a/packages/hal/sh/arch/current/src/sh.ld +++ b/packages/hal/sh/arch/current/src/sh.ld @@ -47,7 +47,7 @@ INPUT(extras.o) #endif GROUP(libtarget.a libgcc.a) -#define ALIGN_LMA 4 +#define ALIGN_LMA 16 #define FOLLOWING(_section_) AT ((LOADADDR (_section_) + SIZEOF (_section_) + ALIGN_LMA - 1) & ~ (ALIGN_LMA - 1)) #define LMA_EQ_VMA #define FORCE_OUTPUT . = . @@ -58,7 +58,8 @@ GROUP(libtarget.a libgcc.a) #define SECTION_vectors(_region_, _vma_, _lma_) \ .vectors _vma_ : _lma_ \ { FORCE_OUTPUT; KEEP(*(.vectors)) } \ - > _region_ + > _region_ \ + __vector_code_lma = LOADADDR(.vectors); #define SECTION_text(_region_, _vma_, _lma_) \ .text _vma_ : _lma_ \ diff --git a/packages/hal/sh/arch/current/src/vectors.S b/packages/hal/sh/arch/current/src/vectors.S --- a/packages/hal/sh/arch/current/src/vectors.S +++ b/packages/hal/sh/arch/current/src/vectors.S @@ -83,45 +83,25 @@ #=========================================================================== # Start by defining the exceptions vectors. .section ".vectors","ax" -rom_vectors: - # reset 0xa0000000 # other exceptions VBR+0x100 # tlb miss VBR+0x400 # interrupts VBR+0x600 + +#=========================================================================== +# Reset code must be PC relative so it can be executed out of the shadow +# area during startup. Not until after hal_hardware_init can the system +# be expected to provide the proper address space (at that time we +# jump to the VMA base of the code). + .globl __reset; __reset: - # Put CPU in a well-known state, disable interrupts. - mov.l $nCYG_SR,r1 + + # Initialize CPU + mov.l $nCYG_SR,r1 ! Put CPU in a well-known state ldc r1,sr - - # Initialize VBR if necessary -#if defined(CYG_HAL_STARTUP_ROM) || \ - ( defined(CYG_HAL_STARTUP_RAM) && \ - !defined(CYGSEM_HAL_USE_ROM_MONITOR)) - mov.l $__reset,r1 ! Set VBR - ldc r1,vbr -#endif - -#ifdef CYG_HAL_STARTUP_ROM - # This code will be executed from address 0 if started from ROM. - # We do not need it when starting from RAM. - mov.l $_start,r0 - jmp @r0 - nop - .align 2 -$_start: - .long _start -#endif - -#=========================================================================== -# Real startup code. - - .globl _start -_start: - # Initialize CPU mov #0,r0 mov #CYGARC_REG_CCR,r1 ! Disable cache mov.l r0,@r1 @@ -139,6 +119,15 @@ rom_vectors: mov.w r0,@r1 mov.l $CYGARC_REG_IPRB,r1 mov.w r0,@r1 + + # Initialize VBR if necessary +#if !defined(CYG_HAL_STARTUP_RAM) || \ + ( defined(CYG_HAL_STARTUP_RAM) && \ + !defined(CYGSEM_HAL_USE_ROM_MONITOR)) + mov.l $__reset,r1 ! Set VBR + ldc r1,vbr +#endif + #ifdef __DEBUG mov #0,r0 @@ -161,17 +150,11 @@ rom_vectors: # Call platform specific hardware initialization # This may include memory controller initialization. It is not # safe to access RAM until after this point. - mov.l $_hal_hardware_init,r0 - jsr @r0 - nop + hal_hardware_init - # Set up monitor related stuff (vectors primarily) - hal_mon_init + # Now copy necessary bits to RAM and jump to the VMA base - # set up stack - mov.l $__startup_stack,r15 - -#if defined(CYG_HAL_STARTUP_ROM) +#ifdef CYG_HAL_STARTUP_ROM # Copy data from ROM to ram mov.l $__rom_data_start,r3 ! r3 = rom start @@ -186,8 +169,110 @@ 1: mov.l @r3+,r0 cmp/eq r4,r5 ! compare bf 1b ! loop if not yet done 2: + + # Jump to the proper VMA base of the code. + mov.l $_complete_setup,r0 + jmp @r0 + nop + .align 2 + + .extern __rom_data_start + .extern __ram_data_start + .extern __ram_data_end + +$__rom_data_start: + .long __rom_data_start +$__ram_data_start: + .long __ram_data_start +$__ram_data_end: + .long __ram_data_end +$_complete_setup: + .long _complete_setup + +#elif defined(CYG_HAL_STARTUP_ROMRAM) + + # Copy everything to the proper VMA base and jump to it. + mov.l $_vectors_lma,r0 + mov.l $_vectors_vma,r1 + mov.l $_end,r2 +1: mov.l @r0+,r3 ! get word from ROM + mov.l r3,@r1 ! store in RAM + add #4,r1 + cmp/eq r1,r2 ! compare + bf 1b ! loop if not yet done + mov.l $_complete_setup,r0 + jmp @r0 + nop + .align 2 + + .extern __vector_code_lma + +$_vectors_lma: + .long __vector_code_lma +$_vectors_vma: + .long __reset +$_end: + .long _end +$_complete_setup: + .long _complete_setup + +#else + + # Jump to remaining setup code. Relative branch is OK since VMA=LMA. + bra _complete_setup + #endif + .align 2 + +$nCYG_SR: + .long CYG_SR +$CYGARC_REG_TSTR: + .long CYGARC_REG_TSTR +$CYGARC_REG_IPRA: + .long CYGARC_REG_IPRA +$CYGARC_REG_IPRB: + .long CYGARC_REG_IPRB +$__reset: + .long __reset + +#--------------------------------------------------------------------------- +# Exception entry + + .org 0x100 +__exception: + +#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) + mov #1,r7 +#endif + + mov #CYGARC_REG_EXCEVT,r1 + mov.l @r1,r1 + shlr2 r1 + shlr r1 ! divide cause by 0x08 + mov.l $_hal_vsr_table,r0 + mov.l @(r0,r1),r1 + jmp @r1 + nop + + .align 2 +$_hal_vsr_table: + .long _hal_vsr_table + +#----------------------------------------------------------------------------- +# Complete target initialization and setup. +# [Placed here to make use of gap between exception and interrupt entry points] +# After this point we can use absolute addressing modes and access all the +# memory in the system. + +_complete_setup: + + # Set up monitor related stuff (vectors primarily) + hal_mon_init + + # set up stack + mov.l $__startup_stack,r15 + # clear BSS mov.l $__bss_start,r3 ! r3 = start mov.l $__bss_end,r4 ! r4 = end @@ -224,7 +309,6 @@ 2: nop #endif - mov.l $_cyg_start,r1 jsr @r1 nop @@ -233,30 +317,14 @@ 9: nop .align 2 -$nCYG_SR: - .long CYG_SR $__startup_stack: .long __startup_stack -$__reset: - .long __reset -$CYGARC_REG_TSTR: - .long CYGARC_REG_TSTR -$CYGARC_REG_IPRA: - .long CYGARC_REG_IPRA -$CYGARC_REG_IPRB: - .long CYGARC_REG_IPRB - .extern _hal_hardware_init .extern __bss_start .extern __bss_end .extern _cyg_hal_invoke_constructors .extern _cyg_start - .extern __rom_data_start - .extern __ram_data_start - .extern __ram_data_end -$_hal_hardware_init: - .long _hal_hardware_init $__bss_start: .long __bss_start $__bss_end: @@ -267,14 +335,6 @@ 9: .long _cyg_hal_enable_caches $_cyg_start: .long _cyg_start -$__rom_data_start: - .long __rom_data_start -$__ram_data_start: - .long __ram_data_start -$__ram_data_end: - .long __ram_data_end - - #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS .extern _initialize_stub @@ -282,44 +342,6 @@ 9: .long _initialize_stub #endif - - .org 0x100 -__exception: - -#if defined(CYGPKG_KERNEL_INSTRUMENT) && defined(CYGDBG_KERNEL_INSTRUMENT_INTR) - mov #1,r7 -#endif - -#ifdef __DEBUG - mov #CYGARC_REG_EXCEVT,r1 - mov.l @r1,r1 - mov.l $trapval,r0 - cmp/eq r0,r1 - bt 1f - mov.l $safe_excevt,r0 - mov.l r1,@r0 -1: -#endif - - mov #CYGARC_REG_EXCEVT,r1 - mov.l @r1,r1 - shlr2 r1 - shlr r1 ! divide cause by 0x08 - mov.l $_hal_vsr_table,r0 - mov.l @(r0,r1),r1 - jmp @r1 - nop - - .align 2 -$_hal_vsr_table: - .long _hal_vsr_table - -#ifdef __DEBUG -$safe_excevt: - .long 0x080d0200 -$trapval: - .long 0x00000160 -#endif #--------------------------------------------------------------------------- # This code handles the common part of all exception handlers. @@ -432,7 +454,8 @@ 1: $_cyg_hal_exception_handler: .long _cyg_hal_exception_handler - ! When the call returns it will go to restore_state. +#--------------------------------------------------------------------------- +# TLB miss entry .org 0x400 __tlb_miss: @@ -440,13 +463,6 @@ 1: mov #2,r7 #endif -#ifdef __DEBUG - mov #CYGARC_REG_EXCEVT,r1 - mov.l @r1,r1 - mov.l $safe_excevt2,r0 - mov.l r1,@r0 -#endif - mov #CYGARC_REG_EXCEVT,r1 mov.l @r1,r1 shlr2 r1 @@ -460,10 +476,8 @@ 1: $_hal_vsr_table2: .long _hal_vsr_table -#ifdef __DEBUG -$safe_excevt2: - .long 0x080d0200 -#endif +#--------------------------------------------------------------------------- +# Interrupt entry .org 0x600 __interrupt: @@ -484,13 +498,6 @@ 1: mov #3,r7 #endif -#ifdef __DEBUG - mov #CYGARC_REG_INTEVT,r1 - mov.l @r1,r1 - mov.l $safe_intevt,r0 - mov.l r1,@r0 -#endif - mov.l $_hal_vsr_table_int,r1 mov.l @r1,r1 jmp @r1 @@ -500,13 +507,6 @@ 1: $_hal_vsr_table_int: .long _hal_vsr_table+CYGNUM_HAL_VECTOR_INTERRUPT*4 -#ifdef __DEBUG -$safe_intevt: - .long 0x080d0204 -#endif - -rom_vectors_end: - #--------------------------------------------------------------------------- # Common interrupt handling code. @@ -524,14 +524,6 @@ rom_vectors_end: # Save away some registers mov r15,r1 ! entry sp -#ifdef __DEBUG - mov.l $int_state_marker,r0 - mov.l r0,@-r15 - mov #CYGARC_REG_INTEVT,r0 - mov.l @r0,r0 - mov.l r0,@-r15 -#endif - #ifdef CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT add #-12,r15 ! Space for cause, gbr, and vbr #else @@ -630,7 +622,11 @@ 1: #endif # Decode the interrupt vector +#ifdef CYGARC_SH_MOD_INTC_V2 + mov.l $nCYGARC_REG_INTEVT2,r0 +#else mov #CYGARC_REG_INTEVT,r0 +#endif mov.l @r0,r4 mov #-5,r0 ! divide cause by 0x20 shld r0,r4 @@ -651,9 +647,6 @@ 1: #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - mov #CYGNUM_HAL_INTERRUPT_SCI_RXI,r1 - cmp/eq r1,r4 - bf 2f mov r4,r10 ! save across call. mov #CYGARC_SHREG_PC,r4 add r8,r4 @@ -758,28 +751,6 @@ skip_isr_proper: restore_state: # All done, restore CPU state and continue -#ifdef __DEBUG - mov.l $_safe_addr,r0 - mov.l @r0,r1 - add #1,r1 - mov.l r1,@r0 - add #4,r0 - - mov r15,r1 - mov #CYGARC_SH_EXCEPTION_SIZE/4,r2 -1: mov.l @r1+,r3 - mov.l r3,@r0 - add #4,r0 - dt r2 - bf 1b - - bra 2f - nop - .align 2 -$_safe_addr: - .long 0x080d0000-4 -2: -#endif # Disable interrupts and switch register bank during the restore # operation @@ -883,6 +854,8 @@ 2: .long CYG_SR $nCYG_SR_BANK1: .long CYG_SR_BANK1 +$nCYGARC_REG_INTEVT2: + .long CYGARC_REG_INTEVT2 $_hal_interrupt_handlers: .long _hal_interrupt_handlers $_hal_interrupt_data: diff --git a/packages/hal/sh/edk/current/ChangeLog b/packages/hal/sh/edk/current/ChangeLog --- a/packages/hal/sh/edk/current/ChangeLog +++ b/packages/hal/sh/edk/current/ChangeLog @@ -1,3 +1,19 @@ +2000-04-12 Jesper Skov + + * src/hal_diag.c: Output text raw if configuration requires it. + + * include/platform.inc: + * src/edk.S: [deleted] + * cdl/hal_sh_edk7708.cdl: + Hardware init code moved to platform.inc in order to allow ROMRAM + startup. + + * include/pkgconf/mlt_sh_edk7708_romram.h: + * include/pkgconf/mlt_sh_edk7708_romram.mlt: + * include/pkgconf/mlt_sh_edk7708_romram.ldi: + * cdl/hal_sh_edk7708.cdl: + Add ROMRAM startup option. + 2000-04-06 Jonathan Larmour * cdl/hal_sh_edk7708.cdl: Use -g now that toolchains work with that diff --git a/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl b/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl --- a/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl +++ b/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl @@ -49,7 +49,7 @@ cdl_package CYGPKG_HAL_SH_EDK7708 { The edk HAL package provides the support needed to run eCos on a Hitachi SH3 EDK7708 board." - compile hal_diag.c edk.S plf_stub.c plf_misc.c + compile hal_diag.c plf_stub.c plf_misc.c implements CYGINT_HAL_DEBUG_GDB_STUBS implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK @@ -64,7 +64,7 @@ cdl_package CYGPKG_HAL_SH_EDK7708 { cdl_component CYG_HAL_STARTUP { display "Startup type" flavor data - legal_values {"RAM" "ROM"} + legal_values {"RAM" "ROM" "ROMRAM"} default_value {"RAM"} no_define define -file system.h CYG_HAL_STARTUP @@ -76,7 +76,10 @@ cdl_package CYGPKG_HAL_SH_EDK7708 { equivalent software that allows GDB to download the eCos application on to the board. The ROM bootstrap typically requires that the eCos application be blown into EPROMs or - equivalent technology." + equivalent technology. ROMRAM bootstrap is similar to ROM + bootstrap, but everything is copied to RAM before execution + starts thus improving performace, but at the cost of an + increased RAM footprint." } cdl_option CYGHWR_HAL_SH_BOARD_SPEED { @@ -137,7 +140,7 @@ cdl_package CYGPKG_HAL_SH_EDK7708 { display "Global compiler flags" flavor data no_define - default_value { CYGHWR_HAL_SH_BIGENDIAN ? "-mb -m3 -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" : "-ml -m3 -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -ggdb -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" } + default_value { CYGHWR_HAL_SH_BIGENDIAN ? "-mb -m3 -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" : "-ml -m3 -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" } description " This option controls the global compiler flags which are used to compile all packages by @@ -186,7 +189,8 @@ cdl_package CYGPKG_HAL_SH_EDK7708 { flavor data no_define calculated { CYG_HAL_STARTUP == "RAM" ? "sh_edk7708_ram" : \ - "sh_edk7708_rom" } + CYG_HAL_STARTUP == "ROM" ? "sh_edk7708_rom" : \ + "sh_edk7708_romram" } cdl_option CYGHWR_MEMORY_LAYOUT_LDI { display "Memory layout linker script fragment" @@ -194,7 +198,8 @@ cdl_package CYGPKG_HAL_SH_EDK7708 { no_define define -file system.h CYGHWR_MEMORY_LAYOUT_LDI calculated { CYG_HAL_STARTUP == "RAM" ? "" : \ - "" } + CYG_HAL_STARTUP == "ROM" ? "" : \ + "" } } cdl_option CYGHWR_MEMORY_LAYOUT_H { @@ -203,7 +208,8 @@ cdl_package CYGPKG_HAL_SH_EDK7708 { no_define define -file system.h CYGHWR_MEMORY_LAYOUT_H calculated { CYG_HAL_STARTUP == "RAM" ? "" : \ - "" } + CYG_HAL_STARTUP == "ROM" ? "" : \ + "" } } } diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.h b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.h new file mode 100644 --- /dev/null +++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.h @@ -0,0 +1,13 @@ +// eCos memory layout - Wed Apr 12 15:28:35 2000 + +// This is a generated file - do not edit + +#include +#include + +#define CYGMEM_REGION_ram (0x8000100) +#define CYGMEM_REGION_ram_SIZE (0xfff00) +#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W) +#define CYGMEM_REGION_rom (0xa0000000) +#define CYGMEM_REGION_rom_SIZE (0x20000) +#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R) diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.ldi b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.ldi new file mode 100644 --- /dev/null +++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.ldi @@ -0,0 +1,24 @@ +// eCos memory layout - Wed Apr 12 15:28:35 2000 + +// This is a generated file - do not edit + +MEMORY +{ + ram : ORIGIN = 0x8000100, LENGTH = 0xfff00 + rom : ORIGIN = 0xa0000000, LENGTH = 0x20000 +} + +SECTIONS +{ + SECTIONS_BEGIN + SECTION_vectors (ram, 0x8000100, AT (0xa0000000)) + SECTION_text (ram, ALIGN (0x10), FOLLOWING (.vectors)) + SECTION_fini (ram, ALIGN (0x10), FOLLOWING (.text)) + SECTION_rodata1 (ram, ALIGN (0x10), FOLLOWING (.fini)) + SECTION_rodata (ram, ALIGN (0x10), FOLLOWING (.rodata1)) + SECTION_fixup (ram, ALIGN (0x10), FOLLOWING (.rodata)) + SECTION_gcc_except_table (ram, ALIGN (0x10), FOLLOWING (.fixup)) + SECTION_data (ram, ALIGN (0x10), FOLLOWING (.gcc_except_table)) + SECTION_bss (ram, ALIGN (0x10), FOLLOWING (.data)) + SECTIONS_END +} diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.mlt b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.mlt new file mode 100644 --- /dev/null +++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_romram.mlt @@ -0,0 +1,12 @@ +version 0 +region ram 8000100 fff00 0 ! +region rom a0000000 20000 1 ! +section vectors 0 10 1 1 1 1 1 1 8000100 a0000000 text text ! +section text 0 10 1 1 0 1 0 1 fini fini ! +section fini 0 10 1 1 0 1 0 1 rodata1 rodata1 ! +section rodata1 0 10 1 1 0 1 0 1 rodata rodata ! +section rodata 0 10 1 1 0 1 0 1 fixup fixup ! +section fixup 0 10 1 1 0 1 0 1 gcc_except_table gcc_except_table ! +section gcc_except_table 0 10 1 1 0 1 0 1 data data ! +section data 0 10 1 1 0 1 0 1 bss bss ! +section bss 0 10 1 1 0 0 0 0 ! diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_stubs.h b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_stubs.h deleted file mode 100644 --- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_stubs.h +++ /dev/null @@ -1,13 +0,0 @@ -// eCos memory layout - Wed Nov 24 11:56:27 1999 - -// This is a generated file - changes will be lost if ConfigTool(MLT) is run - -#include -#include - -#define CYGMEM_REGION_ram (0x80fc000) -#define CYGMEM_REGION_ram_SIZE (0x4000) -#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W) -#define CYGMEM_REGION_rom (0xa0000000) -#define CYGMEM_REGION_rom_SIZE (0x20000) -#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R) diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_stubs.ldi b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_stubs.ldi deleted file mode 100644 --- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_stubs.ldi +++ /dev/null @@ -1,50 +0,0 @@ -//=========================================================================== -// -// STUBS start linker control script -// -//=========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//=========================================================================== - -MEMORY -{ - rom : ORIGIN = 0xa0000000, LENGTH = 0x20000 - ram : ORIGIN = 0x080fc000, LENGTH = 0x4000 -} - -SECTIONS -{ - SECTIONS_BEGIN - SECTION_vectors (rom, 0xa0000000, LMA_EQ_VMA) - SECTION_text (rom, ALIGN (0x4), LMA_EQ_VMA) - SECTION_fini (rom, ALIGN (0x4), LMA_EQ_VMA) - SECTION_rodata1 (rom, ALIGN (0x8), LMA_EQ_VMA) - SECTION_rodata (rom, ALIGN (0x8), LMA_EQ_VMA) - SECTION_fixup (rom, ALIGN (0x4), LMA_EQ_VMA) - SECTION_gcc_except_table (rom, ALIGN (0x1), LMA_EQ_VMA) - SECTION_data (ram, 0x080fc000, FOLLOWING (.gcc_except_table)) - SECTION_bss (ram, ALIGN (0x10), LMA_EQ_VMA) - SECTIONS_END -} diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_stubs.mlt b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_stubs.mlt deleted file mode 100644 --- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_stubs.mlt +++ /dev/null @@ -1,12 +0,0 @@ -version 0 -region ram 80fc000 4000 0 ! -region rom a0000000 20000 1 ! -section data 0 1 1 1 1 1 0 0 80fc000 bss ! -section bss 0 10 0 1 0 0 0 0 ! -section vectors 0 1 0 1 1 1 1 1 a0000000 a0000000 text text ! -section text 0 4 0 1 0 1 0 1 fini fini ! -section fini 0 4 0 1 0 1 0 1 rodata1 rodata1 ! -section rodata1 0 8 0 1 0 1 0 1 rodata rodata ! -section rodata 0 8 0 1 0 1 0 1 fixup fixup ! -section fixup 0 4 0 1 0 1 0 1 gcc_except_table gcc_except_table ! -section gcc_except_table 0 1 0 1 0 0 0 1 data ! diff --git a/packages/hal/sh/edk/current/include/platform.inc b/packages/hal/sh/edk/current/include/platform.inc --- a/packages/hal/sh/edk/current/include/platform.inc +++ b/packages/hal/sh/edk/current/include/platform.inc @@ -50,18 +50,79 @@ #include +#include #include #------------------------------------------------------------------------------ +# Hardware initialization. + + .macro hal_hardware_init + // Set up the Bus State Controller + mova BSC_settings_table,r0 + mov r0,r3 +1: mov.w @r3+,r0 // Address (or zero) + cmp/eq #0,r0 + bt 2f + mov.w @r3+,r1 // data + bra 1b + mov.w r1,@r0 // delay slot + + .align 2 +BSC_settings_table: + # These are the settings set by the Hitachi ROM Monitor. + + # BCR2: Bus size of areas 1-6 to 32 bits + .word CYGARC_REG_BCR2 + .word 0x3ffc + # BCR1: Areas 2 and 3 are SDRAM + .word CYGARC_REG_BCR1 + .word 0x080c + # BCR2: Bus size of areas 1-6 to 32 bits [note: second write!] + .word CYGARC_REG_BCR2 + .word 0x3ffc + # WCR1: 3 wait-state cycles inserted for all areas + .word CYGARC_REG_WCR1 + .word 0x3fff + # WCR2: extra wait states and full pitch for burst + .word CYGARC_REG_WCR2 + .word 0xffd7 + # MCR: RAS/CAS & burst timing area 2/3 + .word CYGARC_REG_MCR + .word 0x963c + # RTCNT: refresh counter (needs a5 in top byte to accept write) + .word CYGARC_REG_RTCNT + .word (0xa500 | 0x0000) + # RTCOR: refresh time constant (needs a5 in top byte to accept write) + .word CYGARC_REG_RTCOR + .word (0xa500 | 0x003b) + # RFCR: refresh count register (needs a4 in top byte to accept write) + .word CYGARC_REG_RFCR + .word (0xa400 | 0x0000) + # RTCSR: refresh timer control (needs a5 in top byte to accept write) + .word CYGARC_REG_RTCSR + .word (0xa500 | 0x0008) + + # Set SDMR to 0x220 + .word 0xd880 + .word 0 + + # Table end + .word 0 + + .align 2 +2: + .endm + +#------------------------------------------------------------------------------ # Monitor initialization. #ifndef CYGPKG_HAL_SH_MON_DEFINED -#if defined(CYG_HAL_STARTUP_ROM) || \ +#if !defined(CYG_HAL_STARTUP_RAM) || \ ( defined(CYG_HAL_STARTUP_RAM) && \ !defined(CYGSEM_HAL_USE_ROM_MONITOR)) - # If we are starting up from ROM, or we are starting in + # If we are not starting up from RAM, or we are starting in # RAM and NOT using a ROM monitor, initialize the VSR table. .macro hal_mon_init diff --git a/packages/hal/sh/edk/current/src/hal_diag.c b/packages/hal/sh/edk/current/src/hal_diag.c --- a/packages/hal/sh/edk/current/src/hal_diag.c +++ b/packages/hal/sh/edk/current/src/hal_diag.c @@ -55,6 +55,20 @@ #include +//----------------------------------------------------------------------------- + +#if defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) + +#define CYG_HAL_DIAG_GDB + +#elif defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) + +#define CYG_HAL_DIAG_GDB + +#endif + +//----------------------------------------------------------------------------- + void hal_diag_init(void) { hal_sci_init_serial(); @@ -79,7 +93,7 @@ externC void cyg_hal_user_break(CYG_ADDR void hal_diag_write_char(char c) { - +#ifdef CYG_HAL_DIAG_GDB static char line[100]; static int pos = 0; @@ -149,8 +163,10 @@ hal_diag_write_char(char c) #else HAL_RESTORE_INTERRUPTS(old); #endif - } +#else // CYG_HAL_DIAG_GDB + hal_diag_write_char_serial(c); +#endif } //----------------------------------------------------------------------------- diff --git a/packages/hal/sparclite/arch/current/cdl/hal_sparclite.cdl b/packages/hal/sparclite/arch/current/cdl/hal_sparclite.cdl --- a/packages/hal/sparclite/arch/current/cdl/hal_sparclite.cdl +++ b/packages/hal/sparclite/arch/current/cdl/hal_sparclite.cdl @@ -93,7 +93,7 @@ cdl_package CYGPKG_HAL_SPARCLITE { } cdl_option CYGPKG_HAL_SPARCLITE_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/hal/sparclite/sim/current/cdl/hal_sparclite_sim.cdl b/packages/hal/sparclite/sim/current/cdl/hal_sparclite_sim.cdl --- a/packages/hal/sparclite/sim/current/cdl/hal_sparclite_sim.cdl +++ b/packages/hal/sparclite/sim/current/cdl/hal_sparclite_sim.cdl @@ -160,7 +160,7 @@ cdl_package CYGPKG_HAL_SPARCLITE_SIM { } cdl_option CYGPKG_HAL_SPARCLITE_SIM_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/hal/sparclite/sleb/current/cdl/hal_sparclite_sleb.cdl b/packages/hal/sparclite/sleb/current/cdl/hal_sparclite_sleb.cdl --- a/packages/hal/sparclite/sleb/current/cdl/hal_sparclite_sleb.cdl +++ b/packages/hal/sparclite/sleb/current/cdl/hal_sparclite_sleb.cdl @@ -236,7 +236,7 @@ cdl_package CYGPKG_HAL_SPARCLITE_SLEB { } cdl_option CYGPKG_HAL_SPARCLITE_SLEB_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/infra/current/ChangeLog b/packages/infra/current/ChangeLog --- a/packages/infra/current/ChangeLog +++ b/packages/infra/current/ChangeLog @@ -1,3 +1,7 @@ +2000-04-12 Jesper Skov + + * cdl/infra.cdl: Allow build flags to be tweaked. + 2000-03-28 Jonathan Larmour * include/cyg_trac.h: Also update internal documentation for below diff --git a/packages/infra/current/cdl/infra.cdl b/packages/infra/current/cdl/infra.cdl --- a/packages/infra/current/cdl/infra.cdl +++ b/packages/infra/current/cdl/infra.cdl @@ -168,4 +168,35 @@ cdl_package CYGPKG_INFRA { puts $::cdl_header "#include " puts $::cdl_header "/***** proc output end *****/" } + + cdl_component CYGPKG_INFRA_OPTIONS { + display "Infra build options" + flavor none + description " + Package specific build options including control over + compiler flags used only in building this package." + + + cdl_option CYGPKG_INFRA_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building the eCos infra package. These flags are used + in addition to the set of global flags." + } + + cdl_option CYGPKG_INFRA_CFLAGS_REMOVE { + display "Suppressed compiler flags" + flavor data + no_define + default_value { "" } + description " + This option modifies the set of compiler flags for + building the eCos infra package. These flags are removed from + the set of global flags if present." + } + } } diff --git a/packages/io/serial/current/ChangeLog b/packages/io/serial/current/ChangeLog --- a/packages/io/serial/current/ChangeLog +++ b/packages/io/serial/current/ChangeLog @@ -1,3 +1,68 @@ +2000-04-13 Gary Thomas + + * src/common/serial.c (serial_write): Make safer - only call + 'start_xmit' with DSRs disabled. + +2000-04-11 Hugo Tyson + + * cdl/io_serial.cdl (CYGPKG_IO_SERIAL_DEVICES): New package which + is a container and control for the real device drivers. + +2000-04-11 Jesper Skov + + * cdl/io_serial.cdl: Bad hack to build separate test. + * tests/serial_echo.c: Added. + +2000-04-11 Hugo Tyson + + * cdl/ser_.... (driver-specific cdl files): + Remove all these; they are no longer needed following the change + below. They do exist in devs/serial/ARCH/PLATFORM/VERSION/cdl/ + directories various instead. + +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + 2000-04-07 Jonathan Larmour * src/common/tty.c (tty_read): Correct handling of modes with newlines diff --git a/packages/io/serial/current/cdl/io_serial.cdl b/packages/io/serial/current/cdl/io_serial.cdl --- a/packages/io/serial/current/cdl/io_serial.cdl +++ b/packages/io/serial/current/cdl/io_serial.cdl @@ -51,7 +51,15 @@ cdl_package CYGPKG_IO_SERIAL { compile -library=libextras.a common/serial.c common/tty.c \ common/haldiag.c - + + define_proc { + puts $::cdl_header "/***** proc output start *****/" + puts $::cdl_header "#include " + puts $::cdl_header "#ifdef CYGDAT_IO_SERIAL_DEVICE_HEADER" + puts $::cdl_header "# include CYGDAT_IO_SERIAL_DEVICE_HEADER" + puts $::cdl_header "#endif " + puts $::cdl_header "/****** proc output end ******/" + } cdl_component CYGPKG_IO_SERIAL_TTY { display "TTY-mode serial device drivers" @@ -65,181 +73,36 @@ cdl_package CYGPKG_IO_SERIAL { script tty.cdl } - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_ARM_PID { - display "ARM PID serial device drivers" + cdl_component CYGPKG_IO_SERIAL_DEVICES { + display "Hardware serial device drivers" flavor bool - active_if CYGPKG_HAL_ARM_PID - default_value 0 - description " - This option enables the serial device drivers for the ARM PID." - - compile -library=libextras.a arm/pid_serial_with_ints.c - - script ser_arm_pid.cdl - } - - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_ARM_AEB { - display "ARM AEB-1 serial device drivers" - flavor bool - active_if CYGPKG_HAL_ARM_AEB - default_value 0 - description " - This option enables the serial device drivers for the ARM AEB-1." - - compile -library=libextras.a arm/aeb_serial.c - - script ser_arm_aeb.cdl - } - - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX { - display "ARM EDB7XXX serial device drivers" - flavor bool - active_if CYGPKG_HAL_ARM_EDB7XXX default_value 0 description " - This option enables the serial device drivers for the - Cirrus Logic EDB7XXX." - - compile -library=libextras.a arm/edb7xxx_serial.c - - script ser_arm_edb7xxx.cdl - } - - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_ARM_CMA230 { - display "Cogent ARM/CMA230 serial device drivers" - flavor bool - default_value 0 - active_if CYGPKG_HAL_ARM_CMA230 - description " - This option enables the serial device drivers for the Cogent - ARM/CMA230." - - compile -library=libextras.a arm/cma230_serial.c - - script ser_arm_cma230.cdl - } - - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT { - display "Cogent PowerPC serial device drivers" - flavor bool - active_if CYGPKG_HAL_POWERPC_COGENT - default_value 0 - description " - This option enables the serial device drivers for the - Cogent PowerPC." - - compile -library=libextras.a powerpc/cogent_serial_with_ints.c - - script ser_powerpc_cogent.cdl - } - - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC { - display "PowerPC QUICC/SMC serial device drivers" - flavor bool - active_if CYGPKG_HAL_QUICC - default_value 0 - description " - This option enables the serial device drivers for the PowerPC - QUICC/SMC." - - compile -library=libextras.a powerpc/quicc_smc_serial.c - - script ser_quicc_smc.cdl + This option enables the hardware device drivers + for the current platform." } - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB { - display "SPARClite SLEB serial device drivers" - flavor bool - active_if CYGPKG_HAL_SPARCLITE_SLEB - default_value 0 - description " - This option enables the serial device drivers for the - SPARClite SLEB." - - compile -library=libextras.a sparclite/sleb_sdtr.c - - script ser_sparclite_sleb.cdl - } - - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_TX39_JMR3904 { - display "TX39 JMR3904 serial device drivers" - flavor bool - active_if CYGPKG_HAL_MIPS_TX39_JMR3904 + cdl_option CYGBLD_IO_SERIAL_EXTRA_TESTS { + display "Build extra serial tests" default_value 0 - description " - This option enables the serial device drivers for the TX39 - JMR3904." - - compile -library=libextras.a mips/tx3904_serial.c - - script ser_mips_jmr3904.cdl - } - - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_MIPS_VRC4373 { - display "VRC4373 serial device drivers" - flavor bool - active_if CYGPKG_HAL_MIPS_VR4300_VRC4373 - default_value 0 - description " - This option enables the serial device drivers for the VRC4373." - - compile -library=libextras.a mips/vrc4373_serial.c - - script ser_mips_vrc4373.cdl - } + no_define + description " + This option enables the building of some extra tests which + can be used when testing / debugging serial drivers. These + are not built by default since they do not use the dedicated + testing infrastructure." - # ------------------------------------------------------------------------- - # Note: this is not currently tied to a specific board since the - # ports are "on chip" - cdl_component CYGPKG_IO_SERIAL_MN10300 { - display "MN10300 serial device drivers" - flavor bool - active_if CYGPKG_HAL_MN10300 - default_value 0 - description " - This option enables the serial device drivers for the MN10300." - - compile -library=libextras.a mn10300/mn10300_serial.c - - script ser_mn10300.cdl - } - - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_I386_PC { - display "PC serial device drivers" - flavor bool - active_if CYGPKG_HAL_I386_PC - default_value 0 - description " - This option enables the serial device drivers for the PC." - - compile -library=libextras.a i386/pc_serial.c - - script ser_i386_pc.cdl - } - - # ------------------------------------------------------------------------- - cdl_component CYGPKG_IO_SERIAL_SH_EDK7708 { - display "SH3 EDK7708 serial device drivers" - flavor bool - active_if CYGPKG_HAL_SH_EDK7708 - default_value 0 - description " - This option enables the serial device driver for the Hitachi - SH3 EDK7708 board." - - compile -library=libextras.a sh/sh_sci_serial.c - - script ser_sh_edk7708.cdl + make -priority 320 { + /bin/serial_echo : /tests/serial_echo.c + @sh -c "mkdir -p tests $(dir $@)" + $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/serial_echo.o $< + @echo $@ ": \\" > $(notdir $@).deps + @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps + @tail +2 deps.tmp >> $(notdir $@).deps + @echo >> $(notdir $@).deps + @rm deps.tmp + $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/serial_echo.o + } } cdl_component CYGPKG_IO_SERIAL_OPTIONS { @@ -263,7 +126,7 @@ cdl_package CYGPKG_IO_SERIAL { } cdl_option CYGPKG_IO_SERIAL_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/io/serial/current/cdl/ser_arm_aeb.cdl b/packages/io/serial/current/cdl/ser_arm_aeb.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_arm_aeb.cdl +++ /dev/null @@ -1,121 +0,0 @@ -# ==================================================================== -# -# ser_arm_aeb.cdl -# -# eCos serial ARM/AEB configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-08 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_component CYGPKG_IO_SERIAL_ARM_AEB_SERIAL0 { - display "ARM AEB-1 serial port 0 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the ARM AEB-1 - port 0." - - cdl_option CYGDAT_IO_SERIAL_ARM_AEB_SERIAL0_NAME { - display "Device name for the ARM AEB-1 serial port 0 driver" - flavor data - default_value {"\"/dev/ser0\""} - description " - This option sets the name of the serial device for the ARM - AEB-1 port 0." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BAUD { - display "Baud rate for the ARM AEB-1 serial port 0 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - ARM AEB-1 port 0." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE { - display "Buffer size for the ARM AEB-1 serial port 0 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used for - the ARM AEB-1 port 0." - } -} - -cdl_component CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1 { - display "ARM AEB-1 serial port 1 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the ARM - AEB-1 port 1." - - cdl_option CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME { - display "Device name for the ARM AEB-1 serial port 1 driver" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the name of serial device for the - ARM AEB-1 port 1." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BAUD { - display "Baud rate for the ARM AEB-1 serial port 1 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - ARM AEB-1 port 1." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE { - display "Buffer size for the ARM AEB-1 serial port 1 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the ARM AEB-1 port 1." - } -} diff --git a/packages/io/serial/current/cdl/ser_arm_cma230.cdl b/packages/io/serial/current/cdl/ser_arm_cma230.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_arm_cma230.cdl +++ /dev/null @@ -1,121 +0,0 @@ -# ==================================================================== -# -# ser_arm_cma230.cdl -# -# eCos serial ARM/CMA230 configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-08 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_component CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A { - display "Cogent ARM/CMA230 serial port A driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the Cogent - ARM/CMA230 port A." - - cdl_option CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_A_NAME { - display "Device name for Cogent ARM/CMA230 serial port A" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the device name for the Cogent - ARM/CMA230 port A." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BAUD { - display "Baud rate for the Cogent ARM/CMA230 serial port A driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - Cogent ARM/CMA230 port A." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE { - display "Buffer size for the Cogent ARM/CMA230 serial port A driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the Cogent ARM/CMA230 port A." - } -} - -cdl_component CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_B { - display "Cogent ARM/CMA230 serial port B driver" - flavor data - default_value 0 - description " - This option includes the serial device driver for the Cogent - ARM/CMA230 port B." - - cdl_option CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_B_NAME { - display "Device name for Cogent ARM/CMA230 serial port B" - flavor data - default_value {"\"/dev/ser2\""} - description " - This option specifies the device name for the Cogent - ARM/CMA230 port B." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BAUD { - display "Baud rate for the Cogent ARM/CMA230 serial port B driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - Cogent ARM/CMA230 port B." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE { - display "Buffer size for the Cogent ARM/CMA230 serial port B driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the Cogent ARM/CMA230 port B." - } -} diff --git a/packages/io/serial/current/cdl/ser_arm_edb7xxx.cdl b/packages/io/serial/current/cdl/ser_arm_edb7xxx.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_arm_edb7xxx.cdl +++ /dev/null @@ -1,122 +0,0 @@ -# ==================================================================== -# -# ser_arm_edb7xxx.cdl -# -# eCos serial ARM/EDB7XXX configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-08 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL1 { - display "Cirrus Logic EDB7XXX serial port 1 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the Cirrus Logic EDB7XXX - port 1." - - - cdl_option CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL1_NAME { - display "Device name for the Cirrus Logic EDB7XXX serial port 1 driver" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the name of serial device for the ARM - EDB7XXX port 1." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BAUD { - display "Baud rate for the Cirrus Logic EDB7XXX serial port 1 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the ARM - EDB7XXX port 1." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE { - display "Buffer size for the Cirrus Logic EDB7XXX serial port 1 driver" - flavor data - default_value 128 - legal_values 0 to 8192 - description " - This option specifies the size of the internal buffers used - for the Cirrus Logic EDB7XXX port 1." - } -} - -cdl_component CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2 { - display "Cirrus Logic EDB7XXX serial port 1 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the ARM - EDB7XXX port 2." - - cdl_option CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL2_NAME { - display "Device name for the Cirrus Logic EDB7XXX serial port 1 driver" - flavor data - default_value {"\"/dev/ser2\""} - description " - This option specifies the name of serial device for the ARM - EDB7XXX port 2." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BAUD { - display "Baud rate for the Cirrus Logic EDB7XXX serial port 1 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - Cirrus Logic EDB7XXX port 2." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE { - display "Buffer size for the Cirrus Logic EDB7XXX serial port 1 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used for - the Cirrus Logic EDB7XXX port 2." - } -} diff --git a/packages/io/serial/current/cdl/ser_arm_pid.cdl b/packages/io/serial/current/cdl/ser_arm_pid.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_arm_pid.cdl +++ /dev/null @@ -1,121 +0,0 @@ -# ==================================================================== -# -# ser_arm_pid.cdl -# -# eCos serial ARM/PID configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-07 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_component CYGPKG_IO_SERIAL_ARM_PID_SERIAL0 { - display "ARM PID serial port 0 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the ARM PID - port 0." - - cdl_option CYGDAT_IO_SERIAL_ARM_PID_SERIAL0_NAME { - display "Device name for ARM PID serial port 0 driver" - flavor data - default_value {"\"/dev/ser0\""} - description " - This option specifies the name of the serial device for the - ARM PID port 0." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BAUD { - display "Baud rate for the ARM PID serial port 0 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - ARM PID port 0." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE { - display "Buffer size for the ARM PID serial port 0 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the ARM PID port 0." - } -} - -cdl_component CYGPKG_IO_SERIAL_ARM_PID_SERIAL1 { - display "ARM PID serial port 1 driver" - flavor bool - default_value 1 - description " - This option includes the serial device driver for the ARM PID - port 1." - - cdl_option CYGDAT_IO_SERIAL_ARM_PID_SERIAL1_NAME { - display "Device name for ARM PID serial port 1 driver" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the name of the serial device for the - ARM PID port 1." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BAUD { - display "Baud rate for the ARM PID serial port 1 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - ARM PID port 1." - } - - cdl_option CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE { - display "Buffer size for the ARM PID serial port 1 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the ARM PID port 1." - } -} diff --git a/packages/io/serial/current/cdl/ser_i386_pc.cdl b/packages/io/serial/current/cdl/ser_i386_pc.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_i386_pc.cdl +++ /dev/null @@ -1,173 +0,0 @@ -# ==================================================================== -# -# ser_i386_pc.cdl -# -# eCos serial PC configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): nickg -# Original data: gthomas, jskov, pjo -# Contributors: -# Date: 2000-02-14 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_component CYGPKG_IO_SERIAL_I386_PC_SERIAL0 { - display "PC serial port 0 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for port 0 on the - PC." - - cdl_option CYGDAT_IO_SERIAL_I386_PC_SERIAL0_NAME { - display "Device name for PC serial port 0" - flavor data - default_value {"\"/dev/ser0\""} - description " - This option specifies the device name port 0 on the PC." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BAUD { - display "Baud rate for the PC serial port 0 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - PC port 0." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE { - display "Buffer size for the PC serial port 0 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the PC port 0." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IOBASE { - display "I/O base address for the i386-PC serial port 0" - flavor data - legal_values 0 to 0xFF8 - default_value 0x3F8 - description " - This option specifies the I/O address of the 8250 or 16550 for serial port 0." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IRQ { - display "IRQ for the i386-PC serial port 0" - flavor data - legal_values 0 to 15 - default_value 4 - description " - This option specifies the IRQ of the 8250 or 16550 for serial port 0." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL0_INT { - display "IRQ for the i386-PC serial port 0" - flavor data - legal_values 32 to 47 - default_value { CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IRQ + 32 } - description " - This option specifies the interrupt vector of the 8250 or 16550 for serial port 0." - } -} - -cdl_component CYGPKG_IO_SERIAL_I386_PC_SERIAL1 { - display "PC serial port 1 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for port 1 on - the PC." - - cdl_option CYGDAT_IO_SERIAL_I386_PC_SERIAL1_NAME { - display "Device name for PC serial port 1" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the device name port 1 on the PC." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BAUD { - display "Baud rate for the PC serial port 1 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - PC port 1." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE { - display "Buffer size for the PC serial port 1 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the PC port 1." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IOBASE { - display "I/O base address for the i386-PC serial port 1" - flavor data - legal_values 0 to 0xFF8 - default_value 0x2F8 - description " - This option specifies the I/O address of the 8250 or 16550 for serial port 1." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IRQ { - display "IRQ for the i386-PC serial port 1" - flavor data - legal_values 0 to 15 - default_value 3 - description " - This option specifies the IRQ of the 8250 or 16550 for serial port 1." - } - - cdl_option CYGNUM_IO_SERIAL_I386_PC_SERIAL1_INT { - display "IRQ for the i386-PC serial port 1" - flavor data - legal_values 32 to 47 - default_value { CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IRQ + 32 } - description " - This option specifies the interrupt vector of the 8250 or 16550 for serial port 1." - } -} diff --git a/packages/io/serial/current/cdl/ser_mips_jmr3904.cdl b/packages/io/serial/current/cdl/ser_mips_jmr3904.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_mips_jmr3904.cdl +++ /dev/null @@ -1,129 +0,0 @@ -# ==================================================================== -# -# ser_mips_jmr3904.cdl -# -# eCos serial MIPS/JMR3904 configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-14 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -# FIXME: Bad name -cdl_option CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE { - display "TX39 JMR3904 polled mode serial drivers" - flavor bool - default_value 0 - description " - If asserted, this option specifies that the serial device - drivers for the TX39 JMR3904 should be polled-mode instead of - interrupt driven." -} - -cdl_component CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 { - display "TX39 JMR3904 serial port 0 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for port 0 on the - TX39 JMR3904." - - cdl_option CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL0_NAME { - display "Device name for TX39 JMR3904 serial port 0" - flavor data - default_value {"\"/dev/ser0\""} - description " - This option specifies the device name port 0 on the TX39 JMR3904." - } - - cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BAUD { - display "Baud rate for the TX39 JMR3904 serial port 0 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - TX39 JMR3904 port 0." - } - - cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE { - display "Buffer size for the TX39 JMR3904 serial port 0 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the TX39 JMR3904 port 0." - } -} -cdl_component CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 { - display "TX39 JMR3904 serial port 1 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for port 1 on - the TX39 JMR3904." - - cdl_option CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL1_NAME { - display "Device name for TX39 JMR3904 serial port 1" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the device name port 1 on the TX39 JMR3904." - } - - cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BAUD { - display "Baud rate for the TX39 JMR3904 serial port 1 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - TX39 JMR3904 port 1." - } - - cdl_option CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE { - display "Buffer size for the TX39 JMR3904 serial port 1 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the TX39 JMR3904 port 1." - } -} diff --git a/packages/io/serial/current/cdl/ser_mips_vrc4373.cdl b/packages/io/serial/current/cdl/ser_mips_vrc4373.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_mips_vrc4373.cdl +++ /dev/null @@ -1,117 +0,0 @@ -# ==================================================================== -# -# ser_mips_vrc4373.cdl -# -# eCos serial MIPS/VRC4373 configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-14 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== -cdl_component CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL0 { - display "VRC4373 serial port 0 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the VRC4373 port 0." - - cdl_option CYGDAT_IO_SERIAL_MIPS_VRC4373_SERIAL0_NAME { - display "Device name for the VRC4373 serial port 0 driver" - flavor data - default_value {"\"/dev/ser0\""} - description " - This option sets the name of the serial device for the VRC4373 - port 0." - } - - cdl_option CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BAUD { - display "Baud rate for the VRC4373 serial port 0 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 9600 - description " - This option specifies the default baud rate (speed) for the - VRC4373 port 0." - } - - cdl_option CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BUFSIZE { - display "Buffer size for the VRC4373 serial port 0 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the VRC4373 port 0." - } -} -cdl_component CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL1 { - display "VRC4373 serial port 1 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the VRC4373 port 1." - - cdl_option CYGDAT_IO_SERIAL_MIPS_VRC4373_SERIAL1_NAME { - display "Device name for the VRC4373 serial port 1 driver" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the name of serial device for the - VRC4373 port 1." - } - - cdl_option CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BAUD { - display "Baud rate for the VRC4373 serial port 1 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 9600 - description " - This option specifies the default baud rate (speed) for the - VRC4373 port 1." - } - - cdl_option CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BUFSIZE { - display "Buffer size for the VRC4373 serial port 1 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used for - the VRC4373 port 1." - } -} diff --git a/packages/io/serial/current/cdl/ser_mn10300.cdl b/packages/io/serial/current/cdl/ser_mn10300.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_mn10300.cdl +++ /dev/null @@ -1,168 +0,0 @@ -# ==================================================================== -# -# ser_mn10300.cdl -# -# eCos serial MN10300 configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-07 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -# FIXME: Bad name -cdl_option CYGPKG_IO_SERIAL_MN10300_POLLED_MODE { - display "MN10300 polled mode serial drivers" - flavor bool - default_value 0 - description " - If asserted, this option specifies that the serial device - drivers for the MN10300 should be polled-mode instead of - interrupt driven." -} - -cdl_component CYGPKG_IO_SERIAL_MN10300_SERIAL0 { - display "MN10300 serial port 0 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for port 0 on the - MN10300." - - cdl_option CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME { - display "Device name for MN10300 serial port 0" - flavor data - default_value {"\"/dev/ser0\""} - description " - This option specifies the device name port 0 on the MN10300." - } - - cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD { - display "Baud rate for the MN10300 serial port 0 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - MN10300 port 0." - } - - cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE { - display "Buffer size for the MN10300 serial port 0 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the MN10300 port 0." - } -} - -cdl_component CYGPKG_IO_SERIAL_MN10300_SERIAL1 { - display "MN10300 serial port 1 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for port 1 on - the MN10300." - - cdl_option CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME { - display "Device name for MN10300 serial port 1" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the device name port 1 on the MN10300." - } - - cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD { - display "Baud rate for the MN10300 serial port 1 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - MN10300 port 1." - } - - cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE { - display "Buffer size for the MN10300 serial port 1 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the MN10300 port 1." - } -} -cdl_component CYGPKG_IO_SERIAL_MN10300_SERIAL2 { - display "MN10300 serial port 2 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for port 2 on the - MN10300." - - cdl_option CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME { - display "Device name for MN10300 serial port 2" - flavor data - default_value {"\"/dev/ser2\""} - description " - This option specifies the device name port 2 on the MN10300." - } - - cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD { - display "Baud rate for the MN10300 serial port 2 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - MN10300 port 2." - } - - cdl_option CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE { - display "Buffer size for the MN10300 serial port 2 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the MN10300 port 2." - } -} diff --git a/packages/io/serial/current/cdl/ser_powerpc_cogent.cdl b/packages/io/serial/current/cdl/ser_powerpc_cogent.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_powerpc_cogent.cdl +++ /dev/null @@ -1,123 +0,0 @@ -# ==================================================================== -# -# ser_powerpc_cogent.cdl -# -# eCos serial PowerPC/Cogent configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-14 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_A { - display "Cogent PowerPC serial port A driver" - flavor bool - default_value 0 - requires (CYGIMP_KERNEL_INTERRUPTS_CHAIN || \ - !CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B) - description " - This option includes the serial device driver for the Cogent - PowerPC port A. If both drivers need to be enabled, interrupt - chaining must be enabled in the kernel configuration." - - cdl_option CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_A_NAME { - display "Device name for Cogent PowerPC serial port A" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the device name for the Cogent PowerPC - port A." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BAUD { - display "Baud rate for the Cogent PowerPC serial port A driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - Cogent PowerPC port A." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE { - display "Buffer size for the Cogent PowerPC serial port A driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used for - the Cogent PowerPC port A." - } -} -cdl_component CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B { - display "Cogent PowerPC serial port B driver" - flavor bool - default_value 1 - description " - This option includes the serial device driver for the Cogent - PowerPC port B." - - cdl_option CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME { - display "Device name for Cogent PowerPC serial port B" - flavor data - default_value {"\"/dev/ser2\""} - description " - This option specifies the device name for the Cogent PowerPC - port B." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BAUD { - display "Baud rate for the Cogent PowerPC serial port B driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - Cogent PowerPC port B." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE { - display "Buffer size for the Cogent PowerPC serial port B driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used - for the Cogent PowerPC port B." - } -} diff --git a/packages/io/serial/current/cdl/ser_quicc_smc.cdl b/packages/io/serial/current/cdl/ser_quicc_smc.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_quicc_smc.cdl +++ /dev/null @@ -1,221 +0,0 @@ -# ==================================================================== -# -# ser_quicc_smc.cdl -# -# eCos serial PowerPC/QUICC SMC configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-14 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 { - display "PowerPC QUICC/SMC serial port 1 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the PowerPC - QUICC/SMC port 1." - - cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME { - display "Device name for PowerPC QUICC/SMC serial port 1" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the device name for the PowerPC - QUICC/SMC port 1." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BAUD { - display "Baud rate for the PowerPC QUICC/SMC serial port 1" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - PowerPC QUICC/SMC port 1." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE { - display "Buffer size for the PowerPC QUICC/SMC serial port 1" - flavor data - legal_values 0 to 8192 - default_value 256 - description " - This option specifies the size of the internal buffers used - for the PowerPC QUICC/SMC port 1." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BRG { - display "Which baud rate generator to use for the PowerPC QUICC/SMC serial port 1" - flavor data - legal_values 1 to 4 - default_value 1 - description " - This option specifies which of the four baud rate generators - to use for the PowerPC QUICC/SMC port 1." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE { - display "Output buffer size for the PowerPC QUICC/SMC serial port 1" - flavor data - legal_values 16 to 128 - default_value 16 - description " - This option specifies the maximum number of characters per - transmit request to be used for the PowerPC QUICC/SMC port 1." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM { - display "Number of output buffers for the PowerPC QUICC/SMC serial port 1" - flavor data - legal_values 2 to 16 - default_value 4 - description " - This option specifies the number of output buffer packets - to be used for the PowerPC QUICC/SMC port 1." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE { - display "Input buffer size for the PowerPC QUICC/SMC serial port 1" - flavor data - legal_values 16 to 128 - default_value 16 - description " - This option specifies the maximum number of characters per receive - request to be used for the PowerPC QUICC/SMC port 1." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM { - display "Number of input buffers for the PowerPC QUICC/SMC serial port 1" - flavor data - legal_values 2 to 16 - default_value 4 - description " - This option specifies the number of input buffer packets - to be used for the PowerPC QUICC/SMC port 1." - } -} - -cdl_component CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 { - display "PowerPC QUICC/SMC serial port 2 driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the PowerPC - QUICC/SMC port 2." - - cdl_option CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_NAME { - display "Device name for PowerPC QUICC/SMC serial port 2" - flavor data - default_value {"\"/dev/ser2\""} - description " - This option specifies the device name for the PowerPC - QUICC/SMC port 2." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BAUD { - display "Baud rate for the PowerPC QUICC/SMC serial port 2" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - PowerPC QUICC/SMC port 2." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE { - display "Buffer size for the PowerPC QUICC/SMC serial port 2" - flavor data - legal_values 0 to 8192 - default_value 256 - description " - This option specifies the size of the internal buffers used - for the PowerPC QUICC/SMC port 2." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BRG { - display "Which baud rate generator to use for the PowerPC QUICC/SMC serial port 2" - flavor data - legal_values 1 to 4 - default_value 2 - description " - This option specifies which of the four baud rate generators - to use for the PowerPC QUICC/SMC port 2." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE { - display "Output buffer size for the PowerPC QUICC/SMC serial port 2" - flavor data - legal_values 16 to 128 - default_value 16 - description " - This option specifies the maximum number of characters per - transmit request to be used for the PowerPC QUICC/SMC port 2." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM { - display "Number of output buffers for the PowerPC QUICC/SMC serial port 2" - flavor data - legal_values 2 to 16 - default_value 4 - description " - This option specifies the number of output buffer packets - to be used for the PowerPC QUICC/SMC port 2." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE { - display "Input buffer size for the PowerPC QUICC/SMC serial port 2" - flavor data - legal_values 16 to 128 - default_value 16 - description " - This option specifies the maximum number of characters per receive - request to be used for the PowerPC QUICC/SMC port 2." - } - - cdl_option CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM { - display "Number of output buffers for the PowerPC QUICC/SMC serial port 2" - flavor data - legal_values 2 to 16 - default_value 4 - description " - This option specifies the number of input buffer packets - to be used for the PowerPC QUICC/SMC port 2." - } -} diff --git a/packages/io/serial/current/cdl/ser_sh_edk7708.cdl b/packages/io/serial/current/cdl/ser_sh_edk7708.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_sh_edk7708.cdl +++ /dev/null @@ -1,76 +0,0 @@ -# ==================================================================== -# -# ser_sh_edk7708.cdl -# -# eCos serial SH/EDK7708 configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Contributors: -# Date: 1999-07-08 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_component CYGPKG_IO_SERIAL_SH_EDK7708_SCI { - display "SH3 EDK7708 SCI device driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the SCI port." - - cdl_option CYGDAT_IO_SERIAL_SH_EDK7708_SCI_NAME { - display "Device name for SH3 EDK7708 SCI" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the device name for the SCI port." - } - - cdl_option CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BAUD { - display "Baud rate for the SH SCI driver" - flavor data - legal_values { 4800 9600 14400 19200 38400 57600 115200 } - default_value 38400 - description " - This option specifies the default baud rate (speed) for the - SCI port." - } - - cdl_option CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BUFSIZE { - display "Buffer size for the SH SCI driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used for - the SCI port." - } -} diff --git a/packages/io/serial/current/cdl/ser_sparclite_sleb.cdl b/packages/io/serial/current/cdl/ser_sparclite_sleb.cdl deleted file mode 100644 --- a/packages/io/serial/current/cdl/ser_sparclite_sleb.cdl +++ /dev/null @@ -1,119 +0,0 @@ -# ==================================================================== -# -# ser_sparclite_sleb.cdl -# -# eCos serial SPARClite/SLEB configuration data -# -# ==================================================================== -#####COPYRIGHTBEGIN#### -# -# ------------------------------------------- -# The contents of this file are subject to the Red Hat eCos Public License -# Version 1.1 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.redhat.com/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations under -# the License. -# -# The Original Code is eCos - Embedded Configurable Operating System, -# released September 30, 1998. -# -# The Initial Developer of the Original Code is Red Hat. -# Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -# All Rights Reserved. -# ------------------------------------------- -# -#####COPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Original data: gthomas -# Contributors: -# Date: 1999-07-14 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== -cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1 { - display "SPARClite SLEB serial CON1 port driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the SPARClite - SLEB CON1 port." - - cdl_option CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME { - display "Device name for SPARClite SLEB serial CON1 port" - flavor data - default_value {"\"/dev/ser0\""} - description " - This option specifies the device name for the SPARClite SLEB - CON1 port." - } - - cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BAUD { - display "Baud rate for the SPARClite SLEB serial CON1 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 19200 - description " - This option specifies the default baud rate (speed) for the - SPARClite SLEB CON1." - } - - cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE { - display "Buffer size for the SPARClite SLEB serial CON1 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used for - the SPARClite SLEB CON1." - } -} -cdl_component CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON2 { - display "SPARClite SLEB serial CON2 port driver" - flavor bool - default_value 0 - description " - This option includes the serial device driver for the SPARClite - SLEB CON2 port." - - cdl_option CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON2_NAME { - display "Device name for SPARClite SLEB serial CON2 port" - flavor data - default_value {"\"/dev/ser1\""} - description " - This option specifies the device name for the SPARClite SLEB - CON2 port." - } - - cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BAUD { - display "Baud rate for the SPARClite SLEB serial CON2 driver" - flavor data - legal_values { 50 75 110 "134_5" 150 200 300 600 1200 1800 2400 3600 - 4800 7200 9600 14400 19200 38400 57600 115200 234000 - } - default_value 19200 - description " - This option specifies the default baud rate (speed) for the - SPARClite SLEB CON2." - } - - cdl_option CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE { - display "Buffer size for the SPARClite SLEB serial CON2 driver" - flavor data - legal_values 0 to 8192 - default_value 128 - description " - This option specifies the size of the internal buffers used for - the SPARClite SLEB CON2." - } -} diff --git a/packages/io/serial/current/src/arm/aeb_serial.c b/packages/io/serial/current/src/arm/aeb_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/arm/aeb_serial.c +++ /dev/null @@ -1,318 +0,0 @@ -//========================================================================== -// -// io/serial/arm/aeb_serial.c -// -// ARM AEB-1 Serial I/O Interface Module (interrupt driven) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: AEB-1 Serial I/O module (interrupt driven version) -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_ARM_AEB - -#include "aeb_serial.h" - -typedef struct aeb_serial_info { - CYG_ADDRWORD base; - CYG_WORD int_num; - cyg_interrupt serial_interrupt; - cyg_handle_t serial_interrupt_handle; -} aeb_serial_info; - -static bool aeb_serial_init(struct cyg_devtab_entry *tab); -static bool aeb_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo aeb_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char aeb_serial_getc(serial_channel *chan); -static bool aeb_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void aeb_serial_start_xmit(serial_channel *chan); -static void aeb_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 aeb_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void aeb_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(aeb_serial_funs, - aeb_serial_putc, - aeb_serial_getc, - aeb_serial_set_config, - aeb_serial_start_xmit, - aeb_serial_stop_xmit - ); - -#ifdef CYGPKG_IO_SERIAL_ARM_AEB_SERIAL0 -static aeb_serial_info aeb_serial_info0 = {0xFFFF0000, - CYGNUM_HAL_INTERRUPT_UART0}; -#if CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE > 0 -static unsigned char aeb_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE]; -static unsigned char aeb_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(aeb_serial_channel0, - aeb_serial_funs, - aeb_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &aeb_serial_out_buf0[0], sizeof(aeb_serial_out_buf0), - &aeb_serial_in_buf0[0], sizeof(aeb_serial_in_buf0) - ); -#else -static SERIAL_CHANNEL(aeb_serial_channel0, - aeb_serial_funs, - aeb_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(aeb_serial_io0, - CYGDAT_IO_SERIAL_ARM_AEB_SERIAL0_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - aeb_serial_init, - aeb_serial_lookup, // Serial driver may need initializing - &aeb_serial_channel0 - ); -#endif // CYGPKG_IO_SERIAL_ARM_AEB_SERIAL0 - -#ifdef CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1 -static aeb_serial_info aeb_serial_info1 = {0xFFFF0400, - CYGNUM_HAL_INTERRUPT_UART1}; -#if CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE > 0 -static unsigned char aeb_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE]; -static unsigned char aeb_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(aeb_serial_channel1, - aeb_serial_funs, - aeb_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &aeb_serial_out_buf1[0], sizeof(aeb_serial_out_buf1), - &aeb_serial_in_buf1[0], sizeof(aeb_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(aeb_serial_channel1, - aeb_serial_funs, - aeb_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_AEB_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(aeb_serial_io1, - CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - aeb_serial_init, - aeb_serial_lookup, // Serial driver may need initializing - &aeb_serial_channel1 - ); -#endif // CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1 - -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool -aeb_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; - unsigned short baud_divisor = select_baud[new_config->baud]; - unsigned char _lcr, _ier; - if (baud_divisor == 0) return false; - _ier = port->REG_IER; - port->REG_IER = 0; // Disable port interrupts while changing hardware - _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | - select_stop_bits[new_config->stop] | - select_parity[new_config->parity]; - port->REG_LCR = _lcr; - port->REG_LCR |= LCR_DL; - port->REG_MDL = baud_divisor >> 8; - port->REG_LDL = baud_divisor & 0xFF; - port->REG_LCR &= ~LCR_DL; - if (init) { - port->REG_FCR = 0x07; // Enable and clear FIFO - if (chan->out_cbuf.len != 0) { - port->REG_IER = IER_RCV; - } else { - port->REG_IER = 0; - } - port->REG_MCR = MCR_INT|MCR_DTR|MCR_RTS; // Master interrupt enable - } else { - port->REG_IER = _ier; - } - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -aeb_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; -#ifdef CYGDBG_IO_INIT - diag_printf("AEB SERIAL init - dev: %x.%d\n", aeb_chan->base, aeb_chan->int_num); -#endif - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (chan->out_cbuf.len != 0) { - cyg_drv_interrupt_create(aeb_chan->int_num, - 99, // Priority - unused - (cyg_addrword_t)chan, // Data item passed to interrupt handler - aeb_serial_ISR, - aeb_serial_DSR, - &aeb_chan->serial_interrupt_handle, - &aeb_chan->serial_interrupt); - cyg_drv_interrupt_attach(aeb_chan->serial_interrupt_handle); - cyg_drv_interrupt_unmask(aeb_chan->int_num); - } - aeb_serial_config_port(chan, &chan->config, true); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -aeb_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -aeb_serial_putc(serial_channel *chan, unsigned char c) -{ - aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; - if (port->REG_LSR & LSR_THE) { -// Transmit buffer is empty - port->REG_THR = c; - return true; - } else { -// No space - return false; - } -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -aeb_serial_getc(serial_channel *chan) -{ - unsigned char c; - aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; - while ((port->REG_LSR & LSR_RSR) == 0) ; // Wait for char - c = port->REG_RHR; - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -aeb_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return aeb_serial_config_port(chan, config, false); -} - -// Enable the transmitter on the device -static void -aeb_serial_start_xmit(serial_channel *chan) -{ - aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; - port->REG_IER |= IER_XMT; // Enable xmit interrupt -} - -// Disable the transmitter on the device -static void -aeb_serial_stop_xmit(serial_channel *chan) -{ - aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; - port->REG_IER &= ~IER_XMT; // Disable xmit interrupt -} - -// Serial I/O - low level interrupt handler (ISR) -static cyg_uint32 -aeb_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(aeb_chan->int_num); - cyg_drv_interrupt_acknowledge(aeb_chan->int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level interrupt handler (DSR) -static void -aeb_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - aeb_serial_info *aeb_chan = (aeb_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)aeb_chan->base; - unsigned char isr; - isr = port->REG_ISR & 0x0E; - if (isr == ISR_Tx) { - (chan->callbacks->xmt_char)(chan); - } else if (isr == ISR_Rx) { - (chan->callbacks->rcv_char)(chan, port->REG_RHR); - } - cyg_drv_interrupt_unmask(aeb_chan->int_num); -} -#endif diff --git a/packages/io/serial/current/src/arm/aeb_serial.h b/packages/io/serial/current/src/arm/aeb_serial.h deleted file mode 100644 --- a/packages/io/serial/current/src/arm/aeb_serial.h +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef CYGONCE_ARM_AEB_SERIAL_H -#define CYGONCE_ARM_AEB_SERIAL_H - -// ==================================================================== -// -// aeb_serial.h -// -// Device I/O - Description of ARM AEB-1 serial hardware -// -// ==================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -// ==================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: Internal interfaces for serial I/O drivers -// Description: -// -//####DESCRIPTIONEND#### -// -// ==================================================================== - -// Description of serial ports on ARM AEB-1 - -struct serial_port { - unsigned char _byte[32]; -}; - -#define REG(n) _byte[n*4] - -// Receive control registers -#define REG_RHR REG(0) // Receive holding register -#define REG_ISR REG(2) // Interrupt status register -#define REG_LSR REG(5) // Line status register -#define REG_MSR REG(6) // Modem status register -#define REG_SCR REG(7) // Scratch register - -// Transmit control registers -#define REG_THR REG(0) // Transmit holding register -#define REG_IER REG(1) // Interrupt enable register -#define REG_FCR REG(2) // FIFO control register -#define REG_LCR REG(3) // Line control register -#define REG_MCR REG(4) // Modem control register -#define REG_LDL REG(0) // LSB of baud rate -#define REG_MDL REG(1) // MSB of baud rate - -// Interrupt Enable Register -#define IER_RCV 0x01 -#define IER_XMT 0x02 -#define IER_LS 0x04 -#define IER_MS 0x08 - -// Line Control Register -#define LCR_WL5 0x00 // Word length -#define LCR_WL6 0x01 -#define LCR_WL7 0x02 -#define LCR_WL8 0x03 -#define LCR_SB1 0x00 // Number of stop bits -#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words -#define LCR_SB2 0x04 -#define LCR_PN 0x00 // Parity mode - none -#define LCR_PE 0x0C // Parity mode - even -#define LCR_PO 0x08 // Parity mode - odd -#define LCR_PM 0x28 // Forced "mark" parity -#define LCR_PS 0x38 // Forced "space" parity -#define LCR_DL 0x80 // Enable baud rate latch - -// Line Status Register -#define LSR_RSR 0x01 -#define LSR_THE 0x20 - -// Modem Control Register -#define MCR_DTR 0x01 -#define MCR_RTS 0x02 -#define MCR_INT 0x08 // Enable interrupts - -// Interrupt status register -#define ISR_Tx 0x02 -#define ISR_Rx 0x04 - -static unsigned char select_word_length[] = { - LCR_WL5, // 5 bits / word (char) - LCR_WL6, - LCR_WL7, - LCR_WL8 -}; - -static unsigned char select_stop_bits[] = { - 0, - LCR_SB1, // 1 stop bit - LCR_SB1_5, // 1.5 stop bit - LCR_SB2 // 2 stop bits -}; - -static unsigned char select_parity[] = { - LCR_PN, // No parity - LCR_PE, // Even parity - LCR_PO, // Odd parity - LCR_PM, // Mark parity - LCR_PS, // Space parity -}; - -// Baud rate values, based on raw 24MHz clock - -static unsigned short select_baud[] = { - 0, // Unused - 10000*3, // 50 - 6667*3, // 75 - 4545*3, // 110 - 3717*3, // 134.5 - 3333*3, // 150 - 0, // 200 - 1667*3, // 300 - 833*3, // 600 - 417*3, // 1200 - 277*3, // 1800 - 208*3, // 2400 - 139*3, // 3600 - 104*3, // 4800 - 69*3, // 7200 - 52*3, // 9600 - (69*3)/2, // 14400 - 26*3, // 19200 - 13*3, // 38400 - 0, // 57600 - 0, // 115200 - 0, // 230400 -}; - -#endif // CYGONCE_ARM_AEB_SERIAL_H diff --git a/packages/io/serial/current/src/arm/cma230_serial.c b/packages/io/serial/current/src/arm/cma230_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/arm/cma230_serial.c +++ /dev/null @@ -1,319 +0,0 @@ -//========================================================================== -// -// io/serial/arm/cma230_serial.c -// -// Cogent CMA230 Serial I/O Interface Module (interrupt driven) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: CMA230 Serial I/O module (interrupt driven version) -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_ARM_CMA230 - -#include "cma230_serial.h" - -typedef struct cma230_serial_info { - CYG_ADDRWORD base; - CYG_WORD int_num; - cyg_interrupt serial_interrupt; - cyg_handle_t serial_interrupt_handle; -} cma230_serial_info; - -static bool cma230_serial_init(struct cyg_devtab_entry *tab); -static bool cma230_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo cma230_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char cma230_serial_getc(serial_channel *chan); -static bool cma230_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void cma230_serial_start_xmit(serial_channel *chan); -static void cma230_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 cma230_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void cma230_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(cma230_serial_funs, - cma230_serial_putc, - cma230_serial_getc, - cma230_serial_set_config, - cma230_serial_start_xmit, - cma230_serial_stop_xmit - ); - -#ifdef CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A -static cma230_serial_info cma230_serial_info0 = {CMA101_DUARTA, - CYGNUM_HAL_INTERRUPT_SERIAL_A}; -#if CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE > 0 -static unsigned char cma230_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE]; -static unsigned char cma230_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(cma230_serial_channel0, - cma230_serial_funs, - cma230_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &cma230_serial_out_buf0[0], sizeof(cma230_serial_out_buf0), - &cma230_serial_in_buf0[0], sizeof(cma230_serial_in_buf0) - ); -#else -static SERIAL_CHANNEL(cma230_serial_channel0, - cma230_serial_funs, - cma230_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_A_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(cma230_serial_io0, - CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_A_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - cma230_serial_init, - cma230_serial_lookup, // Serial driver may need initializing - &cma230_serial_channel0 - ); -#endif // CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_A - -#ifdef CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_B -static cma230_serial_info cma230_serial_info1 = {CMA101_DUARTB, - CYGNUM_HAL_INTERRUPT_SERIAL_B}; -#if CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE > 0 -static unsigned char cma230_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE]; -static unsigned char cma230_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(cma230_serial_channel1, - cma230_serial_funs, - cma230_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &cma230_serial_out_buf1[0], sizeof(cma230_serial_out_buf1), - &cma230_serial_in_buf1[0], sizeof(cma230_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(cma230_serial_channel1, - cma230_serial_funs, - cma230_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_CMA230_SERIAL_B_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(cma230_serial_io1, - CYGDAT_IO_SERIAL_ARM_CMA230_SERIAL_B_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - cma230_serial_init, - cma230_serial_lookup, // Serial driver may need initializing - &cma230_serial_channel1 - ); -#endif // CYGPKG_IO_SERIAL_ARM_CMA230_SERIAL_B - -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool -cma230_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; - unsigned short baud_divisor = select_baud[new_config->baud]; - unsigned char _lcr, _ier; - if (baud_divisor == 0) return false; // Invalid configuration - _ier = port->ier; - port->ier = 0; // Disable port interrupts while changing hardware - _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | - select_stop_bits[new_config->stop] | - select_parity[new_config->parity]; - port->lcr = _lcr; - port->lcr |= LCR_DL; - port->mdl = baud_divisor >> 8; - port->ldl = baud_divisor & 0xFF; - port->lcr &= ~LCR_DL; - if (init) { - port->fcr = 0x07; // Enable and clear FIFO - if (chan->out_cbuf.len != 0) { - port->ier = IER_RCV; - } else { - port->ier = 0; - } - port->mcr = MCR_INT|MCR_DTR|MCR_RTS; // Master interrupt enable - } else { - port->ier = _ier; - } - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -cma230_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; -#ifdef CYGDBG_IO_INIT - diag_printf("CMA230 SERIAL init - dev: %x.%d\n", cma230_chan->base, cma230_chan->int_num); -#endif - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (chan->out_cbuf.len != 0) { - cyg_drv_interrupt_create(cma230_chan->int_num, - 99, // Priority - what goes here? - (cyg_addrword_t)chan, // Data item passed to interrupt handler - cma230_serial_ISR, - cma230_serial_DSR, - &cma230_chan->serial_interrupt_handle, - &cma230_chan->serial_interrupt); - cyg_drv_interrupt_attach(cma230_chan->serial_interrupt_handle); - cyg_drv_interrupt_unmask(cma230_chan->int_num); - } - cma230_serial_config_port(chan, &chan->config, true); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -cma230_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -cma230_serial_putc(serial_channel *chan, unsigned char c) -{ - cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; - if (port->lsr & LSR_THE) { -// Transmit buffer is empty - port->thr = c; - return true; - } else { -// No space - return false; - } -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -cma230_serial_getc(serial_channel *chan) -{ - unsigned char c; - cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; - while ((port->lsr & LSR_RSR) == 0) ; // Wait for char - c = port->rhr; - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -cma230_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return cma230_serial_config_port(chan, config, false); -} - -// Enable the transmitter on the device -static void -cma230_serial_start_xmit(serial_channel *chan) -{ - cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; - port->ier |= IER_XMT; // Enable xmit interrupt -} - -// Disable the transmitter on the device -static void -cma230_serial_stop_xmit(serial_channel *chan) -{ - cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; - port->ier &= ~IER_XMT; // Disable xmit interrupt -} - -// Serial I/O - low level interrupt handler (ISR) -static cyg_uint32 -cma230_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(cma230_chan->int_num); - cyg_drv_interrupt_acknowledge(cma230_chan->int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level interrupt handler (DSR) -static void -cma230_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - cma230_serial_info *cma230_chan = (cma230_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)cma230_chan->base; - unsigned char isr; - isr = port->isr & 0x0E; - if (isr == ISR_Tx) { - (chan->callbacks->xmt_char)(chan); - } else if (isr == ISR_Rx) { - (chan->callbacks->rcv_char)(chan, port->rhr); - } - cyg_drv_interrupt_unmask(cma230_chan->int_num); -} -#endif diff --git a/packages/io/serial/current/src/arm/cma230_serial.h b/packages/io/serial/current/src/arm/cma230_serial.h deleted file mode 100644 --- a/packages/io/serial/current/src/arm/cma230_serial.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef CYGONCE_ARM_CMA230_SERIAL_H -#define CYGONCE_ARM_CMA230_SERIAL_H - -// ==================================================================== -// -// cma230_serial.h -// -// Device I/O - Description of Cogent CMA230 serial hardware -// -// ==================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -// ==================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-05-20 -// Purpose: Internal interfaces for serial I/O drivers -// Description: -// -//####DESCRIPTIONEND#### -// -// ==================================================================== - -// Description of serial ports on Cogent CMA230 - -struct serial_port { - unsigned char _byte[32]; -}; - -#define reg(n) _byte[n*8] - -// Receive control registers -#define rhr reg(0) // Receive holding register -#define isr reg(2) // Interrupt status register -#define lsr reg(5) // Line status register -#define msr reg(6) // Modem status register -#define scr reg(7) // Scratch register - -// Transmit control registers -#define thr reg(0) // Transmit holding register -#define ier reg(1) // Interrupt enable register -#define fcr reg(2) // FIFO control register -#define lcr reg(3) // Line control register -#define mcr reg(4) // Modem control register -#define ldl reg(0) // LSB of baud rate -#define mdl reg(1) // MSB of baud rate - -// Interrupt Enable Register -#define IER_RCV 0x01 -#define IER_XMT 0x02 -#define IER_LS 0x04 -#define IER_MS 0x08 - -// Line Control Register -#define LCR_WL5 0x00 // Word length -#define LCR_WL6 0x01 -#define LCR_WL7 0x02 -#define LCR_WL8 0x03 -#define LCR_SB1 0x00 // Number of stop bits -#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words -#define LCR_SB2 0x04 -#define LCR_PN 0x00 // Parity mode - none -#define LCR_PE 0x0C // Parity mode - even -#define LCR_PO 0x08 // Parity mode - odd -#define LCR_PM 0x28 // Forced "mark" parity -#define LCR_PS 0x38 // Forced "space" parity -#define LCR_DL 0x80 // Enable baud rate latch - -// Line Status Register -#define LSR_RSR 0x01 -#define LSR_THE 0x20 - -// Modem Control Register -#define MCR_DTR 0x01 -#define MCR_RTS 0x02 -#define MCR_INT 0x08 // Enable interrupts - -// Interrupt status register -#define ISR_Tx 0x02 -#define ISR_Rx 0x04 - -static unsigned char select_word_length[] = { - LCR_WL5, // 5 bits / word (char) - LCR_WL6, - LCR_WL7, - LCR_WL8 -}; - -static unsigned char select_stop_bits[] = { - 0, - LCR_SB1, // 1 stop bit - LCR_SB1_5, // 1.5 stop bit - LCR_SB2 // 2 stop bits -}; - -static unsigned char select_parity[] = { - LCR_PN, // No parity - LCR_PE, // Even parity - LCR_PO, // Odd parity - LCR_PM, // Mark parity - LCR_PS, // Space parity -}; - -// The Cogent board has a 3.6864 MHz crystal -static unsigned short select_baud[] = { - 0, // Unused - 4608, // 50 - 0, // 75 - 2094, // 110 - 0, // 134.5 - 1536, // 150 - 0, // 200 - 768, // 300 - 384, // 600 - 182, // 1200 - 0, // 1800 - 96, // 2400 - 0, // 3600 - 48, // 4800 - 32, // 7200 - 24, // 9600 - 16, // 14400 - 12, // 19200 - 6, // 38400 - 4, // 57600 - 2, // 115200 - 0, // 230400 -}; - -#endif // CYGONCE_ARM_CMA230_SERIAL_H diff --git a/packages/io/serial/current/src/arm/ebsa285_serial.c b/packages/io/serial/current/src/arm/ebsa285_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/arm/ebsa285_serial.c +++ /dev/null @@ -1,422 +0,0 @@ -//========================================================================== -// -// io/serial/arm/ebsa285_serial.c -// -// ARM EBSA285 Serial I/O Interface Module (interrupt driven) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): hmt -// Contributors: hmt -// Date: 1999-07-26 -// Purpose: EBSA285 Serial I/O module (interrupt driven version) -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_ARM_EBSA285 - -#include -#include -#include -#include -#include - -#include // Hardware definitions - -// ------------------------------------------------------------------------ -// Baud rates and the like, table-driven setup -#define FCLK_MHZ 50 - -struct _baud { - unsigned char divisor_high, divisor_low; -}; - -// The indexing of this table must match the enum in serialio.h -// The arithmetic is (clock/4)/(baud * 16) - 1 - -#define NONE {0,0} -const static struct _baud bauds[] = { -#if (FCLK_MHZ == 50) - NONE, // unused - NONE, // 50 - NONE, // 75 - NONE, // 110 - NONE, // 134.5 - NONE, // 150 - NONE, // 200 - { 0xA, 0x2B }, // 300 2603 = 0x0A2B - { 0x5, 0x15 }, // 600 1301 = 0x0515 - { 0x2, 0x8A }, // 1200 650 = 0x028A - { 0x1, 0xB1 }, // 1800 433 = 0x01B1 - { 0x1, 0x45 }, // 2400 325 = 0x0145 - { 0x0, 0xD8 }, // 3600 216 = 0x00D8 - { 0x0, 0xA2 }, // 4800 162 = 0x00A2 - { 0x0, 0x6B }, // 7200 107 = 0x006B - { 0x0, 0x50 }, // 9600 80 = 0x0050 - { 0x0, 0x35 }, // 14400 53 = 0x0035 - { 0x0, 0x28 }, // 19200 40 = 0x0028 - { 0x0, 0x13 }, // 38400 19 = 0x0013 - NONE, // 57600 - NONE, // 115200 - NONE // 230400 -#elif (FCLK_MHZ == 60) -#error NOT SUPPORTED - these figures are more for documentation - { /* 300, */ 0xC, 0x34}, /* 2603 = 0x0A2B */ - { /* 600, */ 0x6, 0x19}, /* 1301 = 0x0515 */ - { /* 1200, */ 0x3, 0x0C}, /* 650 = 0x028A */ - { /* 2400, */ 0x1, 0x86}, /* 325 = 0x0145 */ - { /* 4800, */ 0x0, 0xC2}, /* 162 = 0x00A2 */ - { /* 9600, */ 0x0, 0x61}, /* 80 = 0x0050 */ - { /* 19200, */ 0x0, 0x30}, /* 40 = 0x0028 */ - { /* 38400, */ 0x0, 0x17}, /* 19 = 0x0013 */ -#endif -}; - -static int select_word_length[] = { - SA110_UART_DATA_LENGTH_5_BITS, // 5 bits - SA110_UART_DATA_LENGTH_6_BITS, // 6 bits - SA110_UART_DATA_LENGTH_7_BITS, // 7 bits - SA110_UART_DATA_LENGTH_8_BITS // 8 bits -}; - -static int select_stop_bits[] = { - -1, // unused - SA110_UART_STOP_BITS_ONE, // 1 stop bit - -1, // 1.5 stop bit - SA110_UART_STOP_BITS_TWO // 2 stop bits -}; - -static int select_parity[] = { - SA110_UART_PARITY_DISABLED, // No parity - SA110_UART_PARITY_ENABLED | SA110_UART_PARITY_EVEN, // Even parity - SA110_UART_PARITY_ENABLED | SA110_UART_PARITY_ODD, // Odd parity - -1, // Mark parity - -1 // Space parity -}; - -// ------------------------------------------------------------------------ -// some forward references - -struct ebsa285_serial_interrupt { - CYG_WORD int_num; - cyg_interrupt serial_interrupt; - cyg_handle_t serial_interrupt_handle; -}; - -typedef struct ebsa285_serial_info { - struct ebsa285_serial_interrupt rx; - struct ebsa285_serial_interrupt tx; -} ebsa285_serial_info; - -static bool ebsa285_serial_init(struct cyg_devtab_entry *tab); -static bool ebsa285_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo ebsa285_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char ebsa285_serial_getc(serial_channel *chan); -static bool ebsa285_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void ebsa285_serial_start_xmit(serial_channel *chan); -static void ebsa285_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 ebsa285_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void ebsa285_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); -static cyg_uint32 ebsa285_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void ebsa285_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(ebsa285_serial_funs, - ebsa285_serial_putc, - ebsa285_serial_getc, - ebsa285_serial_set_config, - ebsa285_serial_start_xmit, - ebsa285_serial_stop_xmit - ); - - -// ------------------------------------------------------------------------ -// this is dummy in config: there is only one device on the EBSA285 -#define CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL // so always define it -#ifdef CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL - -static ebsa285_serial_info ebsa285_serial_info1 = { - { CYGNUM_HAL_INTERRUPT_SERIAL_RX }, - { CYGNUM_HAL_INTERRUPT_SERIAL_TX } -}; - -#if CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE > 0 -static unsigned char ebsa285_serial_out_buf[CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE]; -static unsigned char ebsa285_serial_in_buf[CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(ebsa285_serial_channel, - ebsa285_serial_funs, - ebsa285_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &ebsa285_serial_out_buf[0], sizeof(ebsa285_serial_out_buf), - &ebsa285_serial_in_buf[0], sizeof(ebsa285_serial_in_buf) - ); -#else -static SERIAL_CHANNEL(ebsa285_serial_channel, - ebsa285_serial_funs, - ebsa285_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EBSA285_SERIAL_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(ebsa285_serial_io, - CYGDAT_IO_SERIAL_ARM_EBSA285_SERIAL_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - ebsa285_serial_init, - ebsa285_serial_lookup, // Serial driver may need initializing - &ebsa285_serial_channel - ); -#endif // CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL - -// ------------------------------------------------------------------------ - - -// ------------------------------------------------------------------------ -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool -ebsa285_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - int dummy, h, m, l; - - // Make sure everything is off - *SA110_UART_CONTROL_REGISTER = SA110_UART_DISABLED | SA110_SIR_DISABLED; - - // Read the RXStat to drain the fifo - dummy = *SA110_UART_RXSTAT; - - // Set the baud rate - this also turns the uart on. - // - // Note that the ordering of these writes is critical, - // and the writes to the H_BAUD_CONTROL and CONTROL_REGISTER - // are necessary to force the UART to update its register - // contents. - - l = bauds[new_config->baud].divisor_low; // zeros in unused slots here - m = bauds[new_config->baud].divisor_high; // and here - h = SA110_UART_BREAK_DISABLED | - select_stop_bits[new_config->stop] | // -1s in unused slots for these - select_parity[new_config->parity] | // and these - SA110_UART_FIFO_ENABLED | // and these below - select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; - - if ( 0 != (l + m) && h >= 0 && h < 256 ) { - *SA110_UART_L_BAUD_CONTROL = l; - *SA110_UART_M_BAUD_CONTROL = m; - *SA110_UART_H_BAUD_CONTROL = h; - init = true; // AOK - } - else if ( init ) { - // put in some sensible defaults - *SA110_UART_L_BAUD_CONTROL = 0x13; // bp->divisor_low; - *SA110_UART_M_BAUD_CONTROL = 0x00; // bp->divisor_high; - *SA110_UART_H_BAUD_CONTROL = SA110_UART_BREAK_DISABLED | - SA110_UART_PARITY_DISABLED | - SA110_UART_STOP_BITS_ONE | - SA110_UART_FIFO_ENABLED | - SA110_UART_DATA_LENGTH_8_BITS; - } - - // All set, re-enable the device: - *SA110_UART_CONTROL_REGISTER = SA110_UART_ENABLED | SA110_SIR_DISABLED; - - if (init && new_config != &chan->config) { - // record the new setup - chan->config = *new_config; - } - // All done - return init; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -ebsa285_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; -#ifdef CYGDBG_IO_INIT - diag_printf("EBSA285 SERIAL init - dev: %x.%d\n", ebsa285_chan->base, ebsa285_chan->int_num); -#endif - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (chan->out_cbuf.len != 0) { - - // first for rx - cyg_drv_interrupt_create(ebsa285_chan->rx.int_num, - 99, // Priority - unused - (cyg_addrword_t)chan, // Data item passed to interrupt handler - ebsa285_serial_rx_ISR, - ebsa285_serial_rx_DSR, - &ebsa285_chan->rx.serial_interrupt_handle, - &ebsa285_chan->rx.serial_interrupt); - cyg_drv_interrupt_attach(ebsa285_chan->rx.serial_interrupt_handle); - cyg_drv_interrupt_unmask(ebsa285_chan->rx.int_num); - - // then for tx - cyg_drv_interrupt_create(ebsa285_chan->tx.int_num, - 99, // Priority - unused - (cyg_addrword_t)chan, // Data item passed to interrupt handler - ebsa285_serial_tx_ISR, - ebsa285_serial_tx_DSR, - &ebsa285_chan->tx.serial_interrupt_handle, - &ebsa285_chan->tx.serial_interrupt); - cyg_drv_interrupt_attach(ebsa285_chan->tx.serial_interrupt_handle); - // DO NOT cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num); - } - (void)ebsa285_serial_config_port(chan, &chan->config, true); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -ebsa285_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -ebsa285_serial_putc(serial_channel *chan, unsigned char c) -{ - if ((*SA110_UART_FLAG_REGISTER & SA110_TX_FIFO_STATUS_MASK) == SA110_TX_FIFO_BUSY) - return false; // No space - - *SA110_UART_DATA_REGISTER = c; // Transmit buffer is empty - return true; -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -ebsa285_serial_getc(serial_channel *chan) -{ - unsigned char c; - while ((*SA110_UART_FLAG_REGISTER & SA110_RX_FIFO_STATUS_MASK) == SA110_RX_FIFO_EMPTY) - ; // wait for char - c = (char)(*SA110_UART_DATA_REGISTER & 0xFF); - // no error checking... no way to return the info - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -ebsa285_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return ebsa285_serial_config_port(chan, config, false); -} - -// Enable the transmitter on the device (nope, already in use by hal_diag) -static void -ebsa285_serial_start_xmit(serial_channel *chan) -{ - ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; - cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num); -} - -// Disable the transmitter on the device (nope, remains in use by hal_diag) -static void -ebsa285_serial_stop_xmit(serial_channel *chan) -{ - ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(ebsa285_chan->tx.int_num); -} - -// Serial I/O - low level interrupt handlers (ISR) -static cyg_uint32 -ebsa285_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(ebsa285_chan->rx.int_num); - cyg_drv_interrupt_acknowledge(ebsa285_chan->rx.int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -static cyg_uint32 -ebsa285_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(ebsa285_chan->tx.int_num); - cyg_drv_interrupt_acknowledge(ebsa285_chan->tx.int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level interrupt handlers (DSR) -static void -ebsa285_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; - if ((*SA110_UART_FLAG_REGISTER & SA110_RX_FIFO_STATUS_MASK) != SA110_RX_FIFO_EMPTY) { - char c = (char)(*SA110_UART_DATA_REGISTER & 0xFF); - int status; - c = (char)(*SA110_UART_DATA_REGISTER & 0xFF); - status = *SA110_UART_RXSTAT; - if ( 0 == (status & (SA110_UART_FRAMING_ERROR_MASK | - SA110_UART_PARITY_ERROR_MASK | - SA110_UART_OVERRUN_ERROR_MASK)) ) - (chan->callbacks->rcv_char)(chan, c); - } - cyg_drv_interrupt_unmask(ebsa285_chan->rx.int_num); -} - -static void -ebsa285_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv; - if ((*SA110_UART_FLAG_REGISTER & SA110_TX_FIFO_STATUS_MASK) != SA110_TX_FIFO_BUSY) { - (chan->callbacks->xmt_char)(chan); - } - cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num); -} -#endif // CYGPKG_IO_SERIAL_ARM_EBSA285 - -// ------------------------------------------------------------------------ -// EOF ebsa285_serial.c diff --git a/packages/io/serial/current/src/arm/edb7xxx_serial.c b/packages/io/serial/current/src/arm/edb7xxx_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/arm/edb7xxx_serial.c +++ /dev/null @@ -1,383 +0,0 @@ -//========================================================================== -// -// io/serial/arm/edb7xxx_serial.c -// -// Cirrus Logic EDB7XXX Serial I/O Interface Module (interrupt driven) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: EDB7XXX Serial I/O module (interrupt driven version) -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_ARM_EDB7XXX - -#include "edb7xxx_serial.h" - -typedef struct edb7xxx_serial_info { - CYG_ADDRWORD data, // Pointer to data register - control, // Pointer to baud rate/line control register - stat, // Pointer to system flags for this port - syscon; // Pointer to system control for this port - CYG_WORD tx_int_num, // Transmit interrupt number - rx_int_num, // Receive interrupt number - ms_int_num; // Modem Status Change interrupt number - cyg_interrupt serial_tx_interrupt, - serial_rx_interrupt, - serial_ms_interrupt; - cyg_handle_t serial_tx_interrupt_handle, - serial_rx_interrupt_handle, - serial_ms_interrupt_handle; - bool tx_enabled; -} edb7xxx_serial_info; - -static bool edb7xxx_serial_init(struct cyg_devtab_entry *tab); -static bool edb7xxx_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo edb7xxx_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char edb7xxx_serial_getc(serial_channel *chan); -static bool edb7xxx_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void edb7xxx_serial_start_xmit(serial_channel *chan); -static void edb7xxx_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 edb7xxx_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void edb7xxx_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); -static cyg_uint32 edb7xxx_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void edb7xxx_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); -static cyg_uint32 edb7xxx_serial_ms_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void edb7xxx_serial_ms_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(edb7xxx_serial_funs, - edb7xxx_serial_putc, - edb7xxx_serial_getc, - edb7xxx_serial_set_config, - edb7xxx_serial_start_xmit, - edb7xxx_serial_stop_xmit - ); - -#ifdef CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL1 -static edb7xxx_serial_info edb7xxx_serial_info1 = {UARTDR1, // Data register - UBLCR1, // Port control - SYSFLG1, // Status - SYSCON1, // System config - CYGNUM_HAL_INTERRUPT_UTXINT1, // Tx interrupt - CYGNUM_HAL_INTERRUPT_URXINT1, // Rx interrupt - 0 /*CYGNUM_HAL_INTERRUPT_UMSINT*/}; // Modem control -#if CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE > 0 -static unsigned char edb7xxx_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE]; -static unsigned char edb7xxx_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(edb7xxx_serial_channel1, - edb7xxx_serial_funs, - edb7xxx_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &edb7xxx_serial_out_buf1[0], sizeof(edb7xxx_serial_out_buf1), - &edb7xxx_serial_in_buf1[0], sizeof(edb7xxx_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(edb7xxx_serial_channel1, - edb7xxx_serial_funs, - edb7xxx_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(edb7xxx_serial_io1, - CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL1_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - edb7xxx_serial_init, - edb7xxx_serial_lookup, // Serial driver may need initializing - &edb7xxx_serial_channel1 - ); -#endif // CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2 - -#ifdef CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2 -static edb7xxx_serial_info edb7xxx_serial_info2 = {UARTDR2, // Data register - UBLCR2, // Port control - SYSFLG2, // Status - SYSCON2, // System config - CYGNUM_HAL_INTERRUPT_UTXINT2, // Tx interrupt - CYGNUM_HAL_INTERRUPT_URXINT2, // Rx interrupt - 0}; // No modem control -#if CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE > 0 -static unsigned char edb7xxx_serial_out_buf2[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE]; -static unsigned char edb7xxx_serial_in_buf2[CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(edb7xxx_serial_channel2, - edb7xxx_serial_funs, - edb7xxx_serial_info2, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &edb7xxx_serial_out_buf2[0], sizeof(edb7xxx_serial_out_buf2), - &edb7xxx_serial_in_buf2[0], sizeof(edb7xxx_serial_in_buf2) - ); -#else -static SERIAL_CHANNEL(edb7xxx_serial_channel2, - edb7xxx_serial_funs, - edb7xxx_serial_info2, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_EDB7XXX_SERIAL2_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(edb7xxx_serial_io2, - CYGDAT_IO_SERIAL_ARM_EDB7XXX_SERIAL2_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - edb7xxx_serial_init, - edb7xxx_serial_lookup, // Serial driver may need initializing - &edb7xxx_serial_channel2 - ); -#endif // CYGPKG_IO_SERIAL_ARM_EDB7XXX_SERIAL2 - -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool -edb7xxx_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - volatile cyg_uint32 *syscon = (volatile cyg_uint32 *)edb7xxx_chan->syscon; - volatile cyg_uint32 *blcfg = (volatile cyg_uint32 *)edb7xxx_chan->control; - unsigned int baud_divisor = select_baud[new_config->baud]; - cyg_uint32 _lcr; - if (baud_divisor == 0) return false; - // Disable port interrupts while changing hardware - _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | - select_stop_bits[new_config->stop] | - select_parity[new_config->parity] | - UBLCR_FIFOEN | UART_BITRATE(baud_divisor); -#ifdef CYGDBG_IO_INIT - diag_printf("Set CTL: %x = %x\n", blcfg, _lcr); -#endif - *blcfg = _lcr; - *syscon |= SYSCON1_UART1EN; - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -edb7xxx_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; -#ifdef CYGDBG_IO_INIT - diag_printf("EDB7XXX SERIAL init - dev: %x.%d\n", edb7xxx_chan->control, edb7xxx_chan->tx_int_num); -#endif - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (chan->out_cbuf.len != 0) { - cyg_drv_interrupt_create(edb7xxx_chan->tx_int_num, - 99, // Priority - unused - (cyg_addrword_t)chan, // Data item passed to interrupt handler - edb7xxx_serial_tx_ISR, - edb7xxx_serial_tx_DSR, - &edb7xxx_chan->serial_tx_interrupt_handle, - &edb7xxx_chan->serial_tx_interrupt); - cyg_drv_interrupt_attach(edb7xxx_chan->serial_tx_interrupt_handle); - cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num); - edb7xxx_chan->tx_enabled = false; - } - if (chan->in_cbuf.len != 0) { - cyg_drv_interrupt_create(edb7xxx_chan->rx_int_num, - 99, // Priority - unused - (cyg_addrword_t)chan, // Data item passed to interrupt handler - edb7xxx_serial_rx_ISR, - edb7xxx_serial_rx_DSR, - &edb7xxx_chan->serial_rx_interrupt_handle, - &edb7xxx_chan->serial_rx_interrupt); - cyg_drv_interrupt_attach(edb7xxx_chan->serial_rx_interrupt_handle); - cyg_drv_interrupt_unmask(edb7xxx_chan->rx_int_num); - } - edb7xxx_serial_config_port(chan, &chan->config, true); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -edb7xxx_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -edb7xxx_serial_putc(serial_channel *chan, unsigned char c) -{ - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - volatile cyg_uint8 *data = (volatile cyg_uint8 *)edb7xxx_chan->data; - volatile cyg_uint32 *stat = (volatile cyg_uint32 *)edb7xxx_chan->stat; - if ((*stat & SYSFLG1_UTXFF1) == 0) { -// Transmit buffer/FIFO is not full - *data = c; - return true; - } else { -// No space - return false; - } -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -edb7xxx_serial_getc(serial_channel *chan) -{ - unsigned char c; - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - volatile cyg_uint32 *data = (volatile cyg_uint32 *)edb7xxx_chan->data; - volatile cyg_uint32 *stat = (volatile cyg_uint32 *)edb7xxx_chan->stat; - while (*stat & SYSFLG1_URXFE1) ; // Wait for char - c = *data; - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -edb7xxx_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return edb7xxx_serial_config_port(chan, config, false); -} - -// Enable the transmitter (interrupt) on the device -static void -edb7xxx_serial_start_xmit(serial_channel *chan) -{ - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - edb7xxx_chan->tx_enabled = true; - cyg_drv_interrupt_unmask(edb7xxx_chan->tx_int_num); -} - -// Disable the transmitter on the device -static void -edb7xxx_serial_stop_xmit(serial_channel *chan) -{ - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num); - edb7xxx_chan->tx_enabled = false; -} - -// Serial I/O - low level Tx interrupt handler (ISR) -static cyg_uint32 -edb7xxx_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num); - cyg_drv_interrupt_acknowledge(edb7xxx_chan->tx_int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level Tx interrupt handler (DSR) -static void -edb7xxx_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - (chan->callbacks->xmt_char)(chan); - if (edb7xxx_chan->tx_enabled) { - cyg_drv_interrupt_unmask(edb7xxx_chan->tx_int_num); - } -} - -// Serial I/O - low level Rx interrupt handler (ISR) -static cyg_uint32 -edb7xxx_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(edb7xxx_chan->rx_int_num); - cyg_drv_interrupt_acknowledge(edb7xxx_chan->rx_int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level Rx interrupt handler (DSR) -static void -edb7xxx_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - volatile cyg_uint32 *datreg = (volatile cyg_uint32 *)edb7xxx_chan->data; - volatile cyg_uint32 *stat = (volatile cyg_uint32 *)edb7xxx_chan->stat; - while (!(*stat & SYSFLG1_URXFE1)) - (chan->callbacks->rcv_char)(chan, *datreg); - cyg_drv_interrupt_unmask(edb7xxx_chan->rx_int_num); -} - -// Serial I/O - low level Ms interrupt handler (ISR) -static cyg_uint32 -edb7xxx_serial_ms_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(edb7xxx_chan->ms_int_num); - cyg_drv_interrupt_acknowledge(edb7xxx_chan->ms_int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level Ms interrupt handler (DSR) -static void -edb7xxx_serial_ms_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ -} -#endif // CYGPKG_IO_SERIAL_ARM_EDB7XXX - diff --git a/packages/io/serial/current/src/arm/edb7xxx_serial.h b/packages/io/serial/current/src/arm/edb7xxx_serial.h deleted file mode 100644 --- a/packages/io/serial/current/src/arm/edb7xxx_serial.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef CYGONCE_ARM_EDB7XXX_SERIAL_H -#define CYGONCE_ARM_EDB7XXX_SERIAL_H - -// ==================================================================== -// -// edb7xxx_serial.h -// -// Device I/O - Description of Cirrus Logic EDB7XXX serial hardware -// -// ==================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -// ==================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: Internal interfaces for serial I/O drivers -// Description: -// -//####DESCRIPTIONEND#### -// -// ==================================================================== - -// Description of serial ports on Cirrus Logic EDB7XXX - -#include // Hardware definitions - -static unsigned int select_word_length[] = { - UBLCR_WRDLEN5, // 5 bits / word (char) - UBLCR_WRDLEN6, - UBLCR_WRDLEN7, - UBLCR_WRDLEN8 -}; - -static unsigned int select_stop_bits[] = { - 0, - 0, // 1 stop bit - 0, // 1.5 stop bit - UBLCR_XSTOP // 2 stop bits -}; - -static unsigned int select_parity[] = { - 0, // No parity - UBLCR_PRTEN|UBLCR_EVENPRT, // Even parity - UBLCR_PRTEN, // Odd parity - 0, // Mark parity - 0, // Space parity -}; - -// Baud rate values, based on PLL clock - -static cyg_int32 select_baud[] = { - 0, // Unused - 50, // 50 - 75, // 75 - 110, // 110 - 0, // 134.5 - 150, // 150 - 200, // 200 - 300, // 300 - 600, // 600 - 1200, // 1200 - 1800, // 1800 - 2400, // 2400 - 3600, // 3600 - 4800, // 4800 - 7200, // 7200 - 9600, // 9600 - 14400, // 14400 - 19200, // 19200 - 38400, // 38400 - 57600, // 57600 - 115200, // 115200 - 0, // 230400 -}; - -#endif // CYGONCE_ARM_EDB7XXX_SERIAL_H diff --git a/packages/io/serial/current/src/arm/pid_serial.h b/packages/io/serial/current/src/arm/pid_serial.h deleted file mode 100644 --- a/packages/io/serial/current/src/arm/pid_serial.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef CYGONCE_ARM_PID_SERIAL_H -#define CYGONCE_ARM_PID_SERIAL_H - -// ==================================================================== -// -// pid_serial.h -// -// Device I/O - Description of ARM PID7T serial hardware -// -// ==================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -// ==================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: Internal interfaces for serial I/O drivers -// Description: -// -//####DESCRIPTIONEND#### -// -// ==================================================================== - -// Description of serial ports on ARM PID7T - -struct serial_port { - unsigned char _byte[32]; -}; - -// Little-endian version -#if (CYG_BYTEORDER == CYG_LSBFIRST) - -#define reg(n) _byte[n*4] - -#else // Big-endian version - -#define reg(n) _byte[(n*4)^3] - -#endif - -// Receive control registers -#define rhr reg(0) // Receive holding register -#define isr reg(2) // Interrupt status register -#define lsr reg(5) // Line status register -#define msr reg(6) // Modem status register -#define scr reg(7) // Scratch register - -// Transmit control registers -#define thr reg(0) // Transmit holding register -#define ier reg(1) // Interrupt enable register -#define fcr reg(2) // FIFO control register -#define lcr reg(3) // Line control register -#define mcr reg(4) // Modem control register -#define ldl reg(0) // LSB of baud rate -#define mdl reg(1) // MSB of baud rate - -// Interrupt Enable Register -#define IER_RCV 0x01 -#define IER_XMT 0x02 -#define IER_LS 0x04 -#define IER_MS 0x08 - -// Line Control Register -#define LCR_WL5 0x00 // Word length -#define LCR_WL6 0x01 -#define LCR_WL7 0x02 -#define LCR_WL8 0x03 -#define LCR_SB1 0x00 // Number of stop bits -#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words -#define LCR_SB2 0x04 -#define LCR_PN 0x00 // Parity mode - none -#define LCR_PE 0x0C // Parity mode - even -#define LCR_PO 0x08 // Parity mode - odd -#define LCR_PM 0x28 // Forced "mark" parity -#define LCR_PS 0x38 // Forced "space" parity -#define LCR_DL 0x80 // Enable baud rate latch - -// Line Status Register -#define LSR_RSR 0x01 -#define LSR_THE 0x20 - -// Modem Control Register -#define MCR_DTR 0x01 -#define MCR_RTS 0x02 -#define MCR_INT 0x08 // Enable interrupts - -// Interrupt status register -#define ISR_Tx 0x02 -#define ISR_Rx 0x04 -#define ISR_RxTO 0x0C - -static unsigned char select_word_length[] = { - LCR_WL5, // 5 bits / word (char) - LCR_WL6, - LCR_WL7, - LCR_WL8 -}; - -static unsigned char select_stop_bits[] = { - 0, - LCR_SB1, // 1 stop bit - LCR_SB1_5, // 1.5 stop bit - LCR_SB2 // 2 stop bits -}; - -static unsigned char select_parity[] = { - LCR_PN, // No parity - LCR_PE, // Even parity - LCR_PO, // Odd parity - LCR_PM, // Mark parity - LCR_PS, // Space parity -}; - -static unsigned short select_baud[] = { - 0, // Unused - 0, // 50 - 0, // 75 - 1047, // 110 - 0, // 134.5 - 768, // 150 - 0, // 200 - 384, // 300 - 192, // 600 - 96, // 1200 - 24, // 1800 - 48, // 2400 - 0, // 3600 - 24, // 4800 - 16, // 7200 - 12, // 9600 - 8, // 14400 - 6, // 19200 - 3, // 38400 - 2, // 57600 - 1, // 115200 - 0, // 230400 -}; - -#endif // CYGONCE_ARM_PID_SERIAL_H diff --git a/packages/io/serial/current/src/arm/pid_serial_with_ints.c b/packages/io/serial/current/src/arm/pid_serial_with_ints.c deleted file mode 100644 --- a/packages/io/serial/current/src/arm/pid_serial_with_ints.c +++ /dev/null @@ -1,318 +0,0 @@ -//========================================================================== -// -// io/serial/arm/pid_serial_with_ints.c -// -// ARM PID Serial I/O Interface Module (interrupt driven) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: PID Serial I/O module (interrupt driven version) -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_ARM_PID -#include "pid_serial.h" - -typedef struct pid_serial_info { - CYG_ADDRWORD base; - CYG_WORD int_num; - cyg_interrupt serial_interrupt; - cyg_handle_t serial_interrupt_handle; -} pid_serial_info; - -static bool pid_serial_init(struct cyg_devtab_entry *tab); -static bool pid_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo pid_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char pid_serial_getc(serial_channel *chan); -static bool pid_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void pid_serial_start_xmit(serial_channel *chan); -static void pid_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 pid_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void pid_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(pid_serial_funs, - pid_serial_putc, - pid_serial_getc, - pid_serial_set_config, - pid_serial_start_xmit, - pid_serial_stop_xmit - ); - -#ifdef CYGPKG_IO_SERIAL_ARM_PID_SERIAL0 -static pid_serial_info pid_serial_info0 = {0x0D800000, CYGNUM_HAL_INTERRUPT_SERIALA}; -#if CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE > 0 -static unsigned char pid_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE]; -static unsigned char pid_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(pid_serial_channel0, - pid_serial_funs, - pid_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &pid_serial_out_buf0[0], sizeof(pid_serial_out_buf0), - &pid_serial_in_buf0[0], sizeof(pid_serial_in_buf0) - ); -#else -static SERIAL_CHANNEL(pid_serial_channel0, - pid_serial_funs, - pid_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(pid_serial_io0, - CYGDAT_IO_SERIAL_ARM_PID_SERIAL0_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - pid_serial_init, - pid_serial_lookup, // Serial driver may need initializing - &pid_serial_channel0 - ); -#endif // CYGPKG_IO_SERIAL_ARM_PID_SERIAL0 - -#ifdef CYGPKG_IO_SERIAL_ARM_PID_SERIAL1 -static pid_serial_info pid_serial_info1 = {0x0D800020, CYGNUM_HAL_INTERRUPT_SERIALB}; -#if CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE > 0 -static unsigned char pid_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE]; -static unsigned char pid_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(pid_serial_channel1, - pid_serial_funs, - pid_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &pid_serial_out_buf1[0], sizeof(pid_serial_out_buf1), - &pid_serial_in_buf1[0], sizeof(pid_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(pid_serial_channel1, - pid_serial_funs, - pid_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_ARM_PID_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(pid_serial_io1, - CYGDAT_IO_SERIAL_ARM_PID_SERIAL1_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - pid_serial_init, - pid_serial_lookup, // Serial driver may need initializing - &pid_serial_channel1 - ); -#endif // CYGPKG_IO_SERIAL_ARM_PID_SERIAL1 - -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool -pid_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; - unsigned short baud_divisor = select_baud[new_config->baud]; - unsigned char _lcr, _ier; - if (baud_divisor == 0) return false; // Invalid configuration - _ier = port->ier; - port->ier = 0; // Disable port interrupts while changing hardware - _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | - select_stop_bits[new_config->stop] | - select_parity[new_config->parity]; - port->lcr = _lcr; - port->lcr |= LCR_DL; - port->mdl = baud_divisor >> 8; - port->ldl = baud_divisor & 0xFF; - port->lcr &= ~LCR_DL; - if (init) { - port->fcr = 0x07; // Enable and clear FIFO - if (chan->out_cbuf.len != 0) { - port->ier = IER_RCV; - } else { - port->ier = 0; - } - port->mcr = MCR_INT|MCR_DTR|MCR_RTS; // Master interrupt enable - } else { - port->ier = _ier; - } - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -pid_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; -#ifdef CYGDBG_IO_INIT - diag_printf("PID SERIAL init - dev: %x.%d\n", pid_chan->base, pid_chan->int_num); -#endif - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (chan->out_cbuf.len != 0) { - cyg_drv_interrupt_create(pid_chan->int_num, - 99, // Priority - what goes here? - (cyg_addrword_t)chan, // Data item passed to interrupt handler - pid_serial_ISR, - pid_serial_DSR, - &pid_chan->serial_interrupt_handle, - &pid_chan->serial_interrupt); - cyg_drv_interrupt_attach(pid_chan->serial_interrupt_handle); - cyg_drv_interrupt_unmask(pid_chan->int_num); - } - pid_serial_config_port(chan, &chan->config, true); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -pid_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -pid_serial_putc(serial_channel *chan, unsigned char c) -{ - pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; - if (port->lsr & LSR_THE) { -// Transmit buffer is empty - port->thr = c; - return true; - } else { -// No space - return false; - } -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -pid_serial_getc(serial_channel *chan) -{ - unsigned char c; - pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; - while ((port->lsr & LSR_RSR) == 0) ; // Wait for char - c = port->rhr; - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -pid_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return pid_serial_config_port(chan, config, false); -} - -// Enable the transmitter on the device -static void -pid_serial_start_xmit(serial_channel *chan) -{ - pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; - port->ier |= IER_XMT; // Enable xmit interrupt -} - -// Disable the transmitter on the device -static void -pid_serial_stop_xmit(serial_channel *chan) -{ - pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; - port->ier &= ~IER_XMT; // Disable xmit interrupt -} - -// Serial I/O - low level interrupt handler (ISR) -static cyg_uint32 -pid_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(pid_chan->int_num); - cyg_drv_interrupt_acknowledge(pid_chan->int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level interrupt handler (DSR) -static void -pid_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - pid_serial_info *pid_chan = (pid_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)pid_chan->base; - unsigned char isr; - while ((isr = port->isr & 0x0E) != 0) { - if (isr == ISR_Tx) { - (chan->callbacks->xmt_char)(chan); - } else if (isr == ISR_RxTO) { - (chan->callbacks->rcv_char)(chan, port->rhr); - } else if (isr == ISR_Rx) { - (chan->callbacks->rcv_char)(chan, port->rhr); - } - } - cyg_drv_interrupt_unmask(pid_chan->int_num); -} -#endif diff --git a/packages/io/serial/current/src/common/serial.c b/packages/io/serial/current/src/common/serial.c --- a/packages/io/serial/current/src/common/serial.c +++ b/packages/io/serial/current/src/common/serial.c @@ -142,8 +142,8 @@ serial_write(cyg_io_handle_t handle, con size--; // Only count if actually sent! } } + (funs->start_xmit)(chan); // Start output as necessary cyg_drv_dsr_unlock(); - (funs->start_xmit)(chan); // Start output as necessary } cyg_drv_mutex_unlock(&cbuf->lock); return res; @@ -208,15 +208,15 @@ serial_read(cyg_io_handle_t handle, void } cyg_drv_dsr_unlock(); } +#ifdef XX_CYGDBG_DIAG_BUF cyg_drv_isr_lock(); -#ifdef XX_CYGDBG_DIAG_BUF - enable_diag_uart = 0; - HAL_CLOCK_READ(&_time); - _stime = (int)cyg_current_time(); - diag_printf("READ done - size: %d, len: %d, time: %x.%x\n", size, *len, _stime, _time); - enable_diag_uart = _enable; + enable_diag_uart = 0; + HAL_CLOCK_READ(&_time); + _stime = (int)cyg_current_time(); + diag_printf("READ done - size: %d, len: %d, time: %x.%x\n", size, *len, _stime, _time); + enable_diag_uart = _enable; + cyg_drv_isr_unlock(); #endif // CYGDBG_DIAG_BUF - cyg_drv_isr_unlock(); cyg_drv_mutex_unlock(&cbuf->lock); return res; } diff --git a/packages/io/serial/current/src/i386/pc_serial.c b/packages/io/serial/current/src/i386/pc_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/i386/pc_serial.c +++ /dev/null @@ -1,399 +0,0 @@ -//========================================================================== -// -// io/serial/i386/pc_serial.c -// -// i386 PC Serial I/O Interface Module (interrupt driven) -// for use with 8250s or 16550s. -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.0 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://sourceware.cygnus.com/ecos -// -// Software distributed under the License is distributed on an -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas, pjo -// Date: 1999-02-04 -// Purpose: AEB-1 Serial I/O module (interrupt driven version) -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_I386_PC - -#include "pc_serial.h" - -typedef struct pc_serial_info { - CYG_ADDRWORD base; - CYG_WORD int_num; - cyg_interrupt serial_interrupt; - cyg_handle_t serial_interrupt_handle; - enum { sNone = 0, - s8250, - s16450, - s16550, - s16550a - } deviceType ; - unsigned char _ier ; - unsigned char charsInTransmitter ; -} pc_serial_info; - -static bool pc_serial_init(struct cyg_devtab_entry *tab); -static bool pc_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo pc_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char pc_serial_getc(serial_channel *chan); -static bool pc_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void pc_serial_start_xmit(serial_channel *chan); -static void pc_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 pc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(pc_serial_funs, - pc_serial_putc, - pc_serial_getc, - pc_serial_set_config, - pc_serial_start_xmit, - pc_serial_stop_xmit - ); - -#ifdef CYGPKG_IO_SERIAL_I386_PC_SERIAL0 -static pc_serial_info pc_serial_info0 = { CYGNUM_IO_SERIAL_I386_PC_SERIAL0_IOBASE, - CYGNUM_IO_SERIAL_I386_PC_SERIAL0_INT}; -#if CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE > 0 -static unsigned char pc_serial_out_buf0[CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE]; -static unsigned char pc_serial_in_buf0[CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(pc_serial_channel0, - pc_serial_funs, - pc_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &pc_serial_out_buf0[0], sizeof(pc_serial_out_buf0), - &pc_serial_in_buf0[0], sizeof(pc_serial_in_buf0) - ); -#else -static SERIAL_CHANNEL(pc_serial_channel0, - pc_serial_funs, - pc_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(pc_serial_io0, - CYGDAT_IO_SERIAL_I386_PC_SERIAL0_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - pc_serial_init, - pc_serial_lookup, // Serial driver may need initializing - &pc_serial_channel0 - ); -#endif // CYGPKG_IO_SERIAL_I386_PC_SERIAL0 - -#ifdef CYGPKG_IO_SERIAL_I386_PC_SERIAL1 -static pc_serial_info pc_serial_info1 = { CYGNUM_IO_SERIAL_I386_PC_SERIAL1_IOBASE, - CYGNUM_IO_SERIAL_I386_PC_SERIAL1_INT}; -#if CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE > 0 -static unsigned char pc_serial_out_buf1[CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE]; -static unsigned char pc_serial_in_buf1[CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(pc_serial_channel1, - pc_serial_funs, - pc_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &pc_serial_out_buf1[0], sizeof(pc_serial_out_buf1), - &pc_serial_in_buf1[0], sizeof(pc_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(pc_serial_channel1, - pc_serial_funs, - pc_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_I386_PC_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(pc_serial_io1, - CYGDAT_IO_SERIAL_I386_PC_SERIAL1_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - pc_serial_init, - pc_serial_lookup, // Serial driver may need initializing - &pc_serial_channel1 - ); -#endif // CYGPKG_IO_SERIAL_I386_PC_SERIAL1 - - -void pc_outb(int port, int byte) ; -int pc_inb(int port) ; - - -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool pc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - pc_serial_info * port = (pc_serial_info *) chan->dev_priv; - unsigned short baud_divisor = select_baud[new_config->baud]; - unsigned char _lcr ; - if (baud_divisor == 0) return false; - -// Initialize the device, if necessary. First, find out what kind of device -// it is. Use a while() loop so that we can break to the next statement; -// otherwise we'd have an avalanche of if/else, which can become very -// difficult to understand. - while (init) - { port->deviceType = sNone ; - pc_outb(port->base + MCR, MCR_LOOP) ; - if (pc_inb(port->base + MSR) & 0xF0) - break ; - pc_outb(port->base + MCR, MCR_LOOP | 0xF) ; - if ((pc_inb(port->base + MSR) & 0xF0) != 0xF0) - break; -// So we have at least an 8250. - pc_outb(port->base + MCR, 0x00) ; - port->deviceType = s8250 ; -// Check for a scratch register; scratch register indicates 16450 or above. - pc_outb(port->base + SCR, 0x55) ; - if (pc_inb(port->base + SCR) != 0x55) - break ; - pc_outb(port->base + SCR, 0xAA) ; - if (pc_inb(port->base + SCR) != 0xAA) - break; -// Check for a FIFO - pc_outb(port->base + FCR, FCR_FE) ; - if ((pc_inb(port->base + ISR) & 0x80) == 0) - break ; - port->deviceType = s16550 ; // Note! 16550 fifo's don't work! - if ((pc_inb(port->base + ISR) & 0x40) == 0) - break ; - port->deviceType = s16550a ; // But 16550A fifos do. - break; - } - - port->_ier = pc_inb(port->base + IER); - pc_outb(port->base + IER, 0) ; // Disable port interrupts while changing hardware - _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | - select_stop_bits[new_config->stop] | - select_parity[new_config->parity]; - pc_outb(port->base + LCR, _lcr | LCR_DL) ; - pc_outb(port->base + MDL, baud_divisor >> 8) ; - pc_outb(port->base + LDL, baud_divisor & 0xFF) ; - pc_outb(port->base + LCR, _lcr) ; - - if (init) - { if (port->deviceType == s16550a) - pc_outb(port->base + FCR, FCR_FE | FCR_RFR | FCR_TFR | FCR_RT14); - else - pc_outb(port->base + FCR, 0); - - if (chan->out_cbuf.len != 0) - pc_outb(port->base + IER, IER_RCV) ; - else - pc_outb(port->base + IER, 0) ; -// port->_ier = MCR_INT | MCR_DTR | MCR_RTS ; -// port->_ier = IER_RCV | IER_LS | IER_MS ; - pc_outb(port->base + MCR, MCR_INT | MCR_DTR | MCR_RTS) ; - port->_ier = IER_RCV ; - } - - pc_outb(port->base + IER, port->_ier) ; - - if (new_config != &chan->config) - chan->config = *new_config; - - return true; -} - - - -// Function to initialize the device. Called at bootstrap time. -static bool pc_serial_init(struct cyg_devtab_entry * tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - pc_serial_info *pc_chan = (pc_serial_info *)chan->dev_priv; -#ifdef CYGDBG_IO_INIT - diag_printf("I386_PC SERIAL init - dev: %x.%d\n", pc_chan->base, pc_chan->int_num); -#endif - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (chan->out_cbuf.len != 0) { - cyg_drv_interrupt_create(pc_chan->int_num, - 99, // Priority - unused - (cyg_addrword_t)chan, // Data item passed to interrupt handler - pc_serial_ISR, - pc_serial_DSR, - &pc_chan->serial_interrupt_handle, - &pc_chan->serial_interrupt); - cyg_drv_interrupt_attach(pc_chan->serial_interrupt_handle); - cyg_drv_interrupt_unmask(pc_chan->int_num); - } - pc_serial_config_port(chan, &chan->config, true); - return true; -} - - - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo pc_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - - - - - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device, return 'false' when -// we've ran out of buffer space in the device itself. -static bool pc_serial_putc(serial_channel *chan, unsigned char c) -{ - int x = 0 ; - - pc_serial_info * port = (pc_serial_info *)chan->dev_priv; - -#if 0 -// Make sure the transmitter is empty. - if ((pc_inb(port->base + LSR) & LSR_THE) == 0) - return false ; -#else - // There isn't a status for FIFO "not full" from the '550, so we have to - // keep track of it ourselves. - if ((pc_inb(port->base + LSR) & LSR_THE) == 0) - { if ((port->deviceType == s16550a) && - (port->charsInTransmitter++ < PC16550_FIFO_TX_LENGTH)) - { /* We're cool to keep sending characters. */ - } - else - return false ; - } -#endif - pc_outb(port->base + THR, c); - - return true ; -} - - - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char pc_serial_getc(serial_channel *chan) -{ - pc_serial_info * port = (pc_serial_info *)chan->dev_priv; - - while ((pc_inb(port->base + LSR) & LSR_RSR) == 0) - ; - - return pc_inb(port->base + RHR) ; -} - - - -// Set up the device characteristics; baud rate, etc. -static bool pc_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return pc_serial_config_port(chan, config, false); -} - - - -// Enable the transmitter on the device -static void pc_serial_start_xmit(serial_channel *chan) -{ - pc_serial_info * port = (pc_serial_info *) chan->dev_priv; - pc_outb(port->base + IER, port->_ier |= IER_XMT) ; -} - - - -// Disable the transmitter on the device -static void pc_serial_stop_xmit(serial_channel * chan) -{ pc_serial_info * port = (pc_serial_info *) chan->dev_priv; - pc_outb(port->base + IER, port->_ier &= ~IER_XMT) ; -} - - - -// Serial I/O - low level interrupt handler (ISR) -static cyg_uint32 pc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *) data; - pc_serial_info * port = (pc_serial_info *) chan->dev_priv; - cyg_drv_interrupt_mask(port->int_num); - cyg_drv_interrupt_acknowledge(port->int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - - - -// Serial I/O - high level interrupt handler (DSR) -static void pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - pc_serial_info *port = (pc_serial_info *)chan->dev_priv; - unsigned char isr; - isr = pc_inb(port->base + ISR) & 0x0E; - if (isr == ISR_Tx) - { port->charsInTransmitter = 0 ; - (chan->callbacks->xmt_char)(chan); - } else if (isr == ISR_Rx) - { - // If we've got s16550a, then read all the characters in the fifo. - while (pc_inb(port->base + LSR) & LSR_RSR) - { - char c = pc_inb(port->base + RHR); - (chan->callbacks->rcv_char)(chan, c); - } - } - cyg_drv_interrupt_unmask(port->int_num); -} -#endif diff --git a/packages/io/serial/current/src/i386/pc_serial.h b/packages/io/serial/current/src/i386/pc_serial.h deleted file mode 100644 --- a/packages/io/serial/current/src/i386/pc_serial.h +++ /dev/null @@ -1,164 +0,0 @@ -#ifndef CYGONCE_I386_PC_SERIAL_H -#define CYGONCE_I386_PC_SERIAL_H - -// ==================================================================== -// -// pc_serial.h -// -// Device I/O - Description of i386/PC 8250/16550 serial hardware -// -// ==================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.0 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://sourceware.cygnus.com/ecos -// -// Software distributed under the License is distributed on an -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -// ==================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas, pjo -// Date: 1999-02-04 -// Purpose: Internal interfaces for serial I/O drivers -// Description: -// -//####DESCRIPTIONEND#### -// -// ==================================================================== - -// Description of serial ports on i386/PC 8250/16550 - - -// Receive control registers -#define RHR 0 // Receive holding register -#define ISR 2 // Interrupt status register -#define LSR 5 // Line status register -#define MSR 6 // Modem status register -#define SCR 7 // Scratch register - -// Transmit control registers -#define THR 0 // Transmit holding register -#define IER 1 // Interrupt enable register -#define FCR 2 // FIFO control register -#define LCR 3 // Line control register -#define MCR 4 // Modem control register -#define LDL 0 // LSB of baud rate -#define MDL 1 // MSB of baud rate - -// Interrupt Enable Register -#define IER_RCV 0x01 -#define IER_XMT 0x02 -#define IER_LS 0x04 -#define IER_MS 0x08 - -// Line Control Register -#define LCR_WL5 0x00 // Word length -#define LCR_WL6 0x01 -#define LCR_WL7 0x02 -#define LCR_WL8 0x03 -#define LCR_SB1 0x00 // Number of stop bits -#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words -#define LCR_SB2 0x04 -#define LCR_PN 0x00 // Parity mode - none -#define LCR_PE 0x0C // Parity mode - even -#define LCR_PO 0x08 // Parity mode - odd -#define LCR_PM 0x28 // Forced "mark" parity -#define LCR_PS 0x38 // Forced "space" parity -#define LCR_DL 0x80 // Enable baud rate latch - -// Line Status Register -#define LSR_RSR 0x01 -#define LSR_THE 0x20 - -// Modem Control Register -#define MCR_DTR 0x01 -#define MCR_RTS 0x02 -#define MCR_INT 0x0C // Enable interrupts -#define MCR_LOOP 0x10 // Loopback mode. - - -// FIFO control register -#define FCR_FE 0x01 // Fifo enable -#define FCR_RFR 0x02 // Receiver fifo reset -#define FCR_TFR 0x04 // Transmitter fifo reset -#define FCR_RT14 0xC0 -#define FCR_RT8 0x80 -#define FCR_RT4 0x40 -#define FCR_RT1 0x00 - -// FIFO lengths -#define PC16550_FIFO_TX_LENGTH (16 /*only for s16550a*/) -#define PC16550_FIFO_RX_LENGTH (16 /*only for s16550a*/) - -// Interrupt status register -#define ISR_Tx 0x02 -#define ISR_Rx 0x04 - -static unsigned char select_word_length[] = { - LCR_WL5, // 5 bits / word (char) - LCR_WL6, - LCR_WL7, - LCR_WL8 -}; - -static unsigned char select_stop_bits[] = { - 0, - LCR_SB1, // 1 stop bit - LCR_SB1_5, // 1.5 stop bit - LCR_SB2 // 2 stop bits -}; - -static unsigned char select_parity[] = { - LCR_PN, // No parity - LCR_PE, // Even parity - LCR_PO, // Odd parity - LCR_PM, // Mark parity - LCR_PS, // Space parity -}; - -// Baud rate values, based on raw 24MHz clock - -static unsigned short select_baud[] = { - 0, // Unused - 2304, // 50 - 1536, // 75 - 1047, // 110 - 857, // 134.5 - 768, // 150 - 576, // 200 - 384, // 300 - 192, // 600 - 96, // 1200 - 64, // 1800 - 48, // 2400 - 32, // 3600 - 24, // 4800 - 16, // 7200 - 12, // 9600 - 8, // 14400 - 6, // 19200 - 3, // 38400 - 2, // 57600 - 1, // 115200 - 0, // 230400 -}; - -#endif // CYGONCE_I386_PC_SERIAL_H diff --git a/packages/io/serial/current/src/mips/tx3904_serial.c b/packages/io/serial/current/src/mips/tx3904_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/mips/tx3904_serial.c +++ /dev/null @@ -1,731 +0,0 @@ -//========================================================================== -// -// tx3904_serial.c -// -// Serial device driver for TX3904 on-chip serial devices -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): nickg -// Contributors: nickg -// Date: 1999-03-3 -// Purpose: TX3904 serial device driver -// Description: TX3904 serial device driver -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include -#include - -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904 - -cyg_bool cyg_hal_is_break(char *buf, int size); -void cyg_hal_user_break( CYG_ADDRWORD *regs ); - -//------------------------------------------------------------------------- - -extern void diag_printf(const char *fmt, ...); - -//------------------------------------------------------------------------- -// Forward definitions - -static bool tx3904_serial_init(struct cyg_devtab_entry *tab); -static bool tx3904_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo tx3904_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char tx3904_serial_getc(serial_channel *chan); -static bool tx3904_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void tx3904_serial_start_xmit(serial_channel *chan); -static void tx3904_serial_stop_xmit(serial_channel *chan); - -#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE -static cyg_uint32 tx3904_serial_ISR(cyg_vector_t vector, cyg_addrword_t data, cyg_addrword_t *regs); -static void tx3904_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); -#endif - - -//------------------------------------------------------------------------- -// TX3904 serial line control register values: - -// Offsets to serial control registers from base -#define SERIAL_CR 0x00 -#define SERIAL_SR 0x04 -#define SERIAL_ICR 0x08 -#define SERIAL_ISR 0x0C -#define SERIAL_FCR 0x10 -#define SERIAL_BRG 0x14 -#define SERIAL_TXB 0x20 -#define SERIAL_RXB 0x30 - -// Status register bits -#define ISR_RXRDY 0x01 -#define ISR_TXRDY 0x02 -#define ISR_ERROR 0x04 - -// Control register bits -#define LCR_SB1 0x0000 -#define LCR_SB1_5 0x0000 -#define LCR_SB2 0x0004 -#define LCR_PN 0x0000 // Parity mode - none -#define LCR_PS 0x0000 // Forced "space" parity -#define LCR_PM 0x0000 // Forced "mark" parity -#define LCR_PE 0x0018 // Parity mode - even -#define LCR_PO 0x0010 // Parity mode - odd -#define LCR_WL5 0x0001 // not supported - use 7bit -#define LCR_WL6 0x0001 // not supported - use 7bit -#define LCR_WL7 0x0001 // 7 bit chars -#define LCR_WL8 0x0000 // 8 bit chars - -#define LCR_BRG 0x0020 // Select baud rate generator - -#define ICR_RXE 0x0001 // receive enable -#define ICR_TXE 0x0002 // transmit enable - -//------------------------------------------------------------------------- -// Tables to map input values to hardware settings - -static unsigned char select_word_length[] = { - LCR_WL5, // 5 bits / word (char) - LCR_WL6, - LCR_WL7, - LCR_WL8 -}; - -static unsigned char select_stop_bits[] = { - 0, - LCR_SB1, // 1 stop bit - LCR_SB1_5, // 1.5 stop bit - LCR_SB2 // 2 stop bits -}; - -static unsigned char select_parity[] = { - LCR_PN, // No parity - LCR_PE, // Even parity - LCR_PO, // Odd parity - LCR_PM, // Mark parity - LCR_PS, // Space parity -}; - -// The values in this table plug straight into the BRG register -// in the serial driver hardware. They comprise a baud rate divisor -// in the bottom 8 bits and a clock selector in the top 8 bits. -// These figures all come from Toshiba. - -#if (CYGHWR_HAL_MIPS_CPU_FREQ == 50) - -static unsigned short select_baud[] = { - 0, // Unused - 0, // 50 - 0, // 75 - 0, // 110 - 0, // 134.5 - 0, // 150 - 0, // 200 - 0, // 300 - 0x0300|20, // 600 - 0x0300|10, // 1200 - 0, // 1800 - 0x0300|05, // 2400 - 0, // 3600 - 0x0300|10, // 4800 - 0, // 7200 - 0x0200|05, // 9600 - 0, // 14400 - 0x0100|10, // 19200 - 0x0100|05, // 38400 - 0, // 57600 - 0, // 115200 - 0, // 230400 -}; - -#elif (CYGHWR_HAL_MIPS_CPU_FREQ == 66) - -static unsigned short select_baud[] = { - 0, // Unused - 0, // 50 - 0, // 75 - 0, // 110 - 0, // 134.5 - 0, // 150 - 0, // 200 - 0, // 300 - 0x0300|27, // 600 - 0x0200|54, // 1200 - 0, // 1800 - 0x0200|27, // 2400 - 0, // 3600 - 0x0100|54, // 4800 - 0, // 7200 - 0x0100|27, // 9600 - 0, // 14400 - 0x0000|54, // 19200 - 0x0000|27, // 38400 - 0, // 57600 - 0, // 115200 - 0, // 230400 -}; - -#else - -#error Unsupported CPU frequency - -#endif - -//------------------------------------------------------------------------- -// Info for each serial device controlled - -typedef struct tx3904_serial_info { - CYG_ADDRWORD base; - CYG_WORD int_num; - cyg_interrupt interrupt; - cyg_handle_t interrupt_handle; - cyg_uint8 input_char; - cyg_bool input_char_valid; - cyg_bool output_ready; - cyg_uint16 cur_baud; -} tx3904_serial_info; - -//------------------------------------------------------------------------- -// Callback functions exported by this driver - -static SERIAL_FUNS(tx3904_serial_funs, - tx3904_serial_putc, - tx3904_serial_getc, - tx3904_serial_set_config, - tx3904_serial_start_xmit, - tx3904_serial_stop_xmit - ); - -//------------------------------------------------------------------------- -// Hardware info for each serial line - -#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 -static tx3904_serial_info tx3904_serial_info0 = { - 0xFFFFF300, - CYGNUM_HAL_INTERRUPT_SIO_0 -}; -#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE > 0 -static unsigned char tx3904_serial_out_buf0[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE]; -static unsigned char tx3904_serial_in_buf0[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE]; -#endif -#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 - -#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 -static tx3904_serial_info tx3904_serial_info1 = { - 0xFFFFF400, - CYGNUM_HAL_INTERRUPT_SIO_1 -}; -#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE > 0 -static unsigned char tx3904_serial_out_buf1[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE]; -static unsigned char tx3904_serial_in_buf1[CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE]; -#endif -#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 - -//------------------------------------------------------------------------- -// Channel descriptions: - -#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE -#define SIZEOF_BUF(_x_) 0 -#else -#define SIZEOF_BUF(_x_) sizeof(_x_) -#endif - -#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 -#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BUFSIZE > 0 -static SERIAL_CHANNEL_USING_INTERRUPTS(tx3904_serial_channel0, - tx3904_serial_funs, - tx3904_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &tx3904_serial_out_buf0[0], - SIZEOF_BUF(tx3904_serial_out_buf0), - &tx3904_serial_in_buf0[0], - SIZEOF_BUF(tx3904_serial_in_buf0) - ); -#else -static SERIAL_CHANNEL(tx3904_serial_channel0, - tx3904_serial_funs, - tx3904_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif -#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 - -#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 -#if CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BUFSIZE > 0 -static SERIAL_CHANNEL_USING_INTERRUPTS(tx3904_serial_channel1, - tx3904_serial_funs, - tx3904_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &tx3904_serial_out_buf1[0], - SIZEOF_BUF(tx3904_serial_out_buf1), - &tx3904_serial_in_buf1[0], - SIZEOF_BUF(tx3904_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(tx3904_serial_channel1, - tx3904_serial_funs, - tx3904_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_TX39_JMR3904_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif -#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 - -//------------------------------------------------------------------------- -// And finally, the device table entries: - -#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 -DEVTAB_ENTRY(tx3904_serial_io0, - CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL0_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - tx3904_serial_init, - tx3904_serial_lookup, // Serial driver may need initializing - &tx3904_serial_channel0 - ); -#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 - -#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 -DEVTAB_ENTRY(tx3904_serial_io1, - CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL1_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - tx3904_serial_init, - tx3904_serial_lookup, // Serial driver may need initializing - &tx3904_serial_channel1 - ); -#endif // CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL1 - -// ------------------------------------------------------------------------ -// Delay for some number of character times. This is based on the baud -// rate currently set. We use the numbers that plug in to the BRG -// clock select and divider to control two loops. The innermost delay -// loop uses a count that is derived from dividing the CPU frequency -// by the BRG granularity (and we then add 1 to compensate for any -// rounding). This gives the number of cycles that the innermost loop -// must consume. For the sake of simplicity we assume that this loop -// will take 1 cycle per loop, which is roughly true in optimized -// code. - -void delay_char_time(tx3904_serial_info *tx3904_chan, int n) -{ - static cyg_uint16 clock_val[4] = { 4, 16, 64, 256 }; - cyg_uint16 baud_val = select_baud[tx3904_chan->cur_baud]; - cyg_count32 clock_loop = clock_val[baud_val>>8]; - cyg_count32 div_loop = baud_val & 0xFF; - cyg_count32 bit_time = ((CYGHWR_HAL_MIPS_CPU_FREQ_ACTUAL)/(2457600)) + 1; - - n *= 11; // allow for start and stop bits and 8 data bits - - while( n-- ) - { - cyg_count32 i,j,k; - - for( i = 0; i < clock_loop; i++ ) - for( j = 0; j < div_loop; j++ ) - for( k = 0; k < bit_time; k++ ) - continue; - } -} - -//------------------------------------------------------------------------- - -static bool -tx3904_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; - cyg_uint16 cr = 0; - cyg_uint16 icr = 0; - cyg_uint16 baud_divisor = select_baud[new_config->baud]; - - if (baud_divisor == 0) - return false; // Invalid baud rate selected - - // set up other config values: - - cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; - cr |= select_stop_bits[new_config->stop]; - cr |= select_parity[new_config->parity]; - - // Source transfer clock from BRG - cr |= LCR_BRG; - -#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE - // Enable RX interrupts only at present -#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0 - if ((chan->out_cbuf.len != 0) || (chan == &tx3904_serial_channel0)) { -#else - if (chan->out_cbuf.len != 0) { -#endif - icr |= ICR_RXE; - } -#endif - - // Avoid any interrupts while we are fiddling with the line parameters. - cyg_drv_interrupt_mask(tx3904_chan->int_num); - - - // In theory we should wait here for the transmitter to drain the - // FIFO so we dont change the line parameters with characters - // unsent. Unfortunately the TX39 serial devices do not allow us - // to discover when the FIFO is empty. - - delay_char_time(tx3904_chan, 8); - - // Disable device entirely. -// HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_CR, 0); -// HAL_WRITE_UINT8(tx3904_chan->base+SERIAL_ICR, 0); - - // Reset the FIFOs - - HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_FCR, 7); - HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_FCR, 0); - - // Set up baud rate - - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_BRG, baud_divisor ); - - // Write CR into hardware - HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_CR, cr); - - // Write ICR into hardware - HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_ICR, icr); - - // Re-enable interrupts. - cyg_drv_interrupt_unmask(tx3904_chan->int_num); - - // Save current baud rate - tx3904_chan->cur_baud = new_config->baud; - - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -//------------------------------------------------------------------------- -// Function to initialize the device. Called at bootstrap time. - -bool tx3904_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; - - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - - tx3904_chan->cur_baud = CYGNUM_SERIAL_BAUD_38400; - -#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE - if (chan->out_cbuf.len != 0) { - // Install and enable the interrupt - cyg_drv_interrupt_create(tx3904_chan->int_num, - 4, // Priority - (cyg_addrword_t)chan, // Data item passed to interrupt handler - (cyg_ISR_t *)tx3904_serial_ISR, - tx3904_serial_DSR, - &tx3904_chan->interrupt_handle, - &tx3904_chan->interrupt); - cyg_drv_interrupt_attach(tx3904_chan->interrupt_handle); - cyg_drv_interrupt_unmask(tx3904_chan->int_num); - } -#endif - - tx3904_serial_config_port(chan, &chan->config, true); - - return true; -} - -//------------------------------------------------------------------------- -// This routine is called when the device is "looked" up (i.e. attached) - -static Cyg_ErrNo -tx3904_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -//------------------------------------------------------------------------- -// Return 'true' if character is sent to device - -bool -tx3904_serial_putc(serial_channel *chan, unsigned char c) -{ - tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; - cyg_uint16 isr; - - HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - - if( isr & ISR_TXRDY ) - { - HAL_WRITE_UINT8( tx3904_chan->base+SERIAL_TXB, c ); - - isr &= ~ISR_TXRDY; - - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - - return true; - } - else return false; -} - -//------------------------------------------------------------------------- - -unsigned char -tx3904_serial_getc(serial_channel *chan) -{ - unsigned char c; - tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; - cyg_uint16 isr; - - do - { - HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - - // Eliminate any RX errors - if( isr & ISR_ERROR ) - { - cyg_uint16 sr = 0; - - isr &= ISR_ERROR; - -// HAL_READ_UINT16( tx3904_chan->base+SERIAL_SR, sr ); - - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_SR, sr ); - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - } - - } while( (isr & ISR_RXRDY) != ISR_RXRDY ); - - HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, c ); - - isr &= ~ISR_RXRDY; - - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - - return c; -} - -//------------------------------------------------------------------------- - -bool -tx3904_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return tx3904_serial_config_port(chan, config, false); -} - -//------------------------------------------------------------------------- -// Enable the transmitter on the device - -static void -tx3904_serial_start_xmit(serial_channel *chan) -{ -#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE - tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; - cyg_uint16 icr; - - HAL_READ_UINT16( tx3904_chan->base+SERIAL_ICR, icr ); - - icr |= ICR_TXE; - - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ICR, icr ); -#endif -} - -//------------------------------------------------------------------------- -// Disable the transmitter on the device - -static void -tx3904_serial_stop_xmit(serial_channel *chan) -{ -#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE - tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; - cyg_uint16 icr; - - HAL_READ_UINT16( tx3904_chan->base+SERIAL_ICR, icr ); - - icr &= ~ICR_TXE; - - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ICR, icr ); -#endif -} - -//------------------------------------------------------------------------- -// Serial I/O - low level interrupt handlers (ISR) - -#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE - -static cyg_uint32 -tx3904_serial_ISR(cyg_vector_t vector, cyg_addrword_t data, cyg_addrword_t *regs) -{ - serial_channel *chan = (serial_channel *)data; - tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; - cyg_uint8 isr; - cyg_uint32 result = 0; - - cyg_drv_interrupt_mask(tx3904_chan->int_num); - cyg_drv_interrupt_acknowledge(tx3904_chan->int_num); - - HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - - // Eliminate any RX errors - if( isr & ISR_ERROR ) - { - cyg_uint16 sr = 0; - - isr &= ~ISR_ERROR; - - HAL_READ_UINT16( tx3904_chan->base+SERIAL_SR, sr ); - - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_SR, 0 ); - } - - // Check for a TX interrupt and set the flag if so. - if( isr & ISR_TXRDY ) - { - isr &= ~ISR_TXRDY; - - tx3904_chan->output_ready = true; - - result |= CYG_ISR_CALL_DSR; // Cause DSR to be run - } - - - // Check here for an RX interrupt and fetch the character. If it - // is a ^C then call into GDB stub to handle it. - - if( isr & ISR_RXRDY ) - { - cyg_uint8 rxb; - HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, rxb ); - - isr &= ~ISR_RXRDY; - - if( cyg_hal_is_break( &rxb , 1 ) ) - cyg_hal_user_break( regs ); - else - { - tx3904_chan->input_char = rxb; - tx3904_chan->input_char_valid = true; - result |= CYG_ISR_CALL_DSR; // Cause DSR to be run - } - - } - - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - - return result; -} - - -#endif - -//------------------------------------------------------------------------- -// Serial I/O - high level interrupt handler (DSR) - -#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE - -static void -tx3904_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv; - cyg_uint8 isr; - - HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - - if( tx3904_chan->input_char_valid ) - { - (chan->callbacks->rcv_char)(chan, tx3904_chan->input_char); - - tx3904_chan->input_char_valid = false; - -#if 0 - // And while we are here, pull any further characters out of the - // FIFO. This should help to reduce the interrupt rate. - - HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - - while( isr & ISR_RXRDY ) - { - cyg_uint8 rxb; - HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, rxb ); - - (chan->callbacks->rcv_char)(chan, rxb); - - isr &= ~ISR_RXRDY; - - HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr ); - } -#endif - - } - - if( tx3904_chan->output_ready ) - { - (chan->callbacks->xmt_char)(chan); - - tx3904_chan->output_ready = false; - } - - cyg_drv_interrupt_unmask(tx3904_chan->int_num); -} - -#endif -#endif // CYGPKG_IO_SERIAL_TX39_JMR3904 - -//------------------------------------------------------------------------- -// EOF tx3904_serial.c diff --git a/packages/io/serial/current/src/mips/vrc4373_serial.c b/packages/io/serial/current/src/mips/vrc4373_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/mips/vrc4373_serial.c +++ /dev/null @@ -1,466 +0,0 @@ -//========================================================================== -// -// io/serial/mips/vrc4373_serial.c -// -// Mips VRC4373 Serial I/O Interface Module (interrupt driven) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-04-15 -// Purpose: VRC4373 Serial I/O module (interrupt driven version) -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include -#include -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373 - -#include "vrc4373_serial.h" - -#if defined(CYGPKG_HAL_MIPS_LSBFIRST) -#define VRC4373_SCC_BASE 0xC1000000 -#elif defined(CYGPKG_HAL_MIPS_MSBFIRST) -#define VRC4373_SCC_BASE 0xC1000003 -#else -#error MIPS endianness not defined by configuration -#endif - -#define VRC4373_SCC_INT CYGNUM_HAL_INTERRUPT_DUART -#define SCC_CHANNEL_A 4 -#define SCC_CHANNEL_B 0 - -extern void diag_printf(const char *fmt, ...); - -typedef struct vrc4373_serial_info { - CYG_ADDRWORD base; - unsigned char regs[16]; // Known register state (since hardware is write-only!) -} vrc4373_serial_info; - -static bool vrc4373_serial_init(struct cyg_devtab_entry *tab); -static bool vrc4373_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo vrc4373_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char vrc4373_serial_getc(serial_channel *chan); -static bool vrc4373_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void vrc4373_serial_start_xmit(serial_channel *chan); -static void vrc4373_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 vrc4373_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void vrc4373_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(vrc4373_serial_funs, - vrc4373_serial_putc, - vrc4373_serial_getc, - vrc4373_serial_set_config, - vrc4373_serial_start_xmit, - vrc4373_serial_stop_xmit - ); - -#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL0 -static vrc4373_serial_info vrc4373_serial_info0 = {VRC4373_SCC_BASE+SCC_CHANNEL_A}; -#if CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BUFSIZE > 0 -static unsigned char vrc4373_serial_out_buf0[CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BUFSIZE]; -static unsigned char vrc4373_serial_in_buf0[CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(vrc4373_serial_channel0, - vrc4373_serial_funs, - vrc4373_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &vrc4373_serial_out_buf0[0], sizeof(vrc4373_serial_out_buf0), - &vrc4373_serial_in_buf0[0], sizeof(vrc4373_serial_in_buf0) - ); -#else -static SERIAL_CHANNEL(vrc4373_serial_channel0, - vrc4373_serial_funs, - vrc4373_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(vrc4373_serial_io0, - CYGDAT_IO_SERIAL_MIPS_VRC4373_SERIAL0_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - vrc4373_serial_init, - vrc4373_serial_lookup, // Serial driver may need initializing - &vrc4373_serial_channel0 - ); -#endif // CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL0 - -#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL1 -static vrc4373_serial_info vrc4373_serial_info1 = {VRC4373_SCC_BASE+SCC_CHANNEL_B}; -#if CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BUFSIZE > 0 -static unsigned char vrc4373_serial_out_buf1[CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BUFSIZE]; -static unsigned char vrc4373_serial_in_buf1[CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(vrc4373_serial_channel1, - vrc4373_serial_funs, - vrc4373_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &vrc4373_serial_out_buf1[0], sizeof(vrc4373_serial_out_buf1), - &vrc4373_serial_in_buf1[0], sizeof(vrc4373_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(vrc4373_serial_channel1, - vrc4373_serial_funs, - vrc4373_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MIPS_VRC4373_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(vrc4373_serial_io1, - CYGDAT_IO_SERIAL_MIPS_VRC4373_SERIAL1_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - vrc4373_serial_init, - vrc4373_serial_lookup, // Serial driver may need initializing - &vrc4373_serial_channel1 - ); -#endif // CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL1 - -static cyg_interrupt vrc4373_serial_interrupt; -static cyg_handle_t vrc4373_serial_interrupt_handle; - -// Table which maps hardware channels (A,B) to software ones -struct serial_channel *vrc4373_chans[] = { -#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL0 // Hardware channel A - &vrc4373_serial_channel0, -#else - 0, -#endif -#ifdef CYGPKG_IO_SERIAL_MIPS_VRC4373_SERIAL1 // Hardware channel B - &vrc4373_serial_channel1, -#else - 0, -#endif -}; - -// Support functions which access the serial device. Note that this chip requires -// a substantial delay after each access. - -#define SCC_DELAY 100 -inline static void -scc_delay(void) -{ - int i; - for (i = 0; i < SCC_DELAY; i++) ; -} - -inline static void -scc_write_reg(volatile unsigned char *reg, unsigned char val) -{ - scc_delay(); - *reg = val; -} - -inline static unsigned char -scc_read_reg(volatile unsigned char *reg) -{ - unsigned char val; - scc_delay(); - val = *reg; - return (val); -} - -inline static unsigned char -scc_read_ctl(volatile struct serial_port *port, int reg) -{ - if (reg != 0) { - scc_write_reg(&port->scc_ctl, reg); - } - return (scc_read_reg(&port->scc_ctl)); -} - -inline static void -scc_write_ctl(volatile struct serial_port *port, int reg, unsigned char val) -{ - if (reg != 0) { - scc_write_reg(&port->scc_ctl, reg); - } - scc_write_reg(&port->scc_ctl, val); -} - -inline static unsigned char -scc_read_dat(volatile struct serial_port *port) -{ - return (scc_read_reg(&port->scc_dat)); -} - -inline static void -scc_write_dat(volatile struct serial_port *port, unsigned char val) -{ - scc_write_reg(&port->scc_dat, val); -} - -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool -vrc4373_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; - cyg_int32 baud_rate = select_baud[new_config->baud]; - cyg_int32 baud_divisor; - unsigned char *regs = &vrc4373_chan->regs[0]; - if (baud_rate == 0) return false; - // Compute state of registers. The register/control state needs to be kept in - // the shadow variable 'regs' because the hardware registers can only be written, - // not read (in general). - if (init) { - // Insert appropriate resets? - if (chan->out_cbuf.len != 0) { - regs[R1] = WR1_IntAllRx; - regs[R9] = WR9_MIE | WR9_NoVector; - } else { - regs[R1] = 0; - regs[R9] = 0; - } - // Clocks are from the baud rate generator - regs[R11] = WR11_TRxCBR | WR11_TRxCOI | WR11_TxCBR | WR11_RxCBR; - regs[R14] = WR14_BRenable | WR14_BRSRC; - regs[R10] = 0; // Unused in this [async] mode - regs[R15] = 0; - } - regs[R3] = WR3_RxEnable | select_word_length_WR3[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; - regs[R4] = WR4_X16CLK | select_stop_bits[new_config->stop] | select_parity[new_config->parity]; - regs[R5] = WR5_TxEnable | select_word_length_WR5[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; - baud_divisor = BRTC(baud_rate); - regs[R12] = baud_divisor & 0xFF; - regs[R13] = baud_divisor >> 8; - // Now load the registers - scc_write_ctl(port, R4, regs[R4]); - scc_write_ctl(port, R10, regs[R10]); - scc_write_ctl(port, R3, regs[R3] & ~WR3_RxEnable); - scc_write_ctl(port, R5, regs[R5] & ~WR5_TxEnable); - scc_write_ctl(port, R1, regs[R1]); - scc_write_ctl(port, R9, regs[R9]); - scc_write_ctl(port, R11, regs[R11]); - scc_write_ctl(port, R12, regs[R12]); - scc_write_ctl(port, R13, regs[R13]); - scc_write_ctl(port, R14, regs[R14]); - scc_write_ctl(port, R15, regs[R15]); - scc_write_ctl(port, R3, regs[R3]); - scc_write_ctl(port, R5, regs[R5]); - // Update configuration - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -vrc4373_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; - static bool init = false; -#ifdef CYGDBG_IO_INIT - diag_printf("VRC4373 SERIAL init '%s' - dev: %x\n", tab->name, vrc4373_chan->base); -#endif - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (!init && chan->out_cbuf.len != 0) { - init = true; - cyg_drv_interrupt_create(VRC4373_SCC_INT, - 99, - (cyg_addrword_t)VRC4373_SCC_BASE+SCC_CHANNEL_A, - vrc4373_serial_ISR, - vrc4373_serial_DSR, - &vrc4373_serial_interrupt_handle, - &vrc4373_serial_interrupt); - cyg_drv_interrupt_attach(vrc4373_serial_interrupt_handle); - cyg_drv_interrupt_unmask(VRC4373_SCC_INT); - } - vrc4373_serial_config_port(chan, &chan->config, true); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -vrc4373_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -vrc4373_serial_putc(serial_channel *chan, unsigned char c) -{ - vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; - if (scc_read_ctl(port, R0) & RR0_TxEmpty) { -// Transmit buffer is empty - scc_write_dat(port, c); - return true; - } else { -// No space - return false; - } -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -vrc4373_serial_getc(serial_channel *chan) -{ - unsigned char c; - vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; - while ((scc_read_ctl(port, R0) & RR0_RxAvail) == 0) ; // Wait for char - c = scc_read_dat(port); - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -vrc4373_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return vrc4373_serial_config_port(chan, config, false); -} - -// Enable the transmitter on the device -static void -vrc4373_serial_start_xmit(serial_channel *chan) -{ - vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; - if ((vrc4373_chan->regs[R1] & WR1_TxIntEnab) == 0) { - CYG_INTERRUPT_STATE old; - HAL_DISABLE_INTERRUPTS(old); - vrc4373_chan->regs[R1] |= WR1_TxIntEnab; // Enable Tx interrupt - scc_write_ctl(port, R1, vrc4373_chan->regs[R1]); - (chan->callbacks->xmt_char)(chan); // Send first character to start xmitter - HAL_RESTORE_INTERRUPTS(old); - } -} - -// Disable the transmitter on the device -static void -vrc4373_serial_stop_xmit(serial_channel *chan) -{ - vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; - if ((vrc4373_chan->regs[R1] & WR1_TxIntEnab) != 0) { - CYG_INTERRUPT_STATE old; - HAL_DISABLE_INTERRUPTS(old); - vrc4373_chan->regs[R1] &= ~WR1_TxIntEnab; // Disable Tx interrupt - scc_write_ctl(port, R1, vrc4373_chan->regs[R1]); - HAL_RESTORE_INTERRUPTS(old); - } -} - -// Serial I/O - low level interrupt handler (ISR) -static cyg_uint32 -vrc4373_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - cyg_drv_interrupt_mask(VRC4373_SCC_INT); - cyg_drv_interrupt_acknowledge(VRC4373_SCC_INT); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -inline static void -vrc4373_int(serial_channel *chan, unsigned char stat) -{ - vrc4373_serial_info *vrc4373_chan = (vrc4373_serial_info *)chan->dev_priv; - volatile struct serial_port *port = (volatile struct serial_port *)vrc4373_chan->base; - // Note: 'stat' value is interrupt status register, shifted into "B" position - if (stat & RR3_BRxIP) { - // Receive interrupt - unsigned char c; - c = scc_read_dat(port); - (chan->callbacks->rcv_char)(chan, c); - } - if (stat & RR3_BTxIP) { - // Transmit interrupt - (chan->callbacks->xmt_char)(chan); - } - if (stat & RR3_BExt) { - // Status interrupt (parity error, framing error, etc) - } -} - -// Serial I/O - high level interrupt handler (DSR) -// Note: This device presents a single interrupt for both channels. Thus the -// interrupt handler has to query the device and decide which channel needs service. -// Additionally, more than one interrupt condition may be present so this needs to -// be done in a loop until all interrupt requests have been handled. -// Also note that the hardware is rather broken. The interrupt status needs to -// be read using only channel A (pointed to by 'data') -static void -vrc4373_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan; - volatile struct serial_port *port = (volatile struct serial_port *)data; - unsigned char stat; - while (true) { - stat = scc_read_ctl(port, R3); - if (stat & (RR3_AExt | RR3_ATxIP | RR3_ARxIP)) { - chan = vrc4373_chans[0]; // Hardware channel A - vrc4373_int(chan, stat>>3); // Handle interrupt - } else if (stat & (RR3_BExt | RR3_BTxIP | RR3_BRxIP)) { - chan = vrc4373_chans[1]; // Hardware channel A - vrc4373_int(chan, stat); // Handle interrupt - } else { - // No more interrupts, all done - break; - } - } - cyg_drv_interrupt_unmask(VRC4373_SCC_INT); -} -#endif diff --git a/packages/io/serial/current/src/mips/vrc4373_serial.h b/packages/io/serial/current/src/mips/vrc4373_serial.h deleted file mode 100644 --- a/packages/io/serial/current/src/mips/vrc4373_serial.h +++ /dev/null @@ -1,335 +0,0 @@ -#ifndef CYGONCE_MIPS_VRC4373_SERIAL_H -#define CYGONCE_MIPS_VRC4373_SERIAL_H - -// ==================================================================== -// -// aeb_serial.h -// -// Device I/O - Description of Mips VRC4373 serial hardware -// -// ==================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -// ==================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-04-15 -// Purpose: Internal interfaces for serial I/O drivers -// Description: -// -//####DESCRIPTIONEND#### -// -// ==================================================================== - -// Description of serial ports on Mips VRC4373 -// Based on Zilog 85C30 SCC - -struct serial_port { - unsigned char _byte[16]; -}; - -#define scc_ctl _byte[0] -#define scc_dat _byte[8] - -#define R0 0 /* Register selects */ -#define R1 1 -#define R2 2 -#define R3 3 -#define R4 4 -#define R5 5 -#define R6 6 -#define R7 7 -#define R8 8 -#define R9 9 -#define R10 10 -#define R11 11 -#define R12 12 -#define R13 13 -#define R14 14 -#define R15 15 - -/* Write Register 0 */ -#define WR0_NullCode 0x00 /* Null Code */ -#define WR0_PointHigh 0x08 /* Select upper half of registers */ -#define WR0_ResExtInt 0x10 /* Reset Ext. Status Interrupts */ -#define WR0_SendAbort 0x18 /* HDLC Abort */ -#define WR0_ResRxIntFC 0x20 /* Reset RxINT on First Character */ -#define WR0_ResTxP 0x28 /* Reset TxINT Pending */ -#define WR0_ErrReset 0x30 /* Error Reset */ -#define WR0_ResHiIUS 0x38 /* Reset highest IUS */ - -#define WR0_ResRxCRC 0x40 /* Reset Rx CRC Checker */ -#define WR0_ResTxCRC 0x80 /* Reset Tx CRC Checker */ -#define WR0_ResEOMlatch 0xC0 /* Reset EOM latch */ - -/* Write Register 1 */ - -#define WR1_ExtIntEnab 0x01 /* Ext Int Enable */ -#define WR1_TxIntEnab 0x02 /* Tx Int Enable */ -#define WR1_ParSpec 0x04 /* Parity is special condition */ - -#define WR1_RxIntDisab 0x00 /* Rx Int Disable */ -#define WR1_RxIntFCE 0x08 /* Rx Int on First Character Only or Error */ -#define WR1_IntAllRx 0x10 /* Int on all Rx Characters or error */ -#define WR1_IntErrRx 0x18 /* Int on error only */ - -#define WR1_WtRdyRT 0x20 /* Wait/Ready on R/T */ -#define WR1_WtFnRdyFn 0x40 /* Wait/FN/Ready FN */ -#define WR1_WtRdyEnab 0x80 /* Wait/Ready Enable */ - -/* Write Register #2 (Interrupt Vector) */ - -/* Write Register 3 */ - -#define WR3_RxEnable 0x01 /* Rx Enable */ -#define WR3_SyncInhibit 0x02 /* Sync Character Load Inhibit */ -#define WR3_AddrSearch 0x04 /* Address Search Mode (SDLC) */ -#define WR3_RxCRC_ENAB 0x08 /* Rx CRC Enable */ -#define WR3_EntHuntMode 0x10 /* Enter Hunt Mode */ -#define WR3_AutoEnab 0x20 /* Auto Enables */ -#define WR3_Rx5 0x00 /* Rx 5 Bits/Character */ -#define WR3_Rx7 0x40 /* Rx 7 Bits/Character */ -#define WR3_Rx6 0x80 /* Rx 6 Bits/Character */ -#define WR3_Rx8 0xc0 /* Rx 8 Bits/Character */ -#define WR3_RxNbitsMask 0xc0 - -/* Write Register 4 */ - -#define WR4_ParityEn 0x01 /* Parity Enable */ -#define WR4_ParityEven 0x02 /* Parity Even/Odd* */ - -#define WR4_SyncEnable 0x00 /* Sync Modes Enable */ -#define WR4_SB1 0x04 /* 1 stop bit/char */ -#define WR4_SB15 0x08 /* 1.5 stop bits/char */ -#define WR4_SB2 0x0c /* 2 stop bits/char */ -#define WR4_SB_MASK 0x0c - -#define WR4_Monsync 0x00 /* 8 Bit Sync character */ -#define WR4_Bisync 0x10 /* 16 bit sync character */ -#define WR4_SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */ -#define WR4_EXtSync 0x30 /* External Sync Mode */ - -#define WR4_X1CLK 0x00 /* x1 clock mode */ -#define WR4_X16CLK 0x40 /* x16 clock mode */ -#define WR4_X32CLK 0x80 /* x32 clock mode */ -#define WR4_X64CLK 0xC0 /* x64 clock mode */ -#define WR4_XCLK_MASK 0xC0 - -/* Write Register 5 */ - -#define WR5_TxCRCEnab 0x01 /* Tx CRC Enable */ -#define WR5_RTS 0x02 /* RTS */ -#define WR5_SDLC_CRC 0x04 /* SDLC/CRC-16 */ -#define WR5_TxEnable 0x08 /* Tx Enable */ -#define WR5_SendBreak 0x10 /* Send Break */ -#define WR5_Tx5 0x00 /* Tx 5 bits (or less)/character */ -#define WR5_Tx7 0x20 /* Tx 7 bits/character */ -#define WR5_Tx6 0x40 /* Tx 6 bits/character */ -#define WR5_Tx8 0x60 /* Tx 8 bits/character */ -#define WR5_TxNbitsMask 0x60 -#define WR5_DTR 0x80 /* DTR */ - -/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */ - -/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ - -/* Write Register 8 (transmit buffer) */ - -/* Write Register 9 (Master interrupt control) */ -#define WR9_VIS 0x01 /* Vector Includes Status */ -#define WR9_NoVector 0x02 /* No Vector */ -#define WR9_DLC 0x04 /* Disable Lower Chain */ -#define WR9_MIE 0x08 /* Master Interrupt Enable */ -#define WR9_StatHi 0x10 /* Status high */ -#define WR9_NoReset 0x00 /* No reset on write to R9 */ -#define WR9_ResetB 0x40 /* Reset channel B */ -#define WR9_ResetA 0x80 /* Reset channel A */ -#define WR9_HwReset 0xc0 /* Force hardware reset */ - -/* Write Register 10 (misc control bits) */ -#define WR10_Bit6 0x01 /* 6 bit/8bit sync */ -#define WR10_LoopMode 0x02 /* SDLC Loop mode */ -#define WR10_AbrtUnder 0x04 /* Abort/flag on SDLC xmit underrun */ -#define WR10_MarkIdle 0x08 /* Mark/flag on idle */ -#define WR10_GAOP 0x10 /* Go active on poll */ -#define WR10_NRZ 0x00 /* NRZ mode */ -#define WR10_NRZI 0x20 /* NRZI mode */ -#define WR10_FM1 0x40 /* FM1 (transition = 1) */ -#define WR10_FM0 0x60 /* FM0 (transition = 0) */ -#define WR10_CRCPS 0x80 /* CRC Preset I/O */ - -/* Write Register 11 (Clock Mode control) */ -#define WR11_TRxCXT 0x00 /* TRxC = Xtal output */ -#define WR11_TRxCTC 0x01 /* TRxC = Transmit clock */ -#define WR11_TRxCBR 0x02 /* TRxC = BR Generator Output */ -#define WR11_TRxCDP 0x03 /* TRxC = DPLL output */ -#define WR11_TRxCOI 0x04 /* TRxC O/I */ -#define WR11_TxCRTxCP 0x00 /* Transmit clock = RTxC pin */ -#define WR11_TxCTRxCP 0x08 /* Transmit clock = TRxC pin */ -#define WR11_TxCBR 0x10 /* Transmit clock = BR Generator output */ -#define WR11_TxCDPLL 0x18 /* Transmit clock = DPLL output */ -#define WR11_RxCRTxCP 0x00 /* Receive clock = RTxC pin */ -#define WR11_RxCTRxCP 0x20 /* Receive clock = TRxC pin */ -#define WR11_RxCBR 0x40 /* Receive clock = BR Generator output */ -#define WR11_RxCDPLL 0x60 /* Receive clock = DPLL output */ -#define WR11_RTxCX 0x80 /* RTxC Xtal/No Xtal */ - -/* Write Register 12 (lower byte of baud rate generator time constant) */ - -/* Write Register 13 (upper byte of baud rate generator time constant) */ - -/* Write Register 14 (Misc control bits) */ -#define WR14_BRenable 0x01 /* Baud rate generator enable */ -#define WR14_BRSRC 0x02 /* Baud rate generator source */ -#define WR14_DTRreq 0x04 /* DTR/Request function */ -#define WR14_AutoEcho 0x08 /* Auto Echo */ -#define WR14_LoopBack 0x10 /* Local loopback */ -#define WR14_Search 0x20 /* Enter search mode */ -#define WR14_RMC 0x40 /* Reset missing clock */ -#define WR14_NoDPLL 0x60 /* Disable DPLL */ -#define WR14_SSBR 0x80 /* Set DPLL source = BR generator */ -#define WR14_SSRTxC 0xa0 /* Set DPLL source = RTxC */ -#define WR14_SFMM 0xc0 /* Set FM mode */ -#define WR14_SNRZI 0xe0 /* Set NRZI mode */ - -/* Write Register 15 (external/status interrupt control) */ -#define WR15_ZCIE 0x02 /* Zero count IE */ -#define WR15_DCDIE 0x08 /* DCD IE */ -#define WR15_SYNCIE 0x10 /* Sync/hunt IE */ -#define WR15_CTSIE 0x20 /* CTS IE */ -#define WR15_TxUIE 0x40 /* Tx Underrun/EOM IE */ -#define WR15_BRKIE 0x80 /* Break/Abort IE */ - -/* Read Register 0 */ -#define RR0_RxAvail 0x01 /* Rx Character Available */ -#define RR0_Zcount 0x02 /* Zero count */ -#define RR0_TxEmpty 0x04 /* Tx Buffer empty */ -#define RR0_DCD 0x08 /* DCD */ -#define RR0_SyncHunt 0x10 /* Sync/hunt */ -#define RR0_CTS 0x20 /* CTS */ -#define RR0_TxEOM 0x40 /* Tx underrun */ -#define RR0_BrkAbort 0x80 /* Break/Abort */ - -/* Read Register 1 */ -#define RR1_AllSent 0x01 /* All sent */ -/* Residue Data for 8 Rx bits/char programmed */ -#define RR1_RES3 0x08 /* 0/3 */ -#define RR1_RES4 0x04 /* 0/4 */ -#define RR1_RES5 0x0c /* 0/5 */ -#define RR1_RES6 0x02 /* 0/6 */ -#define RR1_RES7 0x0a /* 0/7 */ -#define RR1_RES8 0x06 /* 0/8 */ -#define RR1_RES18 0x0e /* 1/8 */ -#define RR1_RES28 0x00 /* 2/8 */ -/* Special Rx Condition Interrupts */ -#define RR1_PariryError 0x10 /* Parity error */ -#define RR1_RxOverrun 0x20 /* Rx Overrun Error */ -#define RR1_FrameError 0x40 /* CRC/Framing Error */ -#define RR1_EndOfFrame 0x80 /* End of Frame (SDLC) */ - -/* Read Register 2 (channel b only) - Interrupt vector */ - -/* Read Register 3 (interrupt pending register) ch a only */ -#define RR3_BExt 0x01 /* Channel B Ext/Stat IP */ -#define RR3_BTxIP 0x02 /* Channel B Tx IP */ -#define RR3_BRxIP 0x04 /* Channel B Rx IP */ -#define RR3_AExt 0x08 /* Channel A Ext/Stat IP */ -#define RR3_ATxIP 0x10 /* Channel A Tx IP */ -#define RR3_ARxIP 0x20 /* Channel A Rx IP */ - -/* Read Register 8 (receive data register) */ - -/* Read Register 10 (misc status bits) */ -#define RR10_OnLoop 0x02 /* On loop */ -#define RR10_LoopSend 0x10 /* Loop sending */ -#define RR10_Clk2Mis 0x40 /* Two clocks missing */ -#define RR10_Clk1Mis 0x80 /* One clock missing */ - -/* Read Register 12 (lower byte of baud rate generator constant) */ - -/* Read Register 13 (upper byte of baud rate generator constant) */ - -/* Read Register 15 (value of WR 15) */ - -#define BRTC(brate) (( ((unsigned) DUART_CLOCK) / (2*(brate)*SCC_CLKMODE_TC)) - 2) -#define DUART_CLOCK 4915200 /* Z8530 duart */ -#define SCC_CLKMODE_TC 16 /* Always run x16 clock for async modes */ - -static unsigned char select_word_length_WR3[] = { - WR3_Rx5, // 5 bits / word (char) - WR3_Rx6, - WR3_Rx7, - WR3_Rx8 -}; - -static unsigned char select_word_length_WR5[] = { - WR5_Tx5, // 5 bits / word (char) - WR5_Tx6, - WR5_Tx7, - WR5_Tx8 -}; - -static unsigned char select_stop_bits[] = { - 0, - WR4_SB1, // 1 stop bit - WR4_SB15, // 1.5 stop bit - WR4_SB2 // 2 stop bits -}; - -static unsigned char select_parity[] = { - 0, // No parity - WR4_ParityEn | WR4_ParityEven, // Even parity - WR4_ParityEn, // Odd parity - 0xFF, // Mark parity - 0xFF, // Space parity -}; - -static cyg_int32 select_baud[] = { - 0, // Unused - 50, // 50 - 75, // 75 - 110, // 110 - 0, // 134.5 - 150, // 150 - 200, // 200 - 300, // 300 - 600, // 600 - 1200, // 1200 - 1800, // 1800 - 2400, // 2400 - 3600, // 3600 - 4800, // 4800 - 7200, // 7200 - 9600, // 9600 - 14400, // 14400 - 19200, // 19200 - 38400, // 38400 - 0, // 57600 - 0, // 115200 - 0, // 230400 -}; - -#endif // CYGONCE_MIPS_VRC4373_SERIAL_H diff --git a/packages/io/serial/current/src/mn10300/mn10300_serial.c b/packages/io/serial/current/src/mn10300/mn10300_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/mn10300/mn10300_serial.c +++ /dev/null @@ -1,1010 +0,0 @@ -//========================================================================== -// -// mn10300_serial.c -// -// Serial device driver for mn10300 on-chip serial devices -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): nickg -// Contributors: nickg -// Date: 1999-02-25 -// Purpose: MN10300 serial device driver -// Description: MN10300 serial device driver -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include - -#include -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_MN10300 - -#define CYG_HAL_MN10300_SERIAL_RX_FIFO - -//------------------------------------------------------------------------- - -extern void diag_printf(const char *fmt, ...); - -//------------------------------------------------------------------------- -// Forward definitions - -static bool mn10300_serial_init(struct cyg_devtab_entry *tab); -static bool mn10300_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo mn10300_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char mn10300_serial_getc(serial_channel *chan); -static bool mn10300_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void mn10300_serial_start_xmit(serial_channel *chan); -static void mn10300_serial_stop_xmit(serial_channel *chan); - -#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE -static cyg_uint32 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static cyg_uint32 mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); -static void mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); -#endif - -//------------------------------------------------------------------------- - -#define BUFSIZE 128 - -//------------------------------------------------------------------------- -// MN10300 serial line control register values: - -// Offsets to serial control registers from base -#define SERIAL_CTR 0x0 -#define SERIAL_ICR 0x4 -#define SERIAL_TXB 0x8 -#define SERIAL_RXB 0x9 -#define SERIAL_STR 0xc -#define SERIAL_TIM 0xd - -// Status register bits -#define SR_RBF 0x10 -#define SR_TBF 0x20 -#define SR_RXF 0x40 -#define SR_TXF 0x80 - -// Control register bits -#define LCR_SB1 0x00 -#define LCR_SB1_5 0x00 -#define LCR_SB2 0x04 -#define LCR_PN 0x00 // Parity mode - none -#define LCR_PS 0x40 // Forced "space" parity -#define LCR_PM 0x50 // Forced "mark" parity -#define LCR_PE 0x60 // Parity mode - even -#define LCR_PO 0x70 // Parity mode - odd -#define LCR_WL5 0x00 // not supported - use 7bit -#define LCR_WL6 0x00 // not supported - use 7bit -#define LCR_WL7 0x00 // 7 bit chars -#define LCR_WL8 0x80 // 8 bit chars -#define LCR_RXE 0x4000 // receive enable -#define LCR_TXE 0x8000 // transmit enable - -#if defined(CYGPKG_HAL_MN10300_AM31) -#define LCR_TWE 0x0100 // interrupt enable (only on serial2/AM31) -#else -#define LCR_TWE 0x0000 // Bit does not exist in other variants -#endif - -//------------------------------------------------------------------------- -// MN10300 timer registers: - -#undef TIMER_BR -#undef TIMER_MD -#define TIMER_MD 0x00 -#define TIMER_BR 0x10 - -//------------------------------------------------------------------------- -// Serial and timer base registers: - -#if defined(CYGPKG_HAL_MN10300_AM31) - -#define SERIAL0_BASE 0x34000800 -#define SERIAL1_BASE 0x34000810 -#define SERIAL2_BASE 0x34000820 - -#define TIMER0_BASE 0x34001000 -#define TIMER1_BASE 0x34001001 -#define TIMER2_BASE 0x34001002 - -#define SERIAL0_TIMER_SELECT 0x0004 // timer 0 -#define SERIAL1_TIMER_SELECT 0x0004 // timer 1 -#define SERIAL2_TIMER_SELECT 0x0001 // timer 2 - -#ifdef CYGPKG_HAL_MN10300_AM31_STDEVAL1 -// The use of PORT3 to provide CTS/CTR is specific to -// the STDEVAL1 board only. -#define PORT3_MD 0x36008025 -#endif - -#define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan) \ -CYG_MACRO_START \ - if( mn10300_chan->is_serial2 ) \ - cr |= LCR_TWE; \ - else \ - cr |= LCR_TXE; \ -CYG_MACRO_END - -#define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan) \ -CYG_MACRO_START \ - if( mn10300_chan->is_serial2 ) \ - cr &= ~LCR_TWE; \ - else \ - cr &= ~LCR_TXE; \ -CYG_MACRO_END - -#elif defined(CYGPKG_HAL_MN10300_AM33) - -#define SERIAL0_BASE 0xd4002000 -#define SERIAL1_BASE 0xd4002010 -#define SERIAL2_BASE 0xd4002020 - -#define TIMER0_BASE 0xd4003002 -#define TIMER1_BASE 0xd4003001 -#define TIMER2_BASE 0xd4003003 - -#define SERIAL0_TIMER_SELECT 0x0005 // timer 2 -#define SERIAL1_TIMER_SELECT 0x0004 // timer 1 -#define SERIAL2_TIMER_SELECT 0x0003 // timer 3 - -#define HW_TIMER0 0xd4003000 - -#define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan) - -#define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan) - -#else - -#error Unsupported MN10300 variant - -#endif - -//------------------------------------------------------------------------- -// Tables to map input values to hardware settings - -static unsigned char select_word_length[] = { - LCR_WL5, // 5 bits / word (char) - LCR_WL6, - LCR_WL7, - LCR_WL8 -}; - -static unsigned char select_stop_bits[] = { - 0, - LCR_SB1, // 1 stop bit - LCR_SB1_5, // 1.5 stop bit - LCR_SB2 // 2 stop bits -}; - -static unsigned char select_parity[] = { - LCR_PN, // No parity - LCR_PE, // Even parity - LCR_PO, // Odd parity - LCR_PM, // Mark parity - LCR_PS, // Space parity -}; - -#if defined(CYGPKG_HAL_MN10300_AM31) - -static unsigned short select_baud_01[] = { - 0, // Unused - 0, // 50 - 0, // 75 - 0, // 110 - 0, // 134.5 - 0, // 150 - 0, // 200 - 0, // 300 - 0, // 600 - 0, // 1200 - 0, // 1800 - 0, // 2400 - 0, // 3600 - 0, // 4800 - 0, // 7200 - 195, // 9600 - 130, // 14400 - 98, // 19200 - 48, // 38400 - 32, // 57600 - 16, // 115200 - 8, // 230400 -}; - -// Serial 2 has its own timer register in addition to using timer 2 to -// supply the baud rate generator. Both of these must be proframmed to -// get the right baud rate. The following values come from Matsushita -// with some modifications from Cygmon. -static struct -{ - cyg_uint8 serial2_val; - cyg_uint8 timer2_val; -} select_baud_2[] = { - { 0, 0 }, // Unused - { 0, 0 }, // 50 - { 0, 0 }, // 75 - { 0, 0 }, // 110 - { 0, 0 }, // 134.5 - { 0, 0 }, // 150 - { 0, 0 }, // 200 - { 0, 0 }, // 300 - { 126, 196 }, // 600 - { 125, 98 }, // 1200 - { 0, 0 }, // 1800 - { 124, 49 }, // 2400 - { 0, 0 }, // 3600 - { 124, 24 }, // 4800 - { 0, 0 }, // 7200 - { 70, 21 }, // 9600 - { 0, 0 }, // 14400 - { 70, 10 }, // 19200 - { 22, 16 }, // 38400 - { 88, 2 }, // 57600 - { 64, 1 }, // 115200 - { 62, 0 }, // 230400 -}; - -#elif defined(CYGPKG_HAL_MN10300_AM33) - -// The AM33 runs at a different clock rate and therefore has a -// different set of dividers for the baud rate. - -static unsigned short select_baud_01[] = { - 0, // Unused - 0, // 50 - 0, // 75 - 0, // 110 - 0, // 134.5 - 0, // 150 - 0, // 200 - 0, // 300 - 0, // 600 - 3168, // 1200 - 0, // 1800 - 1584, // 2400 - 0, // 3600 - 792, // 4800 - 0, // 7200 - 396, // 9600 - 0, // 14400 - 198, // 19200 - 99, // 38400 - 0, // 57600 - 33, // 115200 - 16, // 230400 -}; - -// Serial 2 has its own timer register in addition to using timer 2 to -// supply the baud rate generator. Both of these must be proframmed to -// get the right baud rate. The following values come from Matsushita -// with some modifications from Cygmon. - -// The values in the following table differ significantly from those -// given in the Matsushita documentation. These have been determined -// by (somewhat exhaustive) experiment, the values in the documentation -// do not appear to work at all. - -static struct -{ - cyg_uint8 serial2_val; - cyg_uint8 timer2_val; -} select_baud_2[] = { - { 0, 0 }, // Unused - { 0, 0 }, // 50 - { 0, 0 }, // 75 - { 0, 0 }, // 110 - { 0, 0 }, // 134.5 - { 0, 0 }, // 150 - { 0, 0 }, // 200 - { 0, 0 }, // 300 - { 0, 0 }, // 600 - { 0, 0 }, // 1200 - { 0, 0 }, // 1800 - { 0, 0 }, // 2400 - { 0, 0 }, // 3600 - { 110, 56 }, // 4800 - { 0, 0 }, // 7200 - { 110, 28 }, // 9600 - { 0, 0 }, // 14400 - { 71, 21 }, // 19200 - { 102, 7 }, // 38400 - { 0, 0 }, // 57600 - { 9, 26 }, // 115200 - { 0, 0 }, // 230400 -}; - -#else - -#error Unsupported MN10300 variant - -#endif - -//------------------------------------------------------------------------- -// Info for each serial device controlled - -typedef struct mn10300_serial_info { - CYG_ADDRWORD base; - CYG_ADDRWORD timer_base; - CYG_WORD timer_select; - CYG_WORD rx_int; - CYG_WORD tx_int; - cyg_bool is_serial2; - cyg_interrupt rx_interrupt; - cyg_interrupt tx_interrupt; - cyg_handle_t rx_interrupt_handle; - cyg_handle_t tx_interrupt_handle; -#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO - volatile cyg_int32 fifo_head; - volatile cyg_int32 fifo_tail; - volatile cyg_uint8 fifo[16]; -#endif -} mn10300_serial_info; - -//------------------------------------------------------------------------- -// Callback functions exported by this driver - -static SERIAL_FUNS(mn10300_serial_funs, - mn10300_serial_putc, - mn10300_serial_getc, - mn10300_serial_set_config, - mn10300_serial_start_xmit, - mn10300_serial_stop_xmit - ); - -//------------------------------------------------------------------------- -// Hardware info for each serial line - -#ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1 -#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 -static mn10300_serial_info mn10300_serial_info0 = { - SERIAL0_BASE, - TIMER0_BASE, - SERIAL0_TIMER_SELECT, - CYGNUM_HAL_INTERRUPT_SERIAL_0_RX, - CYGNUM_HAL_INTERRUPT_SERIAL_0_TX, - false -}; -#if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0 -static unsigned char mn10300_serial_out_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE]; -static unsigned char mn10300_serial_in_buf0[CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE]; -#endif -#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 -#endif - -#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 -static mn10300_serial_info mn10300_serial_info1 = { - SERIAL1_BASE, - TIMER1_BASE, - SERIAL1_TIMER_SELECT, - CYGNUM_HAL_INTERRUPT_SERIAL_1_RX, - CYGNUM_HAL_INTERRUPT_SERIAL_1_TX, - false -}; -#if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0 -static unsigned char mn10300_serial_out_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE]; -static unsigned char mn10300_serial_in_buf1[CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE]; -#endif -#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 - -#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 -static mn10300_serial_info mn10300_serial_info2 = { - SERIAL2_BASE, - TIMER2_BASE, - SERIAL2_TIMER_SELECT, - CYGNUM_HAL_INTERRUPT_SERIAL_2_RX, - CYGNUM_HAL_INTERRUPT_SERIAL_2_TX, - true -}; -#if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0 -static unsigned char mn10300_serial_out_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE]; -static unsigned char mn10300_serial_in_buf2[CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE]; -#endif -#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2 - - -//------------------------------------------------------------------------- -// Channel descriptions: - -#ifdef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE -#define SIZEOF_BUF(_x_) 0 -#else -#define SIZEOF_BUF(_x_) sizeof(_x_) -#endif - -#ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1 -#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 -#if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0 -static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel0, - mn10300_serial_funs, - mn10300_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &mn10300_serial_out_buf0[0], - SIZEOF_BUF(mn10300_serial_out_buf0), - &mn10300_serial_in_buf0[0], - SIZEOF_BUF(mn10300_serial_in_buf0) - ); -#else -static SERIAL_CHANNEL(mn10300_serial_channel0, - mn10300_serial_funs, - mn10300_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL0_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif -#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 -#endif - -#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 -#if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0 -static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel1, - mn10300_serial_funs, - mn10300_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &mn10300_serial_out_buf1[0], - SIZEOF_BUF(mn10300_serial_out_buf1), - &mn10300_serial_in_buf1[0], - SIZEOF_BUF(mn10300_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(mn10300_serial_channel1, - mn10300_serial_funs, - mn10300_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif -#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 - -#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 -#if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0 -static SERIAL_CHANNEL_USING_INTERRUPTS(mn10300_serial_channel2, - mn10300_serial_funs, - mn10300_serial_info2, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &mn10300_serial_out_buf2[0], - SIZEOF_BUF(mn10300_serial_out_buf2), - &mn10300_serial_in_buf2[0], - SIZEOF_BUF(mn10300_serial_in_buf2) - ); -#else -static SERIAL_CHANNEL(mn10300_serial_channel2, - mn10300_serial_funs, - mn10300_serial_info2, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_MN10300_SERIAL2_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif -#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2 - -//------------------------------------------------------------------------- -// And finally, the device table entries: - -#ifndef CYGPKG_HAL_MN10300_AM31_STDEVAL1 -#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 -// On the standard eval board serial0 is not connected. If enabled, it -// generates continuous frame error and overrun interrupts. Hence we do -// not touch it. -DEVTAB_ENTRY(mn10300_serial_io0, - CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - mn10300_serial_init, - mn10300_serial_lookup, // Serial driver may need initializing - &mn10300_serial_channel0 - ); -#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 -#endif - -#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 -DEVTAB_ENTRY(mn10300_serial_io1, - CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - mn10300_serial_init, - mn10300_serial_lookup, // Serial driver may need initializing - &mn10300_serial_channel1 - ); -#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 - -#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 -DEVTAB_ENTRY(mn10300_serial_io2, - CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - mn10300_serial_init, - mn10300_serial_lookup, // Serial driver may need initializing - &mn10300_serial_channel2 - ); -#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2 - -//------------------------------------------------------------------------- -// Read the serial line's status register. Serial 2 has an 8 bit status -// register while serials 0 and 1 have 16 bit registers. This function -// uses the correct size access, but passes back a 16 bit quantity for -// both. - -static cyg_uint16 mn10300_read_sr( mn10300_serial_info *mn10300_chan ) -{ - cyg_uint16 sr = 0; - if( mn10300_chan->is_serial2 ) - { - cyg_uint8 sr8; - HAL_READ_UINT8(mn10300_chan->base+SERIAL_STR, sr8); - sr = sr8; - } - else - { - HAL_READ_UINT16(mn10300_chan->base+SERIAL_STR, sr); - } - - return sr; -} - -//------------------------------------------------------------------------- - -static bool -mn10300_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - cyg_uint16 cr = 0; - cyg_uint16 sr; - - // wait for the device to become quiescent. This could take some time - // if the device had been transmitting at a low baud rate. - do { - sr = mn10300_read_sr(mn10300_chan); - } while (sr & (SR_RXF|SR_TXF)); - - // Disable device entirely. - HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, 0); - - // Set up the Interrupt Mode Register - HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_ICR, 0); - - // Set up baud rate - if( mn10300_chan->is_serial2 ) - { - // Serial 2 is a bit different from 0 and 1 in the way that the - // baud rate is controlled. - - cyg_uint8 baud_divisor = select_baud_2[new_config->baud].timer2_val; - - if (baud_divisor == 0) - return false; // Invalid baud rate selected - - HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor); - - HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, 0x80 ); - - baud_divisor = select_baud_2[new_config->baud].serial2_val; - - HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_TIM, baud_divisor); - - cr |= mn10300_chan->timer_select; - } - else - { - cyg_uint16 baud_divisor = select_baud_01[new_config->baud]; - cyg_uint8 timer_mode = 0x80; - - if (baud_divisor == 0) - return false; // Invalid baud rate selected - -#if defined(CYGPKG_HAL_MN10300_AM33) - if( baud_divisor > 255 ) - { - // The AM33 runs at a higher clock rate than the AM31 and - // needs a bigger divisor for low baud rates. We do this by - // using timer 0 as a prescaler. We set it to 198 so we can then - // use it to prescale for both serial0 and serial1 if they need - // it. - static int timer0_initialized = 0; - baud_divisor /= 198; - baud_divisor--; - timer_mode = 0x84; - if( !timer0_initialized ) - { - timer0_initialized = 1; - HAL_WRITE_UINT8(HW_TIMER0+TIMER_BR, 198 ); - HAL_WRITE_UINT8(HW_TIMER0+TIMER_MD, 0x80 ); - } - } -#endif - - HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor); - - HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, timer_mode ); - - cr |= mn10300_chan->timer_select; - } - -#ifdef PORT3_MD - HAL_WRITE_UINT8( PORT3_MD, 0x01 ); -#endif - - // set up other config values: - - cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; - cr |= select_stop_bits[new_config->stop]; - cr |= select_parity[new_config->parity]; - - cr |= LCR_RXE | LCR_TXE; // enable Rx and Tx - -#ifdef CYGPKG_HAL_MN10300_AM31 - if( mn10300_chan->is_serial2 ) - { - // AM31 has an extra TX interrupt enable bit for serial 2. - DISABLE_TRANSMIT_INTERRUPT(mn10300_chan); - } -#endif - - // Write CR into hardware - HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, cr); - - sr = mn10300_read_sr(mn10300_chan); - - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -//------------------------------------------------------------------------- -// Function to initialize the device. Called at bootstrap time. - -bool mn10300_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - -#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE - if (chan->out_cbuf.len != 0) { - // Install and enable the receive interrupt - cyg_drv_interrupt_create(mn10300_chan->rx_int, - 4, // Priority - what goes here? - (cyg_addrword_t)chan, // Data item passed to interrupt handler - mn10300_serial_rx_ISR, - mn10300_serial_rx_DSR, - &mn10300_chan->rx_interrupt_handle, - &mn10300_chan->rx_interrupt); - cyg_drv_interrupt_attach(mn10300_chan->rx_interrupt_handle); - cyg_drv_interrupt_unmask(mn10300_chan->rx_int); - - // Install and enable the transmit interrupt - cyg_drv_interrupt_create(mn10300_chan->tx_int, - 4, // Priority - what goes here? - (cyg_addrword_t)chan, // Data item passed to interrupt handler - mn10300_serial_tx_ISR, - mn10300_serial_tx_DSR, - &mn10300_chan->tx_interrupt_handle, - &mn10300_chan->tx_interrupt); - cyg_drv_interrupt_attach(mn10300_chan->tx_interrupt_handle); - cyg_drv_interrupt_mask(mn10300_chan->tx_int); - } -#endif - - mn10300_serial_config_port(chan, &chan->config, true); - - return true; -} - -//------------------------------------------------------------------------- -// This routine is called when the device is "looked" up (i.e. attached) - -static Cyg_ErrNo -mn10300_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -//------------------------------------------------------------------------- -// Return 'true' if character is sent to device - -bool -mn10300_serial_putc(serial_channel *chan, unsigned char c) -{ - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - cyg_uint8 sr = mn10300_read_sr( mn10300_chan); - - if( (sr & SR_TBF) == 0 ) - { - HAL_WRITE_UINT8( mn10300_chan->base+SERIAL_TXB, c ); - - return true; - } - else return false; -} - -//------------------------------------------------------------------------- - -unsigned char -mn10300_serial_getc(serial_channel *chan) -{ - unsigned char c; - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - do - { - cyg_uint8 sr = mn10300_read_sr( mn10300_chan ); - - if( (sr & SR_RBF) != 0 ) - { - HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c ); - - break; - } - - } while(1); - - return c; -} - -//------------------------------------------------------------------------- - -bool -mn10300_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return mn10300_serial_config_port(chan, config, false); -} - -//------------------------------------------------------------------------- -// Enable the transmitter on the device - -static void -mn10300_serial_start_xmit(serial_channel *chan) -{ -#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - cyg_uint16 cr; - - HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); - - ENABLE_TRANSMIT_INTERRUPT(mn10300_chan); - - HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); - - cyg_drv_interrupt_unmask(mn10300_chan->tx_int); - - (chan->callbacks->xmt_char)(chan); -#endif -} - -//------------------------------------------------------------------------- -// Disable the transmitter on the device - -static void -mn10300_serial_stop_xmit(serial_channel *chan) -{ -#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - cyg_uint16 cr; - cyg_uint16 sr; - - // Wait until the transmitter has actually stopped before turning it off. - - do - { - sr = mn10300_read_sr( mn10300_chan ); - - } while( sr & SR_TXF ); - - HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); - - DISABLE_TRANSMIT_INTERRUPT(mn10300_chan); - - HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); - - cyg_drv_interrupt_mask(mn10300_chan->tx_int); - -#endif -} - -//------------------------------------------------------------------------- -// Serial I/O - low level interrupt handlers (ISR) - -#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE - -#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO - -// This version of the RX ISR implements a simple receive FIFO. The -// MN10300 serial devices do not have hardware FIFOs (as found in -// 16550s for example), and it can be difficult at times to keep up -// with higher baud rates without overrunning. This ISR implements a -// software equivalent of the hardware FIFO, placing recieved -// characters into the FIFO as soon as they arrive. Whenever the DSR -// is run, it collects all the pending characters from the FIFO for -// delivery to the application. Neither the ISR or DSR disable -// interrupts, instead we rely on being able to write the head and -// tail pointers atomically, to implement lock-free synchronization. - -static cyg_uint32 -mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - cyg_uint8 sr = mn10300_read_sr( mn10300_chan); - - while( (sr & SR_RBF) != 0 ) - { - register cyg_int32 head = mn10300_chan->fifo_head; - cyg_uint8 c; - int i; - HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c ); - - mn10300_chan->fifo[head++] = c; - - if( head >= sizeof(mn10300_chan->fifo) ) - head = 0; - - mn10300_chan->fifo_head = head; - - sr = mn10300_read_sr( mn10300_chan); - - } - - cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int); - - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -#else - -static cyg_uint32 -mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - - cyg_drv_interrupt_mask(mn10300_chan->rx_int); - cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int); - - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -#endif - -static cyg_uint32 -mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - - cyg_drv_interrupt_mask(mn10300_chan->tx_int); - cyg_drv_interrupt_acknowledge(mn10300_chan->tx_int); - - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -#endif - -//------------------------------------------------------------------------- -// Serial I/O - high level interrupt handler (DSR) - -#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE - -#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO - -static void -mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - register cyg_int32 head = mn10300_chan->fifo_head; - register cyg_int32 tail = mn10300_chan->fifo_tail; - - while( head != tail ) - { - cyg_uint8 c = mn10300_chan->fifo[tail++]; - - if( tail >= sizeof(mn10300_chan->fifo) ) tail = 0; - - (chan->callbacks->rcv_char)(chan, c); - } - - mn10300_chan->fifo_tail = tail; -} - -#else - -static void -mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - cyg_uint8 sr = mn10300_read_sr( mn10300_chan); - - if( (sr & SR_RBF) != 0 ) - { - cyg_uint8 rxb; - HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, rxb ); - - (chan->callbacks->rcv_char)(chan, rxb); - } - - cyg_drv_interrupt_unmask(mn10300_chan->rx_int); -} - -#endif - -static void -mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; - cyg_uint8 sr = mn10300_read_sr( mn10300_chan); - - if( (sr & SR_TBF) == 0 ) - { - (chan->callbacks->xmt_char)(chan); - } - - cyg_drv_interrupt_unmask(mn10300_chan->tx_int); -} - -#endif - -#endif // CYGPKG_IO_SERIAL_MN10300 - -//------------------------------------------------------------------------- -// EOF mn10300.c diff --git a/packages/io/serial/current/src/powerpc/cogent_serial.h b/packages/io/serial/current/src/powerpc/cogent_serial.h deleted file mode 100644 --- a/packages/io/serial/current/src/powerpc/cogent_serial.h +++ /dev/null @@ -1,204 +0,0 @@ -//========================================================================== -// -// io/serial/powerpc/cogent_serial.h -// -// PowerPC Cogent Serial I/O definitions. -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jskov, based on ARM driver by gthomas -// Contributors:gthomas, jskov -// Date: 1999-03-02 -// Purpose: Cogent Serial definitions -//####DESCRIPTIONEND#### -//========================================================================== - -// Description of serial ports on Cogent board - -// Interrupt Enable Register -#define IER_RCV 0x01 -#define IER_XMT 0x02 -#define IER_LS 0x04 -#define IER_MS 0x08 - -// Line Control Register -#define LCR_WL5 0x00 // Word length -#define LCR_WL6 0x01 -#define LCR_WL7 0x02 -#define LCR_WL8 0x03 -#define LCR_SB1 0x00 // Number of stop bits -#define LCR_SB1_5 0x04 // 1.5 -> only valid with 5 bit words -#define LCR_SB2 0x04 -#define LCR_PN 0x00 // Parity mode - none -#define LCR_PE 0x0C // Parity mode - even -#define LCR_PO 0x08 // Parity mode - odd -#define LCR_PM 0x28 // Forced "mark" parity -#define LCR_PS 0x38 // Forced "space" parity -#define LCR_DL 0x80 // Enable baud rate latch - -// Line Status Register -#define LSR_RSR 0x01 -#define LSR_THE 0x20 - -// Modem Control Register -#define MCR_DTR 0x01 -#define MCR_RTS 0x02 -#define MCR_INT 0x08 // Enable interrupts - -// Interrupt status register -#define ISR_Tx 0x02 -#define ISR_Rx 0x04 - -// FIFO control register -#define FCR_ENABLE 0x01 -#define FCR_CLEAR_RCVR 0x02 -#define FCR_CLEAR_XMIT 0x04 - - -//////////////////////////////////////////////////////////// -// Clean this up. - -//----------------------------------------------------------------------------- -// There are two serial ports. -#define CMA_SER_16550_BASE_A 0xe900047 // port A -#define CMA_SER_16550_BASE_B 0xe900007 // port B -#define SER_16550_BASE CMA_SER_16550_BASE_B - -//----------------------------------------------------------------------------- -// Define the serial registers. The Cogent board is equipped with a 16552 -// serial chip. -#define SER_16550_RBR 0x00 // receiver buffer register, read, dlab = 0 -#define SER_16550_THR 0x00 // transmitter holding register, write, dlab = 0 -#define SER_16550_DLL 0x00 // divisor latch (LS), read/write, dlab = 1 -#define SER_16550_IER 0x08 // interrupt enable register, read/write, dlab = 0 -#define SER_16550_DLM 0x08 // divisor latch (MS), read/write, dlab = 1 -#define SER_16550_IIR 0x10 // interrupt identification reg, read, dlab = 0 -#define SER_16550_FCR 0x10 // fifo control register, write, dlab = 0 -#define SER_16550_AFR 0x10 // alternate function reg, read/write, dlab = 1 -#define SER_16550_LCR 0x18 // line control register, read/write -#define SER_16550_MCR 0x20 // modem control register, read/write -#define SER_16550_LSR 0x28 // line status register, read -#define SER_16550_MSR 0x30 // modem status register, read -#define SER_16550_SCR 0x38 // scratch pad register - -// The interrupt enable register bits. -#define SIO_IER_ERDAI 0x01 // enable received data available irq -#define SIO_IER_ETHREI 0x02 // enable THR empty interrupt -#define SIO_IER_ELSI 0x04 // enable receiver line status irq -#define SIO_IER_EMSI 0x08 // enable modem status interrupt - -// The interrupt identification register bits. -#define SIO_IIR_IP 0x01 // 0 if interrupt pending -#define SIO_IIR_ID_MASK 0x0e // mask for interrupt ID bits - -// The line status register bits. -#define SIO_LSR_DR 0x01 // data ready -#define SIO_LSR_OE 0x02 // overrun error -#define SIO_LSR_PE 0x04 // parity error -#define SIO_LSR_FE 0x08 // framing error -#define SIO_LSR_BI 0x10 // break interrupt -#define SIO_LSR_THRE 0x20 // transmitter holding register empty -#define SIO_LSR_TEMT 0x40 // transmitter register empty -#define SIO_LSR_ERR 0x80 // any error condition - -// The modem status register bits. -#define SIO_MSR_DCTS 0x01 // delta clear to send -#define SIO_MSR_DDSR 0x02 // delta data set ready -#define SIO_MSR_TERI 0x04 // trailing edge ring indicator -#define SIO_MSR_DDCD 0x08 // delta data carrier detect -#define SIO_MSR_CTS 0x10 // clear to send -#define SIO_MSR_DSR 0x20 // data set ready -#define SIO_MSR_RI 0x40 // ring indicator -#define SIO_MSR_DCD 0x80 // data carrier detect - -// The line control register bits. -#define SIO_LCR_WLS0 0x01 // word length select bit 0 -#define SIO_LCR_WLS1 0x02 // word length select bit 1 -#define SIO_LCR_STB 0x04 // number of stop bits -#define SIO_LCR_PEN 0x08 // parity enable -#define SIO_LCR_EPS 0x10 // even parity select -#define SIO_LCR_SP 0x20 // stick parity -#define SIO_LCR_SB 0x40 // set break -#define SIO_LCR_DLAB 0x80 // divisor latch access bit - -// The FIFO control register -#define SIO_FCR_FCR0 0x01 // enable xmit and rcvr fifos -#define SIO_FCR_FCR1 0x02 // clear RCVR FIFO -#define SIO_FCR_FCR2 0x04 // clear XMIT FIFO -///////////////////////////////////////// - - -static unsigned char select_word_length[] = { - LCR_WL5, // 5 bits / word (char) - LCR_WL6, - LCR_WL7, - LCR_WL8 -}; - -static unsigned char select_stop_bits[] = { - 0, - LCR_SB1, // 1 stop bit - LCR_SB1_5, // 1.5 stop bit - LCR_SB2 // 2 stop bits -}; - -static unsigned char select_parity[] = { - LCR_PN, // No parity - LCR_PE, // Even parity - LCR_PO, // Odd parity - LCR_PM, // Mark parity - LCR_PS, // Space parity -}; - -// FIXME: calc all properly -// The Cogent board has a 3.6864 MHz crystal -static unsigned short select_baud[] = { - 0, // Unused - 4608, // 50 - 0, // 75 - 2094, // 110 - 0, // 134.5 - 1536, // 150 - 0, // 200 - 768, // 300 - 384, // 600 - 182, // 1200 - 0, // 1800 - 96, // 2400 - 0, // 3600 - 48, // 4800 - 32, // 7200 - 24, // 9600 - 16, // 14400 - 12, // 19200 - 6, // 38400 - 4, // 57600 - 2, // 115200 - 0, // 230400 -}; - diff --git a/packages/io/serial/current/src/powerpc/cogent_serial_with_ints.c b/packages/io/serial/current/src/powerpc/cogent_serial_with_ints.c deleted file mode 100644 --- a/packages/io/serial/current/src/powerpc/cogent_serial_with_ints.c +++ /dev/null @@ -1,387 +0,0 @@ -//========================================================================== -// -// io/serial/powerpc/cogent_serial_with_ints.c -// -// PowerPC Cogent Serial I/O Interface Module (interrupt driven) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jskov, based on ARM driver by gthomas -// Contributors:gthomas, jskov -// Date: 1999-03-02 -// Purpose: Cogent Serial I/O module (interrupt driven version) -// Description: -// -// To Do: -// Put in magic to effectively use the FIFOs. Transmitter FIFO fill is a -// problem, and setting receiver FIFO interrupts to happen only after -// n chars may conflict with hal diag. -// -//####DESCRIPTIONEND#### -//========================================================================== - -#include -#include - -#include -#include -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_POWERPC_COGENT - -#include "cogent_serial.h" - -// Make sure the configuration is sane. -#if defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_A) && \ - defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B) && \ - !defined(CYGIMP_KERNEL_INTERRUPTS_CHAIN) -#error "Need CYGIMP_KERNEL_INTERRUPTS_CHAIN to support both ports" -#endif - - -#define BUFSIZE 128 - -typedef struct cogent_serial_info { - CYG_ADDRWORD base; - CYG_WORD int_num; - cyg_interrupt serial_interrupt; - cyg_handle_t serial_interrupt_handle; -} cogent_serial_info; - -static bool cogent_serial_init(struct cyg_devtab_entry *tab); -static bool cogent_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo cogent_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char cogent_serial_getc(serial_channel *chan); -static bool cogent_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void cogent_serial_start_xmit(serial_channel *chan); -static void cogent_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 cogent_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void cogent_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(cogent_serial_funs, - cogent_serial_putc, - cogent_serial_getc, - cogent_serial_set_config, - cogent_serial_start_xmit, - cogent_serial_stop_xmit - ); - -#ifdef CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_A -static cogent_serial_info cogent_serial_info0 ={CMA_SER_16550_BASE_A, - CYGNUM_HAL_INTERRUPT_SIU_IRQ1}; -#if CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE > 0 -static unsigned char cogent_serial_out_buf0[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE]; -static unsigned char cogent_serial_in_buf0[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(cogent_serial_channel0, - cogent_serial_funs, - cogent_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &cogent_serial_out_buf0[0], - sizeof(cogent_serial_out_buf0), - &cogent_serial_in_buf0[0], - sizeof(cogent_serial_in_buf0) - ); -#else -static SERIAL_CHANNEL(cogent_serial_channel0, - cogent_serial_funs, - cogent_serial_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_A_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(cogent_serial_io0, - CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_A_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - cogent_serial_init, - cogent_serial_lookup, // Serial driver may need initializing - &cogent_serial_channel0 - ); -#endif - -#ifdef CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B -static cogent_serial_info cogent_serial_info1 ={CMA_SER_16550_BASE_B, - CYGNUM_HAL_INTERRUPT_SIU_IRQ1}; -#if CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE > 0 -static unsigned char cogent_serial_out_buf1[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE]; -static unsigned char cogent_serial_in_buf1[CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(cogent_serial_channel1, - cogent_serial_funs, - cogent_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &cogent_serial_out_buf1[0], - sizeof(cogent_serial_out_buf1), - &cogent_serial_in_buf1[0], - sizeof(cogent_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(cogent_serial_channel1, - cogent_serial_funs, - cogent_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_COGENT_SERIAL_B_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(cogent_serial_io1, - CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - cogent_serial_init, - cogent_serial_lookup, // Serial driver may need initializing - &cogent_serial_channel1 - ); -#endif - - - -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool -cogent_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; - cyg_addrword_t port = cogent_chan->base; - cyg_uint16 baud_divisor = select_baud[new_config->baud]; - cyg_uint8 _lcr, _ier; - - if (baud_divisor == 0) - return false; // Invalid baud rate selected - - // Disable port interrupts while changing hardware - HAL_READ_UINT8(port+SER_16550_IER, _ier); - HAL_WRITE_UINT8(port+SER_16550_IER, 0); - - // Set databits, stopbits and parity. - _lcr = select_word_length[(new_config->word_length - - CYGNUM_SERIAL_WORD_LENGTH_5)] | - select_stop_bits[new_config->stop] | - select_parity[new_config->parity]; - HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr); - - // Set baud rate. - _lcr |= LCR_DL; - HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr); - HAL_WRITE_UINT8(port+SER_16550_DLM, baud_divisor >> 8); - HAL_WRITE_UINT8(port+SER_16550_DLL, baud_divisor & 0xff); - _lcr &= ~LCR_DL; - HAL_WRITE_UINT8(port+SER_16550_LCR, _lcr); - - if (init) { - // Enable and clear FIFO - HAL_WRITE_UINT8(port+SER_16550_FCR, - (FCR_ENABLE | FCR_CLEAR_RCVR | FCR_CLEAR_XMIT)); - - if (chan->out_cbuf.len != 0) { - HAL_WRITE_UINT8(port+SER_16550_IER, SIO_IER_ERDAI); - } else { - HAL_WRITE_UINT8(port+SER_16550_IER, 0); - } - - { - // Special initialization for ST16C552 on CMA102 - cyg_uint8 mcr; - - HAL_READ_UINT8(CMA_SER_16550_BASE_A+SER_16550_MCR, mcr); - mcr |= 8; - HAL_WRITE_UINT8(CMA_SER_16550_BASE_A+SER_16550_MCR, mcr); - - HAL_READ_UINT8(CMA_SER_16550_BASE_B+SER_16550_MCR, mcr); - mcr |= 8; - HAL_WRITE_UINT8(CMA_SER_16550_BASE_B+SER_16550_MCR, mcr); - } - } else { - HAL_WRITE_UINT8(port+SER_16550_IER, _ier); - } - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -cogent_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; -#ifdef CYGDBG_IO_INIT - diag_printf("COGENT SERIAL init - dev: %x.%d\n", cogent_chan->base, cogent_chan->int_num); -#endif - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (chan->out_cbuf.len != 0) { - cyg_drv_interrupt_create(cogent_chan->int_num, - 0, // can change IRQ0 priority - (cyg_addrword_t)chan, // Data item passed to interrupt handler - cogent_serial_ISR, - cogent_serial_DSR, - &cogent_chan->serial_interrupt_handle, - &cogent_chan->serial_interrupt); - cyg_drv_interrupt_attach(cogent_chan->serial_interrupt_handle); - cyg_drv_interrupt_unmask(cogent_chan->int_num); - } - cogent_serial_config_port(chan, &chan->config, true); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -cogent_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -cogent_serial_putc(serial_channel *chan, unsigned char c) -{ - cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; - cyg_addrword_t port = cogent_chan->base; - cyg_uint8 _lsr; - - HAL_READ_UINT8(port+SER_16550_LSR, _lsr); - if (_lsr & SIO_LSR_THRE) { -// Transmit buffer is empty - HAL_WRITE_UINT8(port+SER_16550_THR, c); - return true; - } else { -// No space - return false; - } -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -cogent_serial_getc(serial_channel *chan) -{ - unsigned char c; - cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; - cyg_addrword_t port = cogent_chan->base; - cyg_uint8 _lsr; - - do { - HAL_READ_UINT8(port+SER_16550_LSR, _lsr); - } while ((_lsr & SIO_LSR_DR) == 0); - - HAL_READ_UINT8(port+SER_16550_RBR, c); - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -cogent_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return cogent_serial_config_port(chan, config, false); -} - -// Enable the transmitter on the device -static void -cogent_serial_start_xmit(serial_channel *chan) -{ - cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; - cyg_addrword_t port = cogent_chan->base; - cyg_uint8 _ier; - - HAL_READ_UINT8(port+SER_16550_IER, _ier); - _ier |= IER_XMT; // Enable xmit interrupt - HAL_WRITE_UINT8(port+SER_16550_IER, _ier); - - (chan->callbacks->xmt_char)(chan); -} - -// Disable the transmitter on the device -static void -cogent_serial_stop_xmit(serial_channel *chan) -{ - cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; - cyg_addrword_t port = cogent_chan->base; - cyg_uint8 _ier; - - HAL_READ_UINT8(port+SER_16550_IER, _ier); - _ier &= ~IER_XMT; // Disable xmit interrupt - HAL_WRITE_UINT8(port+SER_16550_IER, _ier); -} - -// Serial I/O - low level interrupt handler (ISR) -static cyg_uint32 -cogent_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(cogent_chan->int_num); - cyg_drv_interrupt_acknowledge(cogent_chan->int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level interrupt handler (DSR) -static void -cogent_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - cogent_serial_info *cogent_chan = (cogent_serial_info *)chan->dev_priv; - cyg_addrword_t port = cogent_chan->base; - cyg_uint8 _iir; - - HAL_READ_UINT8(port+SER_16550_IIR, _iir); - _iir &= SIO_IIR_ID_MASK; - if ( ISR_Tx == _iir ) { - (chan->callbacks->xmt_char)(chan); - } else if ( ISR_Rx == _iir ) { - cyg_uint8 _c; - HAL_READ_UINT8(port+SER_16550_RBR, _c); - (chan->callbacks->rcv_char)(chan, _c); - } - cyg_drv_interrupt_unmask(cogent_chan->int_num); -} -#endif diff --git a/packages/io/serial/current/src/powerpc/quicc_smc_serial.c b/packages/io/serial/current/src/powerpc/quicc_smc_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/powerpc/quicc_smc_serial.c +++ /dev/null @@ -1,743 +0,0 @@ -//========================================================================== -// -// io/serial/powerpc/quicc_smc_serial.c -// -// PowerPC QUICC (SMC) Serial I/O Interface Module (interrupt driven) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-06-20 -// Purpose: QUICC SMC Serial I/O module (interrupt driven version) -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include CYGBLD_HAL_PLATFORM_H - -#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC - -// Buffer descriptor control bits -#define QUICC_BD_CTL_Ready 0x8000 // Buffer contains data (tx) or is empty (rx) -#define QUICC_BD_CTL_Wrap 0x2000 // Last buffer in list -#define QUICC_BD_CTL_Int 0x1000 // Generate interrupt when empty (tx) or full (rx) -#define QUICC_BD_CTL_MASK 0xB000 // User settable bits - -// SMC Mode Register -#define QUICC_SMCMR_CLEN(n) ((n+1)<<11) // Character length -#define QUICC_SMCMR_SB(n) ((n-1)<<10) // Stop bits (1 or 2) -#define QUICC_SMCMR_PE(n) (n<<9) // Parity enable (0=disable, 1=enable) -#define QUICC_SMCMR_PM(n) (n<<8) // Parity mode (0=odd, 1=even) -#define QUICC_SMCMR_UART (2<<4) // UART mode -#define QUICC_SMCMR_TEN (1<<1) // Enable transmitter -#define QUICC_SMCMR_REN (1<<0) // Enable receiver - -// SMC Events (interrupts) -#define QUICC_SMCE_BRK 0x10 // Break received -#define QUICC_SMCE_BSY 0x04 // Busy - receive buffer overrun -#define QUICC_SMCE_TX 0x02 // Tx interrupt -#define QUICC_SMCE_RX 0x01 // Rx interrupt - -// SMC Commands -#define QUICC_SMC_CMD_InitTxRx (0<<8) -#define QUICC_SMC_CMD_InitTx (1<<8) -#define QUICC_SMC_CMD_InitRx (2<<8) -#define QUICC_SMC_CMD_StopTx (4<<8) -#define QUICC_SMC_CMD_RestartTx (6<<8) -#define QUICC_SMC_CMD_Reset 0x8000 -#define QUICC_SMC_CMD_Go 0x0001 - -#include "quicc_smc_serial.h" - -typedef struct quicc_smc_serial_info { - CYG_ADDRWORD channel; // Which channel SMC1/SMC2 - CYG_WORD int_num; // Interrupt number - cyg_uint32 *brg; // Which baud rate generator - volatile struct smc_uart_pram *pram; // Parameter RAM pointer - volatile struct smc_regs *ctl; // SMC control registers - volatile struct cp_bufdesc *txbd, *rxbd; // Next Tx,Rx descriptor to use - struct cp_bufdesc *tbase, *rbase; // First Tx,Rx descriptor - int txsize, rxsize; // Length of individual buffers - cyg_interrupt serial_interrupt; - cyg_handle_t serial_interrupt_handle; - bool tx_enabled; -} quicc_smc_serial_info; - -static bool quicc_smc_serial_init(struct cyg_devtab_entry *tab); -static bool quicc_smc_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo quicc_smc_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char quicc_smc_serial_getc(serial_channel *chan); -static bool quicc_smc_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void quicc_smc_serial_start_xmit(serial_channel *chan); -static void quicc_smc_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 quicc_smc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void quicc_smc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(quicc_smc_serial_funs, - quicc_smc_serial_putc, - quicc_smc_serial_getc, - quicc_smc_serial_set_config, - quicc_smc_serial_start_xmit, - quicc_smc_serial_stop_xmit - ); - -#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 -static quicc_smc_serial_info quicc_smc_serial_info1 = { - 0x90, // Channel indicator - CYGNUM_HAL_INTERRUPT_CPM_SMC1 // interrupt -}; -#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE > 0 -static unsigned char quicc_smc_serial_out_buf1[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE]; -static unsigned char quicc_smc_serial_in_buf1[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_smc_serial_channel1, - quicc_smc_serial_funs, - quicc_smc_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &quicc_smc_serial_out_buf1[0], sizeof(quicc_smc_serial_out_buf1), - &quicc_smc_serial_in_buf1[0], sizeof(quicc_smc_serial_in_buf1) - ); -#else -static SERIAL_CHANNEL(quicc_smc_serial_channel1, - quicc_smc_serial_funs, - quicc_smc_serial_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -static unsigned char quicc_smc1_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE]; -static unsigned char quicc_smc1_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE]; - -DEVTAB_ENTRY(quicc_smc_serial_io1, - CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - quicc_smc_serial_init, - quicc_smc_serial_lookup, // Serial driver may need initializing - &quicc_smc_serial_channel1 - ); -#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 - -#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 -static quicc_smc_serial_info quicc_smc_serial_info2 = { - 0xD0, // Channel indicator - CYGNUM_HAL_INTERRUPT_CPM_SMC2_PIP // interrupt -}; -#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE > 0 -static unsigned char quicc_smc_serial_out_buf2[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE]; -static unsigned char quicc_smc_serial_in_buf2[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_smc_serial_channel2, - quicc_smc_serial_funs, - quicc_smc_serial_info2, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &quicc_smc_serial_out_buf2[0], sizeof(quicc_smc_serial_out_buf2), - &quicc_smc_serial_in_buf2[0], sizeof(quicc_smc_serial_in_buf2) - ); -#else -static SERIAL_CHANNEL(quicc_smc_serial_channel2, - quicc_smc_serial_funs, - quicc_smc_serial_info2, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif -static unsigned char quicc_smc2_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE]; -static unsigned char quicc_smc2_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM][CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE]; - -DEVTAB_ENTRY(quicc_smc_serial_io2, - CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - quicc_smc_serial_init, - quicc_smc_serial_lookup, // Serial driver may need initializing - &quicc_smc_serial_channel2 - ); -#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 - -#ifdef CYGDBG_DIAG_BUF -extern int enable_diag_uart; -#endif // CYGDBG_DIAG_BUF - -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool -quicc_smc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; - unsigned int baud_divisor = select_baud[new_config->baud]; - cyg_uint32 _lcr; - EPPC *eppc = eppc_base(); - if (baud_divisor == 0) return false; - // Disable channel during setup - smc_chan->ctl->smc_smcmr = QUICC_SMCMR_UART; // Disabled, UART mode - // Disable port interrupts while changing hardware - _lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | - select_stop_bits[new_config->stop] | - select_parity[new_config->parity]; - // Stop transmitter while changing baud rate - eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_StopTx; - // Set baud rate generator - *smc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1); -#ifdef XX_CYGDBG_DIAG_BUF - enable_diag_uart = 0; - diag_printf("Set BAUD RATE[%x], %d = %x, tstate = %x\n", smc_chan->brg, baud_divisor, *smc_chan->brg, smc_chan->pram->tstate); - enable_diag_uart = 1; -#endif // CYGDBG_DIAG_BUF - - // Enable channel with new configuration - smc_chan->ctl->smc_smcmr = QUICC_SMCMR_UART|QUICC_SMCMR_TEN|QUICC_SMCMR_REN|_lcr; - eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_RestartTx; - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -// Function to set up internal tables for device. -static void -quicc_smc_serial_init_info(quicc_smc_serial_info *smc_chan, - volatile struct smc_uart_pram *uart_pram, - volatile struct smc_regs *ctl, - int TxBD, int TxNUM, int TxSIZE, - cyg_uint8 *TxBUF, - int RxBD, int RxNUM, int RxSIZE, - cyg_uint8 *RxBUF, - int portBmask, - int BRG, int SIpos) -{ - EPPC *eppc = eppc_base(); - struct cp_bufdesc *txbd, *rxbd; - cyg_uint32 simode = 0; - int i; - - // Disable channel during setup - ctl->smc_smcmr = QUICC_SMCMR_UART; // Disabled, UART mode - smc_chan->pram = uart_pram; - smc_chan->ctl = ctl; - /* - * SDMA & LCD bus request level 5 - * (Section 16.10.2.1) - */ - eppc->dma_sdcr = 1; - switch (BRG) { - case 1: - smc_chan->brg = (cyg_uint32 *)&eppc->brgc1; - simode = 0; - break; - case 2: - smc_chan->brg = (cyg_uint32 *)&eppc->brgc2; - simode = 1; - break; - case 3: - smc_chan->brg = (cyg_uint32 *)&eppc->brgc3; - simode = 2; - break; - case 4: - smc_chan->brg = (cyg_uint32 *)&eppc->brgc4; - simode = 3; - break; - } - // NMSI mode, BRGn to SMCm (Section 16.12.5.2) - eppc->si_simode = (eppc->si_simode & ~(0xF<pip_pbpar |= portBmask; - eppc->pip_pbdir &= ~portBmask; - /* - * Reset Rx & Tx params - */ - eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_InitTxRx; - /* - * SDMA & LCD bus request level 5 - * (Section 16.10.2.1) - */ - eppc->dma_sdcr = 1; - /* - * Set Rx and Tx function code - * (Section 16.15.4.2) - */ - uart_pram->rfcr = 0x18; - uart_pram->tfcr = 0x18; - /* - * Set pointers to buffer descriptors. - * (Sections 16.15.4.1, 16.15.7.12, and 16.15.7.13) - */ - uart_pram->rbase = RxBD; - uart_pram->tbase = TxBD; - /* tx and rx buffer descriptors */ - txbd = (struct cp_bufdesc *)((char *)eppc + TxBD); - rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD); - smc_chan->txbd = txbd; - smc_chan->tbase = txbd; - smc_chan->txsize = TxSIZE; - smc_chan->rxbd = rxbd; - smc_chan->rbase = rxbd; - smc_chan->rxsize = RxSIZE; - /* max receive buffer length */ - uart_pram->mrblr = RxSIZE; - /* set max_idle feature - generate interrupt after 4 chars idle period */ - uart_pram->max_idl = 4; - /* no last brk char received */ - uart_pram->brkln = 0; - /* no break condition occurred */ - uart_pram->brkec = 0; - /* 1 break char sent on top XMIT */ - uart_pram->brkcr = 1; - /* setup RX buffer descriptors */ - for (i = 0; i < RxNUM; i++) { - rxbd->length = 0; - rxbd->buffer = RxBUF; - rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int; - if (i == (RxNUM-1)) rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer - RxBUF += RxSIZE; - rxbd++; - } - /* setup TX buffer descriptors */ - for (i = 0; i < TxNUM; i++) { - txbd->length = 0; - txbd->buffer = TxBUF; - txbd->ctrl = 0; - if (i == (TxNUM-1)) txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer - TxBUF += TxSIZE; - txbd++; - } - /* - * Clear any previous events. Enable interrupts. - * (Section 16.15.7.14 and 16.15.7.15) - */ - ctl->smc_smce = 0xFF; - ctl->smc_smcm = QUICC_SMCE_BSY|QUICC_SMCE_TX|QUICC_SMCE_RX; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -quicc_smc_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; - volatile EPPC *eppc = (volatile EPPC *)eppc_base(); - int TxBD, RxBD; - static int first_init = 1; - int cache_state; - HAL_DCACHE_IS_ENABLED(cache_state); - HAL_DCACHE_SYNC(); - HAL_DCACHE_DISABLE(); -#ifdef CYGDBG_IO_INIT - diag_printf("QUICC_SMC SERIAL init - dev: %x.%d\n", smc_chan->channel, smc_chan->int_num); -#endif - if (first_init) { - // Set up tables since many fields are dynamic [computed at runtime] - first_init = 0; -#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 - eppc->cp_cr = QUICC_SMC_CMD_Reset | QUICC_SMC_CMD_Go; // Totally reset CP - while (eppc->cp_cr & QUICC_SMC_CMD_Reset) ; - TxBD = 0x2800; // Note: this should be configurable - RxBD = TxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM*8; - quicc_smc_serial_init_info(&quicc_smc_serial_info1, - &eppc->pram[2].scc.pothers.smc_modem.psmc.u, // PRAM - &eppc->smc_regs[0], // Control registers - TxBD, - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM, - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE, - &quicc_smc1_txbuf[0][0], - RxBD, - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM, - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE, - &quicc_smc1_rxbuf[0][0], - 0xC0, // PortB mask - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BRG, - 12 // SI mask position - ); - TxBD = RxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM*8; -#else -#ifdef CYGPKG_HAL_POWERPC_MBX - // Ensure the SMC1 side is initialized first and use shared mem - // above where it plays: - diag_init(); // (pull in constructor that inits diag channel) - TxBD = 0x2830; // Note: this should be inferred from the chip state -#else - // there is no diag device wanting to use the QUICC, so prepare it - // for SMC2 use only. - eppc->cp_cr = QUICC_SMC_CMD_Reset | QUICC_SMC_CMD_Go; // Totally reset CP - while (eppc->cp_cr & QUICC_SMC_CMD_Reset) ; - TxBD = 0x2800; // Note: this should be configurable -#endif -#endif -#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 - RxBD = TxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM*8; - quicc_smc_serial_init_info(&quicc_smc_serial_info2, - &eppc->pram[3].scc.pothers.smc_modem.psmc.u, // PRAM - &eppc->smc_regs[1], // Control registers - TxBD, - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM, - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE, - &quicc_smc2_txbuf[0][0], - RxBD, - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM, - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE, - &quicc_smc2_rxbuf[0][0], - 0xC00, // PortB mask - CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BRG, - 28 // SI mask position - ); -#endif - } - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (chan->out_cbuf.len != 0) { - cyg_drv_interrupt_create(smc_chan->int_num, - CYGARC_SIU_PRIORITY_HIGH, // Priority - unused (but asserted) - (cyg_addrword_t)chan, // Data item passed to interrupt handler - quicc_smc_serial_ISR, - quicc_smc_serial_DSR, - &smc_chan->serial_interrupt_handle, - &smc_chan->serial_interrupt); - cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle); - cyg_drv_interrupt_mask(smc_chan->int_num); - smc_chan->tx_enabled = false; - } - quicc_smc_serial_config_port(chan, &chan->config, true); - if (cache_state) - HAL_DCACHE_ENABLE(); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -quicc_smc_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -// Force the current transmit buffer to be sent -static void -quicc_smc_serial_flush(quicc_smc_serial_info *smc_chan) -{ - volatile struct cp_bufdesc *txbd = smc_chan->txbd; - if ((txbd->length > 0) && ((txbd->ctrl & QUICC_BD_CTL_Ready) == 0)) { - txbd->ctrl |= QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int; // Signal buffer ready - if (txbd->ctrl & QUICC_BD_CTL_Wrap) { - txbd = smc_chan->tbase; - } else { - txbd++; - } - smc_chan->txbd = txbd; - } -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -quicc_smc_serial_putc(serial_channel *chan, unsigned char c) -{ - quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; - volatile struct cp_bufdesc *txbd, *txfirst; - EPPC *eppc = eppc_base(); - bool res; - cyg_drv_dsr_lock(); // Avoid race condition testing pointers - txbd = (struct cp_bufdesc *)((char *)eppc + smc_chan->pram->tbptr); - txfirst = txbd; - // Scan for a non-busy buffer - while (txbd->ctrl & QUICC_BD_CTL_Ready) { - // This buffer is busy, move to next one - if (txbd->ctrl & QUICC_BD_CTL_Wrap) { - txbd = smc_chan->tbase; - } else { - txbd++; - } - if (txbd == txfirst) break; // Went all the way around - } - smc_chan->txbd = txbd; - if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == 0) { - // Transmit buffer is not full/busy - txbd->buffer[txbd->length++] = c; - if (txbd->length == smc_chan->txsize) { - // This buffer is now full, tell SMC to start processing it - quicc_smc_serial_flush(smc_chan); - } - res = true; - } else { - // No space - res = false; - } - cyg_drv_dsr_unlock(); - return res; -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -quicc_smc_serial_getc(serial_channel *chan) -{ - unsigned char c; - quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; - volatile struct cp_bufdesc *rxbd = smc_chan->rxbd; - while ((rxbd->ctrl & QUICC_BD_CTL_Ready) != 0) ; - c = rxbd->buffer[0]; - rxbd->length = smc_chan->rxsize; - rxbd->ctrl |= QUICC_BD_CTL_Ready; - if (rxbd->ctrl & QUICC_BD_CTL_Wrap) { - rxbd = smc_chan->rbase; - } else { - rxbd++; - } - smc_chan->rxbd = (struct cp_bufdesc *)rxbd; - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -quicc_smc_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - bool res = quicc_smc_serial_config_port(chan, config, false); - // FIXME - The documentation says that you can't change the baud rate - // again until at least two BRG input clocks have occurred. - return res; -} - -// Enable the transmitter (interrupt) on the device -static void -quicc_smc_serial_start_xmit(serial_channel *chan) -{ - quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; - if (smc_chan->txbd->length == 0) { - // See if there is anything to put in this buffer, just to get it going - cyg_drv_dsr_lock(); - (chan->callbacks->xmt_char)(chan); - cyg_drv_dsr_unlock(); - } - if (smc_chan->txbd->length != 0) { - // Make sure it gets started - quicc_smc_serial_flush(smc_chan); - } - smc_chan->tx_enabled = true; - cyg_drv_interrupt_unmask(smc_chan->int_num); -} - -// Disable the transmitter on the device -static void -quicc_smc_serial_stop_xmit(serial_channel *chan) -{ - quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; - // If anything is in the last buffer, need to get it started - if (smc_chan->txbd->length != 0) { - quicc_smc_serial_flush(smc_chan); - // Note: interrupt will get masked after this buffer finishes - } else { - cyg_drv_interrupt_mask(smc_chan->int_num); - } - smc_chan->tx_enabled = false; -} - -// Serial I/O - low level interrupt handler (ISR) -static cyg_uint32 -quicc_smc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; - cyg_drv_interrupt_mask(smc_chan->int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level interrupt handler (DSR) -static void -quicc_smc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv; - volatile struct smc_regs *ctl = smc_chan->ctl; - volatile struct cp_bufdesc *txbd; - volatile struct cp_bufdesc *rxbd = smc_chan->rxbd; - struct cp_bufdesc *rxlast; - int i, cache_state; -#ifdef CYGDBG_DIAG_BUF - int _time, _stime; - externC cyg_tick_count_t cyg_current_time(void); - cyg_drv_isr_lock(); - enable_diag_uart = 0; - HAL_CLOCK_READ(&_time); - _stime = (int)cyg_current_time(); - diag_printf("DSR start - CE: %x, time: %x.%x\n", ctl->smc_smce, _stime, _time); - enable_diag_uart = 1; -#endif // CYGDBG_DIAG_BUF - if (ctl->smc_smce & QUICC_SMCE_TX) { -#ifdef XX_CYGDBG_DIAG_BUF - enable_diag_uart = 0; - txbd = smc_chan->tbase; - for (i = 0; i < CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM; i++, txbd++) { - diag_printf("Tx BD: %x, length: %d, ctl: %x\n", txbd, txbd->length, txbd->ctrl); - } - enable_diag_uart = 1; -#endif // CYGDBG_DIAG_BUF - // Transmit interrupt - ctl->smc_smce = QUICC_SMCE_TX; // Reset interrupt state; - txbd = smc_chan->tbase; // First buffer - while (true) { - if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) { -#ifdef XX_CYGDBG_DIAG_BUF - enable_diag_uart = 0; - HAL_CLOCK_READ(&_time); - _stime = (int)cyg_current_time(); - diag_printf("TX Done - Tx: %x, length: %d, time: %x.%x\n", txbd, txbd->length, _stime, _time); - enable_diag_uart = 1; -#endif // CYGDBG_DIAG_BUF - txbd->length = 0; - txbd->ctrl &= ~QUICC_BD_CTL_Int; // Reset interrupt bit - } - if (txbd->ctrl & QUICC_BD_CTL_Wrap) { - txbd = smc_chan->tbase; - break; - } else { - txbd++; - } - } - (chan->callbacks->xmt_char)(chan); - } - while (ctl->smc_smce & QUICC_SMCE_RX) { - // Receive interrupt - ctl->smc_smce = QUICC_SMCE_RX; // Reset interrupt state; - rxlast = (struct cp_bufdesc *) ( - (char *)eppc_base() + smc_chan->pram->rbptr ); -#ifdef CYGDBG_DIAG_BUF - enable_diag_uart = 0; - HAL_CLOCK_READ(&_time); - _stime = (int)cyg_current_time(); - diag_printf("Scan RX - rxbd: %x, rbptr: %x, time: %x.%x\n", rxbd, rxlast, _stime, _time); -#endif // CYGDBG_DIAG_BUF - while (rxbd != rxlast) { - if ((rxbd->ctrl & QUICC_BD_CTL_Ready) == 0) { -#ifdef CYGDBG_DIAG_BUF - diag_printf("rxbuf: %x, flags: %x, length: %d\n", rxbd, rxbd->ctrl, rxbd->length); - diag_dump_buf(rxbd->buffer, rxbd->length); -#endif // CYGDBG_DIAG_BUF - for (i = 0; i < rxbd->length; i++) { - (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]); - } - // Note: the MBX860 does not seem to snoop/invalidate the data cache properly! - HAL_DCACHE_IS_ENABLED(cache_state); - if (cache_state) { - HAL_DCACHE_INVALIDATE(rxbd->buffer, smc_chan->rxsize); // Make sure no stale data - } - rxbd->length = 0; - rxbd->ctrl |= QUICC_BD_CTL_Ready; - } - if (rxbd->ctrl & QUICC_BD_CTL_Wrap) { - rxbd = smc_chan->rbase; - } else { - rxbd++; - } - } -#ifdef CYGDBG_DIAG_BUF - enable_diag_uart = 1; -#endif // CYGDBG_DIAG_BUF - smc_chan->rxbd = (struct cp_bufdesc *)rxbd; - } - if (ctl->smc_smce & QUICC_SMCE_BSY) { -#ifdef CYGDBG_DIAG_BUF - enable_diag_uart = 0; - diag_printf("RX BUSY interrupt\n"); - enable_diag_uart = 1; -#endif // CYGDBG_DIAG_BUF - ctl->smc_smce = QUICC_SMCE_BSY; // Reset interrupt state; - } -#ifdef CYGDBG_DIAG_BUF - enable_diag_uart = 0; - HAL_CLOCK_READ(&_time); - _stime = (int)cyg_current_time(); - diag_printf("DSR done - CE: %x, time: %x.%x\n", ctl->smc_smce, _stime, _time); - enable_diag_uart = 1; -#endif // CYGDBG_DIAG_BUF - cyg_drv_interrupt_acknowledge(smc_chan->int_num); - cyg_drv_interrupt_unmask(smc_chan->int_num); -#ifdef CYGDBG_DIAG_BUF - cyg_drv_isr_unlock(); -#endif // CYGDBG_DIAG_BUF -} - -void -show_rxbd(int dump_all) -{ -#ifdef CYGDBG_DIAG_BUF - EPPC *eppc = eppc_base(); - struct smc_uart_pram *pram = &eppc->pram[2].scc.pothers.smc_modem.psmc.u; - struct cp_bufdesc *rxbd = (struct cp_bufdesc *)((char *)eppc+pram->rbase); - int _enable = enable_diag_uart; - enable_diag_uart = 0; -#if 1 - diag_printf("SMC Mask: %x, Events: %x, Rbase: %x, Rbptr: %x\n", - eppc->smc_regs[0].smc_smcm, eppc->smc_regs[0].smc_smce, - pram->rbase, pram->rbptr); - while (true) { - diag_printf("Rx BD: %x, ctl: %x, length: %d\n", rxbd, rxbd->ctrl, rxbd->length); - if (rxbd->ctrl & QUICC_BD_CTL_Wrap) break; - rxbd++; - } -#endif - enable_diag_uart = _enable; - if (dump_all) dump_diag_buf(); -#endif // CYGDBG_DIAG_BUF -} -#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC - -// ------------------------------------------------------------------------ -// EOF powerpc/quicc_smc_serial.c diff --git a/packages/io/serial/current/src/powerpc/quicc_smc_serial.h b/packages/io/serial/current/src/powerpc/quicc_smc_serial.h deleted file mode 100644 --- a/packages/io/serial/current/src/powerpc/quicc_smc_serial.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef CYGONCE_POWERPC_QUICC_SMC_SERIAL_H -#define CYGONCE_POWERPC_QUICC_SMC_SERIAL_H - -// ==================================================================== -// -// quicc_smc_serial.h -// -// Device I/O - Description of PowerPC QUICC/SMC serial hardware -// -// ==================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -// ==================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-06-21 -// Purpose: Internal interfaces for serial I/O drivers -// Description: -// -//####DESCRIPTIONEND#### -// -// ==================================================================== - -// Description of serial ports using QUICC/SMC - -#include // QUICC structure definitions - -static unsigned int select_word_length[] = { - QUICC_SMCMR_CLEN(5), // 5 bits / word (char) - QUICC_SMCMR_CLEN(6), - QUICC_SMCMR_CLEN(7), - QUICC_SMCMR_CLEN(8) -}; - -static unsigned int select_stop_bits[] = { - 0, - QUICC_SMCMR_SB(1), // 1 stop bit - QUICC_SMCMR_SB(1), // 1.5 stop bit - QUICC_SMCMR_SB(2) // 2 stop bits -}; - -static unsigned int select_parity[] = { - QUICC_SMCMR_PE(0), // No parity - QUICC_SMCMR_PE(1)|QUICC_SMCMR_PM(1), // Even parity - QUICC_SMCMR_PE(1)|QUICC_SMCMR_PM(0), // Odd parity - 0, // Mark parity - 0, // Space parity -}; - -// Baud rate values, based on board clock - -static cyg_int32 select_baud[] = { - 0, // Unused - 50, // 50 - 75, // 75 - 110, // 110 - 0, // 134.5 - 150, // 150 - 200, // 200 - 300, // 300 - 600, // 600 - 1200, // 1200 - 1800, // 1800 - 2400, // 2400 - 3600, // 3600 - 4800, // 4800 - 7200, // 7200 - 9600, // 9600 - 14400, // 14400 - 19200, // 19200 - 38400, // 38400 - 57600, // 57600 - 115200, // 115200 - 0, // 230400 -}; - -#define UART_BITRATE(n) (((CYGHWR_HAL_POWERPC_MBX_BOARD_SPEED*1000000)/16)/n) -#define UART_SLOW_BITRATE(n) ((CYGHWR_HAL_POWERPC_MBX_BOARD_SPEED*1000000)/n)) - -#endif // CYGONCE_POWERPC_QUICC_SMC_SERIAL_H diff --git a/packages/io/serial/current/src/sh/sh_sci_7708.inl b/packages/io/serial/current/src/sh/sh_sci_7708.inl deleted file mode 100644 --- a/packages/io/serial/current/src/sh/sh_sci_7708.inl +++ /dev/null @@ -1,97 +0,0 @@ -//========================================================================== -// -// io/serial/sh/sh_sci_7708.c -// -// Serial I/O Interface Module definitions for SH3/7708 -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jskov -// Contributors:jskov -// Date: 1999-06-16 -// Purpose: Defines SCI serial resources for SH3/7708. -// Description: -// -//####DESCRIPTIONEND#### -//========================================================================== - -// Controller bases in the SH3/7708 (only one) -#define SH_SERIAL_SCI_BASE 0xfffffe80 - -// The SCI controller register layout on the SH3/7708. -#define SCI_SCSMR 0 // serial mode register -#define SCI_SCBRR 2 // bit rate register -#define SCI_SCSCR 4 // serial control register -#define SCI_SCTDR 6 // transmit data register -#define SCI_SCSSR 8 // serial status register -#define SCI_SCRDR 10 // receive data register -#define SCI_SCSPTR -4 // serial port register - -static sh_sci_info sh_serial_info = {CYGARC_REG_SCSPTR, - CYGNUM_HAL_INTERRUPT_SCI_ERI, - CYGNUM_HAL_INTERRUPT_SCI_RXI, - CYGNUM_HAL_INTERRUPT_SCI_TXI, - SH_SERIAL_SCI_BASE}; - -#if CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BUFSIZE > 0 -static unsigned char sh_serial_out_buf[CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BUFSIZE]; -static unsigned char sh_serial_in_buf[CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(sh_serial_channel, - sh_serial_funs, - sh_serial_info, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &sh_serial_out_buf[0], - sizeof(sh_serial_out_buf), - &sh_serial_in_buf[0], - sizeof(sh_serial_in_buf) - ); -#else -static SERIAL_CHANNEL(sh_serial_channel, - sh_serial_funs, - sh_serial_info, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_EDK7708_SCI_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(sh_serial_io, - CYGDAT_IO_SERIAL_SH_EDK7708_SCI_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - sh_serial_init, - sh_serial_lookup, // Serial driver may need initializing - &sh_serial_channel - ); diff --git a/packages/io/serial/current/src/sh/sh_sci_serial.c b/packages/io/serial/current/src/sh/sh_sci_serial.c deleted file mode 100644 --- a/packages/io/serial/current/src/sh/sh_sci_serial.c +++ /dev/null @@ -1,496 +0,0 @@ -//========================================================================== -// -// io/serial/sh/sh_sci_serial.c -// -// SH Serial SCI I/O Interface Module (interrupt driven) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jskov -// Contributors:gthomas, jskov -// Date: 1999-05-24 -// Purpose: SH Serial I/O module (interrupt driven version) -// Description: -// -// Note: Since interrupt sources from the same SCI channel share the same -// interrupt level, there is no risk of races when altering the -// channel's control register from ISRs and DSRs. However, when -// altering the control register from user-level code, interrupts -// must be disabled while the register is being accessed. -// -// FIXME: Receiving in polled mode prevents duplex transfers from working for -// some reason. -//####DESCRIPTIONEND#### -//========================================================================== - -#include -#include - -#include -#include -#include -#include -#include - -#include - -#ifdef CYGPKG_IO_SERIAL_SH_EDK7708 -#define __CYGPKG_IO_SERIAL_SH_SCI_INL "sh_sci_7708.inl" -#endif - - -// Only compile driver if an inline file with driver details was selected. -#ifdef __CYGPKG_IO_SERIAL_SH_SCI_INL - -static short select_word_length[] = { - -1, - -1, - CYGARC_REG_SCSMR_CHR, // 7 bits - 0 // 8 bits -}; - -static short select_stop_bits[] = { - -1, - 0, // 1 stop bit - -1, - CYGARC_REG_SCSMR_STOP // 2 stop bits -}; - -static short select_parity[] = { - 0, // No parity - CYGARC_REG_SCSMR_PE, // Even parity - CYGARC_REG_SCSMR_PE|CYGARC_REG_SCSMR_OE, // Odd parity - -1, - -1 -}; - -static unsigned short select_baud[] = { - 0, // Unused - CYGARC_SCBRR_CKSx(50)<<8 | CYGARC_SCBRR_N(50), - CYGARC_SCBRR_CKSx(75)<<8 | CYGARC_SCBRR_N(75), - CYGARC_SCBRR_CKSx(110)<<8 | CYGARC_SCBRR_N(110), - CYGARC_SCBRR_CKSx(134)<<8 | CYGARC_SCBRR_N(134), - CYGARC_SCBRR_CKSx(150)<<8 | CYGARC_SCBRR_N(150), - CYGARC_SCBRR_CKSx(200)<<8 | CYGARC_SCBRR_N(200), - CYGARC_SCBRR_CKSx(300)<<8 | CYGARC_SCBRR_N(300), - CYGARC_SCBRR_CKSx(600)<<8 | CYGARC_SCBRR_N(600), - CYGARC_SCBRR_CKSx(1200)<<8 | CYGARC_SCBRR_N(1200), - CYGARC_SCBRR_CKSx(1800)<<8 | CYGARC_SCBRR_N(1800), - CYGARC_SCBRR_CKSx(2400)<<8 | CYGARC_SCBRR_N(2400), - CYGARC_SCBRR_CKSx(3600)<<8 | CYGARC_SCBRR_N(3600), - CYGARC_SCBRR_CKSx(4800)<<8 | CYGARC_SCBRR_N(4800), - CYGARC_SCBRR_CKSx(7200)<<8 | CYGARC_SCBRR_N(7200), - CYGARC_SCBRR_CKSx(9600)<<8 | CYGARC_SCBRR_N(9600), - CYGARC_SCBRR_CKSx(14400)<<8 | CYGARC_SCBRR_N(14400), - CYGARC_SCBRR_CKSx(19200)<<8 | CYGARC_SCBRR_N(19200), - CYGARC_SCBRR_CKSx(38400)<<8 | CYGARC_SCBRR_N(38400), - CYGARC_SCBRR_CKSx(57600)<<8 | CYGARC_SCBRR_N(57600), - CYGARC_SCBRR_CKSx(115200)<<8 | CYGARC_SCBRR_N(115200), - CYGARC_SCBRR_CKSx(230400)<<8 | CYGARC_SCBRR_N(230400) -}; - - -typedef struct sh_sci_info { - CYG_ADDRWORD data; // Pointer to data register - - CYG_WORD er_int_num, // Error interrupt number - rx_int_num, // Receive interrupt number - tx_int_num; // Transmit interrupt number - - CYG_ADDRWORD ctrl_base; // Base address of SCI controller - - cyg_interrupt serial_er_interrupt, - serial_rx_interrupt, - serial_tx_interrupt; - cyg_handle_t serial_er_interrupt_handle, - serial_rx_interrupt_handle, - serial_tx_interrupt_handle; - - bool tx_enabled; -} sh_sci_info; - -static bool sh_serial_init(struct cyg_devtab_entry *tab); -static bool sh_serial_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo sh_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char sh_serial_getc(serial_channel *chan); -static bool sh_serial_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void sh_serial_start_xmit(serial_channel *chan); -static void sh_serial_stop_xmit(serial_channel *chan); - -static cyg_uint32 sh_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void sh_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, - cyg_addrword_t data); -static cyg_uint32 sh_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void sh_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, - cyg_addrword_t data); -static cyg_uint32 sh_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void sh_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count, - cyg_addrword_t data); - -static SERIAL_FUNS(sh_serial_funs, - sh_serial_putc, - sh_serial_getc, - sh_serial_set_config, - sh_serial_start_xmit, - sh_serial_stop_xmit - ); - -#include __CYGPKG_IO_SERIAL_SH_SCI_INL - -// Internal function to actually configure the hardware to desired baud rate, -// etc. -static bool -sh_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, - bool init) -{ - cyg_uint16 baud_divisor = select_baud[new_config->baud]; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - cyg_uint8 _scr, _smr; - - // Check configuration request - if ((-1 == select_word_length[(new_config->word_length - - CYGNUM_SERIAL_WORD_LENGTH_5)]) - || -1 == select_stop_bits[new_config->stop] - || -1 == select_parity[new_config->parity] - || baud_divisor == 0) - return false; - - // Disable SCI interrupts while changing hardware - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, 0); - - // Set databits, stopbits and parity. - _smr = select_word_length[(new_config->word_length - - CYGNUM_SERIAL_WORD_LENGTH_5)] | - select_stop_bits[new_config->stop] | - select_parity[new_config->parity]; - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSMR, _smr); - - // Set baud rate. - _smr &= ~CYGARC_REG_SCSMR_CKSx_MASK; - _smr |= baud_divisor >> 8; - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSMR, _smr); - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCBRR, baud_divisor & 0xff); - - // Clear the status register. - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, 0); - - if (init) { - // Always enable transmitter and receiver. - _scr = CYGARC_REG_SCSCR_TE | CYGARC_REG_SCSCR_RE; - - if (chan->out_cbuf.len != 0) - _scr |= CYGARC_REG_SCSCR_TIE; // enable tx interrupts - - if (chan->in_cbuf.len != 0) - _scr |= CYGARC_REG_SCSCR_RIE; // enable rx interrupts - } - - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - - if (new_config != &chan->config) { - chan->config = *new_config; - } - return true; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -sh_serial_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; -#ifdef CYGDBG_IO_INIT - diag_printf("SH SERIAL init - dev: %x.%d\n", - sh_chan->data, sh_chan->rx_int_num); -#endif - // Really only required for interrupt driven devices - (chan->callbacks->serial_init)(chan); - - if (chan->out_cbuf.len != 0) { - cyg_drv_interrupt_create(sh_chan->tx_int_num, - 3, - (cyg_addrword_t)chan, // Data item passed to interrupt handler - sh_serial_tx_ISR, - sh_serial_tx_DSR, - &sh_chan->serial_tx_interrupt_handle, - &sh_chan->serial_tx_interrupt); - cyg_drv_interrupt_attach(sh_chan->serial_tx_interrupt_handle); - cyg_drv_interrupt_unmask(sh_chan->tx_int_num); - sh_chan->tx_enabled = false; - } - if (chan->in_cbuf.len != 0) { - // Receive interrupt - cyg_drv_interrupt_create(sh_chan->rx_int_num, - 3, - (cyg_addrword_t)chan, // Data item passed to interrupt handler - sh_serial_rx_ISR, - sh_serial_rx_DSR, - &sh_chan->serial_rx_interrupt_handle, - &sh_chan->serial_rx_interrupt); - cyg_drv_interrupt_attach(sh_chan->serial_rx_interrupt_handle); - // Receive error interrupt - cyg_drv_interrupt_create(sh_chan->er_int_num, - 3, - (cyg_addrword_t)chan, // Data item passed to interrupt handler - sh_serial_er_ISR, - sh_serial_er_DSR, - &sh_chan->serial_er_interrupt_handle, - &sh_chan->serial_er_interrupt); - cyg_drv_interrupt_attach(sh_chan->serial_er_interrupt_handle); - // This unmasks both interrupt sources. - cyg_drv_interrupt_unmask(sh_chan->rx_int_num); - } - sh_serial_config_port(chan, &chan->config, true); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -sh_serial_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - - // Really only required for interrupt driven devices - (chan->callbacks->serial_init)(chan); - return ENOERR; -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -sh_serial_putc(serial_channel *chan, unsigned char c) -{ - cyg_uint8 _ssr; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr); - if (_ssr & CYGARC_REG_SCSSR_TDRE) { -// Transmit buffer is empty - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCTDR, c); - // Clear empty flag. - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, - CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_TDRE); - return true; - } else { -// No space - return false; - } -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -sh_serial_getc(serial_channel *chan) -{ - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - unsigned char c; - cyg_uint8 _ssr; - - do { - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr); - } while ((_ssr & CYGARC_REG_SCSSR_RDRF) == 0); - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCRDR, c); - - // Clear buffer full flag. - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, - CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF); - - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -sh_serial_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return sh_serial_config_port(chan, config, false); -} - -// Enable the transmitter on the device -static void -sh_serial_start_xmit(serial_channel *chan) -{ - cyg_uint8 _scr; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - - sh_chan->tx_enabled = true; - - // Mask the interrupts (all sources of the unit) while changing - // the CR since a rx interrupt in the middle of this would result - // in a bad CR state. - cyg_drv_interrupt_mask(sh_chan->rx_int_num); - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - _scr |= CYGARC_REG_SCSCR_TIE; // Enable xmit interrupt - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - - cyg_drv_interrupt_unmask(sh_chan->rx_int_num); -} - -// Disable the transmitter on the device -static void -sh_serial_stop_xmit(serial_channel *chan) -{ - cyg_uint8 _scr; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - - sh_chan->tx_enabled = false; - - // Mask the interrupts (all sources of the unit) while changing - // the CR since a rx interrupt in the middle of this would result - // in a bad CR state. - cyg_drv_interrupt_mask(sh_chan->rx_int_num); - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - _scr &= ~CYGARC_REG_SCSCR_TIE; // Disable xmit interrupt - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - - cyg_drv_interrupt_unmask(sh_chan->rx_int_num); -} - -// Serial I/O - low level tx interrupt handler (ISR) -static cyg_uint32 -sh_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - cyg_uint8 _scr; - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - _scr &= ~CYGARC_REG_SCSCR_TIE; // mask out tx interrupts - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level tx interrupt handler (DSR) -static void -sh_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - - (chan->callbacks->xmt_char)(chan); - - if (sh_chan->tx_enabled) { - cyg_uint8 _scr; - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - _scr |= CYGARC_REG_SCSCR_TIE; // unmask tx interrupts - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - } -} - -// Serial I/O - low level RX interrupt handler (ISR) -static cyg_uint32 -sh_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - cyg_uint8 _scr; - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - _scr &= ~CYGARC_REG_SCSCR_RIE; // mask rx interrupts - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level rx interrupt handler (DSR) -static void -sh_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - cyg_uint8 _ssr, _scr; - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr); - if (_ssr & CYGARC_REG_SCSSR_RDRF) { - cyg_uint8 _c; - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCRDR, _c); - // Clear buffer full flag. - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, - CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF); - - (chan->callbacks->rcv_char)(chan, _c); - } - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - _scr |= CYGARC_REG_SCSCR_RIE; // unmask rx interrupts - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); -} - -static volatile int sh_serial_error_orer = 0; -static volatile int sh_serial_error_fer = 0; -static volatile int sh_serial_error_per = 0; - -// Serial I/O - low level error interrupt handler (ISR) -static cyg_uint32 -sh_serial_er_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - cyg_uint8 _scr; - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - _scr &= ~CYGARC_REG_SCSCR_RIE; // mask rx interrupts - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSCR, _scr); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level error interrupt handler (DSR) -static void -sh_serial_er_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sh_sci_info *sh_chan = (sh_sci_info *)chan->dev_priv; - cyg_uint8 _ssr, _ssr2; - - HAL_READ_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr); - _ssr2 = CYGARC_REG_SCSSR_CLEARMASK; - - if (_ssr & CYGARC_REG_SCSSR_ORER) { - _ssr2 &= ~CYGARC_REG_SCSSR_ORER; - sh_serial_error_orer++; - } - if (_ssr & CYGARC_REG_SCSSR_FER) { - _ssr2 &= ~CYGARC_REG_SCSSR_FER; - sh_serial_error_fer++; - } - if (_ssr & CYGARC_REG_SCSSR_PER) { - _ssr2 &= ~CYGARC_REG_SCSSR_PER; - sh_serial_error_per++; - } - HAL_WRITE_UINT8(sh_chan->ctrl_base+SCI_SCSSR, _ssr2); -} - -#endif // ifdef __CYGPKG_IO_SERIAL_SH_SCI - diff --git a/packages/io/serial/current/src/sparclite/sleb_sdtr.c b/packages/io/serial/current/src/sparclite/sleb_sdtr.c deleted file mode 100644 --- a/packages/io/serial/current/src/sparclite/sleb_sdtr.c +++ /dev/null @@ -1,375 +0,0 @@ -//========================================================================== -// -// io/serial/sparclite/sleb_sdtr.c -// -// Serial I/O interface module for SPARClite Eval Board (SLEB) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: SLEB serial I/O module -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include -#include -#include -#include -#include -#include - -#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB - -#include "sleb_sdtr.h" - -extern void diag_printf(const char *fmt, ...); - -#define BUFSIZE 128 - -typedef struct sleb_sdtr_info { - CYG_ADDRWORD base; - CYG_WORD tx_int_num; - CYG_WORD rx_int_num; - cyg_interrupt tx_serial_interrupt; - cyg_handle_t tx_serial_interrupt_handle; - cyg_interrupt rx_serial_interrupt; - cyg_handle_t rx_serial_interrupt_handle; - cyg_uint8 cmd_reg; - bool xmit_enabled; -} sleb_sdtr_info; - -static bool sleb_sdtr_init(struct cyg_devtab_entry *tab); -static bool sleb_sdtr_putc(serial_channel *chan, unsigned char c); -static Cyg_ErrNo sleb_sdtr_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name); -static unsigned char sleb_sdtr_getc(serial_channel *chan); -static bool sleb_sdtr_set_config(serial_channel *chan, cyg_serial_info_t *config); -static void sleb_sdtr_start_xmit(serial_channel *chan); -static void sleb_sdtr_stop_xmit(serial_channel *chan); - -static cyg_uint32 sleb_sdtr_tx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void sleb_sdtr_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); -static cyg_uint32 sleb_sdtr_rx_ISR(cyg_vector_t vector, cyg_addrword_t data); -static void sleb_sdtr_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data); - -static SERIAL_FUNS(sleb_sdtr_funs, - sleb_sdtr_putc, - sleb_sdtr_getc, - sleb_sdtr_set_config, - sleb_sdtr_start_xmit, - sleb_sdtr_stop_xmit - ); - -#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1 -static sleb_sdtr_info sleb_sdtr_info0 = {SLEB_SDTR0_BASE, SLEB_SDTR0_TX_INT, SLEB_SDTR0_RX_INT}; -#if CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE > 0 -static unsigned char sleb_sdtr_out_buf0[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE]; -static unsigned char sleb_sdtr_in_buf0[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(sleb_sdtr_channel0, - sleb_sdtr_funs, - sleb_sdtr_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &sleb_sdtr_out_buf0[0], sizeof(sleb_sdtr_out_buf0), - &sleb_sdtr_in_buf0[0], sizeof(sleb_sdtr_in_buf0) - ); -#else -static SERIAL_CHANNEL(sleb_sdtr_channel0, - sleb_sdtr_funs, - sleb_sdtr_info0, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON1_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(sleb_sdtr_io0, - CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - sleb_sdtr_init, - sleb_sdtr_lookup, // Serial driver may need initializing - &sleb_sdtr_channel0 - ); -#endif // CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1 - -#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON2 -static sleb_sdtr_info sleb_sdtr_info1 = {SLEB_SDTR1_BASE, SLEB_SDTR1_TX_INT, SLEB_SDTR1_RX_INT}; -#if CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE > 0 -static unsigned char sleb_sdtr_out_buf1[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE]; -static unsigned char sleb_sdtr_in_buf1[CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BUFSIZE]; - -static SERIAL_CHANNEL_USING_INTERRUPTS(sleb_sdtr_channel1, - sleb_sdtr_funs, - sleb_sdtr_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT, - &sleb_sdtr_out_buf1[0], sizeof(sleb_sdtr_out_buf1), - &sleb_sdtr_in_buf1[0], sizeof(sleb_sdtr_in_buf1) - ); -#else -static SERIAL_CHANNEL(sleb_sdtr_channel1, - sleb_sdtr_funs, - sleb_sdtr_info1, - CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SPARCLITE_SLEB_CON2_BAUD), - CYG_SERIAL_STOP_DEFAULT, - CYG_SERIAL_PARITY_DEFAULT, - CYG_SERIAL_WORD_LENGTH_DEFAULT, - CYG_SERIAL_FLAGS_DEFAULT - ); -#endif - -DEVTAB_ENTRY(sleb_sdtr_io1, - CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON2_NAME, - 0, // Does not depend on a lower level interface - &cyg_io_serial_devio, - sleb_sdtr_init, - sleb_sdtr_lookup, // Serial driver may need initializing - &sleb_sdtr_channel1 - ); -#endif // CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON2 - -// Internal function to actually configure the hardware to desired baud rate, etc. -static bool -sleb_sdtr_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) -{ - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; - CYG_ADDRWORD port = sdtr_chan->base; - cyg_int32 baud_divisor; - cyg_int32 clk, tval; - unsigned char mode; -#if 0 - if ((new_config->baud < CYGNUM_SERIAL_BAUD_MIN) || (new_config->baud > CYGNUM_SERIAL_BAUD_MAX)) - return false; // Invalid baud rate -#endif - baud_divisor = select_baud[new_config->baud]; - if (baud_divisor == 0) - return false; // Unsupported baud rate - // Reset the port - HAL_SPARC_86940_WRITE(SDTR_CONTROL(port), SDTR_CMD_RST); - // Write the mode - mode = SDTR_MODE_MODE_ASYNC16 | - select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] | - select_stop_bits[new_config->stop] | - select_parity[new_config->parity]; - HAL_SPARC_86940_WRITE(SDTR_CONTROL(port), mode); - // Set baud rate clock. - // ***** CAUTION! Both ports use the same time, thus they must both run at the same baud rate! - clk = *SLEB_CLOCK_SWITCH; // Compute board speed - if (clk & 0x80) clk = 10; - clk = (clk & 0x3F) * 1000000; // in MHz - tval = (clk / (baud_divisor * 32)) - 1; - HAL_SPARC_86940_WRITE(SLEB_TIMER3_RELOAD, tval); - // Set up control register - sdtr_chan->cmd_reg = SDTR_CMD_RTS | SDTR_CMD_DTR | SDTR_CMD_TxEN; -#ifdef CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1 - // Cygmon needs the receiver - if ((chan->out_cbuf.len != 0) || (chan == &sleb_sdtr_channel0)) { -#else - if (chan->out_cbuf.len != 0) { -#endif - sdtr_chan->cmd_reg |= SDTR_CMD_RxEN; - } - if (init) { - sdtr_chan->xmit_enabled = false; - } - HAL_SPARC_86940_WRITE(SDTR_CONTROL(port), sdtr_chan->cmd_reg); - if (new_config != &chan->config) - chan->config = *new_config; - return true; -} - -// Function to initialize the device. Called at bootstrap time. -static bool -sleb_sdtr_init(struct cyg_devtab_entry *tab) -{ - serial_channel *chan = (serial_channel *)tab->priv; - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; -#ifdef CYGDBG_IO_INIT - diag_printf("SLEB SERIAL init - dev: %x.%d.%d\n", sdtr_chan->base, sdtr_chan->tx_int_num, sdtr_chan->rx_int_num); -#endif - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - if (chan->out_cbuf.len != 0) { - cyg_drv_interrupt_create(sdtr_chan->tx_int_num, - 99, // Priority - unused - (cyg_addrword_t)chan, // Data item passed to interrupt handler - sleb_sdtr_tx_ISR, - sleb_sdtr_tx_DSR, - &sdtr_chan->tx_serial_interrupt_handle, - &sdtr_chan->tx_serial_interrupt); - cyg_drv_interrupt_attach(sdtr_chan->tx_serial_interrupt_handle); - cyg_drv_interrupt_mask(sdtr_chan->tx_int_num); - cyg_drv_interrupt_create(sdtr_chan->rx_int_num, - 99, // Priority - unused - (cyg_addrword_t)chan, // Data item passed to interrupt handler - sleb_sdtr_rx_ISR, - sleb_sdtr_rx_DSR, - &sdtr_chan->rx_serial_interrupt_handle, - &sdtr_chan->rx_serial_interrupt); - cyg_drv_interrupt_attach(sdtr_chan->rx_serial_interrupt_handle); - cyg_drv_interrupt_unmask(sdtr_chan->rx_int_num); - } - sleb_sdtr_config_port(chan, &chan->config, true); - return true; -} - -// This routine is called when the device is "looked" up (i.e. attached) -static Cyg_ErrNo -sleb_sdtr_lookup(struct cyg_devtab_entry **tab, - struct cyg_devtab_entry *sub_tab, - const char *name) -{ - serial_channel *chan = (serial_channel *)(*tab)->priv; - (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices - return ENOERR; -} - -// Send a character to the device output buffer. -// Return 'true' if character is sent to device -static bool -sleb_sdtr_putc(serial_channel *chan, unsigned char c) -{ - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; - CYG_ADDRWORD port = sdtr_chan->base; - cyg_uint8 status; - HAL_SPARC_86940_READ(SDTR_STATUS(port), status); - if (status & SDTR_STAT_TxRDY) { -// Transmit buffer is empty - HAL_SPARC_86940_WRITE(SDTR_TXDATA(port), c); - return true; - } else { -// No space - return false; - } -} - -// Fetch a character from the device input buffer, waiting if necessary -static unsigned char -sleb_sdtr_getc(serial_channel *chan) -{ - unsigned char c; - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; - CYG_ADDRWORD port = sdtr_chan->base; - cyg_uint8 status; - HAL_SPARC_86940_READ(SDTR_STATUS(port), status); - while ((status & SDTR_STAT_RxRDY) == 0) - HAL_SPARC_86940_READ(SDTR_STATUS(port), status); // Wait for char - HAL_SPARC_86940_READ(SDTR_RXDATA(port), c); - return c; -} - -// Set up the device characteristics; baud rate, etc. -static bool -sleb_sdtr_set_config(serial_channel *chan, cyg_serial_info_t *config) -{ - return sleb_sdtr_config_port(chan, config, false); -} - -// Enable the transmitter on the device -static void -sleb_sdtr_start_xmit(serial_channel *chan) -{ - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; - sdtr_chan->xmit_enabled = true; - cyg_drv_interrupt_unmask(sdtr_chan->tx_int_num); -} - -// Disable the transmitter on the device -static void -sleb_sdtr_stop_xmit(serial_channel *chan) -{ - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; - cyg_drv_interrupt_mask(sdtr_chan->tx_int_num); - sdtr_chan->xmit_enabled = false; -} - -// Serial I/O - low level interrupt handler (ISR) -static cyg_uint32 -sleb_sdtr_tx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; - cyg_drv_interrupt_mask(sdtr_chan->tx_int_num); - cyg_drv_interrupt_acknowledge(sdtr_chan->tx_int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level interrupt handler (DSR) -static void -sleb_sdtr_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; - (chan->callbacks->xmt_char)(chan); - if (sdtr_chan->xmit_enabled) - cyg_drv_interrupt_unmask(sdtr_chan->tx_int_num); -} - -// Serial I/O - low level interrupt handler (ISR) -static cyg_uint32 -sleb_sdtr_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; - cyg_drv_interrupt_mask(sdtr_chan->rx_int_num); - return CYG_ISR_CALL_DSR; // Cause DSR to be run -} - -// Serial I/O - high level interrupt handler (DSR) -static void -sleb_sdtr_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) -{ - serial_channel *chan = (serial_channel *)data; - sleb_sdtr_info *sdtr_chan = (sleb_sdtr_info *)chan->dev_priv; - CYG_ADDRWORD port = sdtr_chan->base; - cyg_uint8 status, c; - HAL_SPARC_86940_READ(SDTR_STATUS(port), status); - if ((status & SDTR_STAT_RxRDY) != 0) { - HAL_SPARC_86940_READ(SDTR_RXDATA(port), c); - (chan->callbacks->rcv_char)(chan, c); - } - cyg_drv_interrupt_acknowledge(sdtr_chan->rx_int_num); - cyg_drv_interrupt_unmask(sdtr_chan->rx_int_num); -} - -#endif // CYGPKG_IO_SERIAL_SPARCLITE_SLEB diff --git a/packages/io/serial/current/src/sparclite/sleb_sdtr.h b/packages/io/serial/current/src/sparclite/sleb_sdtr.h deleted file mode 100644 --- a/packages/io/serial/current/src/sparclite/sleb_sdtr.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef CYGONCE_SLEB_SDTR_H -#define CYGONCE_SLEB_SDTR_H -//========================================================================== -// -// io/serial/sparclite/sleb_sdtr.c -// -// Serial I/O interface module for SPARClite Eval Board (SLEB) -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: SLEB serial I/O module -// Description: -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include // For I/O macros - -#define reg(n) ((n)*4) - -// SDTR Registers -#define SDTR_TXDATA(base) base+reg(0) -#define SDTR_RXDATA(base) base+reg(0) -#define SDTR_STATUS(base) base+reg(1) -#define SDTR_CONTROL(base) base+reg(1) - -// Mode register -#define SDTR_MODE_MODE_MASK 0x03 // Mode selection bits (mask) -#define SDTR_MODE_MODE_SYNC 0x00 // Synchronous mode -#define SDTR_MODE_MODE_ASYNC1 0x01 // Async - clock/1 -#define SDTR_MODE_MODE_ASYNC16 0x02 // Async - clock/16 -#define SDTR_MODE_MODE_ASYNC64 0x03 // Async - clock/64 -#define SDTR_MODE_DTB_MASK 0x0C // Number of data bits (mask) -#define SDTR_MODE_DTB_5 0x00 // 5 bits / char -#define SDTR_MODE_DTB_6 0x04 // 6 bits / char -#define SDTR_MODE_DTB_7 0x08 // 7 bits / char -#define SDTR_MODE_DTB_8 0x0C // 8 bits / char -#define SDTR_MODE_PARITY_MASK 0x30 // Parity modes (mask) -#define SDTR_MODE_PARITY_ENABLE 0x10 // Enable parity -#define SDTR_MODE_PARITY_NONE 0x00 // No parity (parity disabled) -#define SDTR_MODE_PARITY_ODD 0x00 // Odd parity -#define SDTR_MODE_PARITY_EVEN 0x20 // Even parity -#define SDTR_MODE_STOP_BITS_MASK 0xC0 // Number of stop bits (mask) -#define SDTR_MODE_STOP_BITS_1 0x40 // 1 stop bit -#define SDTR_MODE_STOP_BITS_1_5 0x80 // 1.5 stop bits -#define SDTR_MODE_STOP_BITS_2 0xC0 // 2 stop bits - -// Command register -#define SDTR_CMD_TxEN 0x01 // Enable transmitter -#define SDTR_CMD_DTR 0x02 // Assert DTR -#define SDTR_CMD_RxEN 0x04 // Enable receiver -#define SDTR_CMD_BREAK 0x08 // Send break -#define SDTR_CMD_EFR 0x10 // Error flag reset -#define SDTR_CMD_RTS 0x20 // Assert RTS -#define SDTR_CMD_RST 0x40 // Internal RESET -#define SDTR_CMD_EHM 0x80 // Enable Hunt mode - -// Status register -#define SDTR_STAT_TxRDY 0x01 // Transmitter ready -#define SDTR_STAT_RxRDY 0x02 // Receiver ready -#define SDTR_STAT_TxEMP 0x04 // Transmitter empty -#define SDTR_STAT_PERR 0x08 // Parity error -#define SDTR_STAT_OERR 0x10 // Overrun error -#define SDTR_STAT_FERR 0x20 // Framing error -#define SDTR_STAT_SYBRK 0x40 // Break -#define SDTR_STAT_DSR 0x80 // State of DSR signal - -// Offsets to standard SDTR elements -#define SLEB_SDTR0_BASE (8*4) -#define SLEB_SDTR0_TX_INT 9 -#define SLEB_SDTR0_RX_INT 10 -#define SLEB_SDTR1_BASE (12*4) -#define SLEB_SDTR1_TX_INT 6 -#define SLEB_SDTR1_RX_INT 7 -#define SLEB_TIMER3_CONTROL reg(29) -#define SLEB_TIMER3_RELOAD reg(30) - -// On-board switch, used to determine baud rate -#define SLEB_CLOCK_SWITCH (volatile unsigned char *)0x01000003 - -static unsigned char select_word_length[] = { - SDTR_MODE_DTB_5, // 5 bits / word (char) - SDTR_MODE_DTB_6, - SDTR_MODE_DTB_7, - SDTR_MODE_DTB_8 -}; - -static unsigned char select_stop_bits[] = { - 0, - SDTR_MODE_STOP_BITS_1, // 1 stop bit - SDTR_MODE_STOP_BITS_1_5, // 1.5 stop bit - SDTR_MODE_STOP_BITS_2 // 2 stop bits -}; - -static unsigned char select_parity[] = { - SDTR_MODE_PARITY_NONE, // No parity - SDTR_MODE_PARITY_ENABLE|SDTR_MODE_PARITY_EVEN, // Even parity - SDTR_MODE_PARITY_ENABLE|SDTR_MODE_PARITY_ODD, // ODD parity - 0xFF, // Mark parity - 0xFF, // Space parity -}; - -static cyg_int32 select_baud[] = { - 0, // Unused - 50, // 50 - 75, // 75 - 110, // 110 - 0, // 134.5 - 150, // 150 - 200, // 200 - 300, // 300 - 600, // 600 - 1200, // 1200 - 1800, // 1800 - 2400, // 2400 - 3600, // 3600 - 4800, // 4800 - 7200, // 7200 - 9600, // 9600 - 14400, // 14400 - 19200, // 19200 - 38400, // 38400 - 57600, // 57600 - 115200, // 115200 - 230400, // 230400 -}; - -#endif // CYGONCE_SLEB_SDTR_H - diff --git a/packages/io/serial/current/tests/ser_test_protocol.inl b/packages/io/serial/current/tests/ser_test_protocol.inl --- a/packages/io/serial/current/tests/ser_test_protocol.inl +++ b/packages/io/serial/current/tests/ser_test_protocol.inl @@ -122,7 +122,9 @@ # define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV # endif #endif -#if defined(CYGPKG_HAL_ARM_EBSA285) && defined(CYGPKG_IO_SERIAL_ARM_EBSA285) +#if defined(CYGPKG_HAL_ARM_EBSA285) \ + && defined(CYGPKG_IO_SERIAL_ARM_EBSA285) \ + && defined(CYGPKG_IO_SERIAL_ARM_EBSA285_SERIAL) # define TEST_CRASH_ID "arm285" # define TEST_SER_DEV CYGDAT_IO_SERIAL_ARM_EBSA285_SERIAL_NAME # if defined(CYGPKG_IO_SERIAL_TTY_TTY1) diff --git a/packages/io/serial/current/tests/serial_echo.c b/packages/io/serial/current/tests/serial_echo.c new file mode 100644 --- /dev/null +++ b/packages/io/serial/current/tests/serial_echo.c @@ -0,0 +1,118 @@ +//========================================================================== +// +// serial_echo.c +// +// Simple interactive echo test. +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov +// Contributors: jskov +// Date: 2000-04-11 +// Description: Simple echo test. +// +//####DESCRIPTIONEND#### + +#include + +#include // test macros +#include // assertion macros + +// Package requirements +#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL) + +#include + +// Package option requirements +#if defined(CYGFUN_KERNEL_API_C) + +#include // CYGNUM_HAL_STACK_SIZE_TYPICAL +#include +unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; +cyg_thread thread_data; +cyg_handle_t thread_handle; + +#include "ser_test_protocol.inl" + +//--------------------------------------------------------------------------- +// Serial test main function. +void +serial_test( void ) +{ + cyg_io_handle_t ser_handle; + cyg_uint8 in_buffer[1]; + int len = 1; + + test_open_ser(&ser_handle); + + CYG_TEST_INFO("Kill GDB and open a terminal emulator."); + CYG_TEST_INFO("This test will echo all data."); + + while (1) { + len = 1; + Tcyg_io_read(ser_handle, in_buffer, &len); + len = 1; + Tcyg_io_write(ser_handle, in_buffer, &len); + } + +} + +void +cyg_start(void) +{ + CYG_TEST_INIT(); + cyg_thread_create(10, // Priority - just a number + (cyg_thread_entry_t*)serial_test, // entry + 0, // + "serial_thread", // Name + &stack[0], // Stack + CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size + &thread_handle, // Handle + &thread_data // Thread data structure + ); + cyg_thread_resume(thread_handle); + cyg_scheduler_start(); +} + +#else // CYGFUN_KERNEL_API_C +#define N_A_MSG "Needs kernel C API" +#endif + +#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL +#define N_A_MSG "Needs IO/serial and Kernel" +#endif + +#ifdef N_A_MSG +void +cyg_start( void ) +{ + CYG_TEST_INIT(); + CYG_TEST_NA( N_A_MSG); +} +#endif // N_A_MSG +// EOF serial3.c diff --git a/packages/io/wallclock/current/ChangeLog b/packages/io/wallclock/current/ChangeLog --- a/packages/io/wallclock/current/ChangeLog +++ b/packages/io/wallclock/current/ChangeLog @@ -1,3 +1,12 @@ +2000-04-13 Jesper Skov + + * tests/wallclock.cxx: Use TEST_NA if N/A. + Split in two separate parts (accuracy & info). + +2000-04-12 Jesper Skov + + * cdl/wallclock.cdl: Don't let interfaces define anything. + 2000-04-06 Jonathan Larmour * tests/wallclock2.cxx: Test correct libc feature CDL diff --git a/packages/io/wallclock/current/cdl/wallclock.cdl b/packages/io/wallclock/current/cdl/wallclock.cdl --- a/packages/io/wallclock/current/cdl/wallclock.cdl +++ b/packages/io/wallclock/current/cdl/wallclock.cdl @@ -56,10 +56,12 @@ cdl_package CYGPKG_IO_WALLCLOCK { cdl_interface CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS { display "Number of wallclock hardware implementations" + no_define } cdl_interface CYGINT_WALLCLOCK_IMPLEMENTATIONS { display "Number of wallclock implementations" + no_define requires 1 == CYGINT_WALLCLOCK_IMPLEMENTATIONS } @@ -111,7 +113,7 @@ cdl_package CYGPKG_IO_WALLCLOCK { } cdl_option CYGPKG_IO_WALLCLOCK_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/io/wallclock/current/tests/wallclock.cxx b/packages/io/wallclock/current/tests/wallclock.cxx --- a/packages/io/wallclock/current/tests/wallclock.cxx +++ b/packages/io/wallclock/current/tests/wallclock.cxx @@ -96,10 +96,11 @@ void wallclock_thread( CYG_ADDRWORD id ) cyg_uint32 wtime; cyg_tick_count ticks; - Cyg_WallClock::wallclock->set_current_time( EPOCH ); + CYG_TEST_INFO("Testing accuracy of wallclock (10 seconds silence)"); // Check clock only every other second since the call itself may // take about a second. + Cyg_WallClock::wallclock->set_current_time( EPOCH ); for( int i = 0; i < loops; i += 2 ) { // Make a note of the time @@ -111,14 +112,37 @@ void wallclock_thread( CYG_ADDRWORD id ) CYG_TEST_FAIL_FINISH( "Clock out of sync" ); } - CYG_TEST_STILL_ALIVE(i, "2xtick..."); - // then calculate how much the above took so the delay // below can be made accurate. ticks = Cyg_Clock::real_time_clock->current_value() - ticks; th->delay( 2*one_sec - ticks ); } + + if ( ! cyg_test_is_simulator ) { + CYG_TEST_INFO("Tick output. Two seconds between each output."); + + Cyg_WallClock::wallclock->set_current_time( EPOCH ); + for( int i = 0; i < loops; i += 2 ) + { + // Make a note of the time + ticks = Cyg_Clock::real_time_clock->current_value(); + + wtime = Cyg_WallClock::wallclock->get_current_time(); + if(wtime != EPOCH+i) + { + diag_printf("wallclock drift: saw %d expected %d\n", + wtime, EPOCH+i); + } + CYG_TEST_STILL_ALIVE(i, "2xtick..."); + + // then calculate how much the above took so the delay + // below can be made accurate. + ticks = Cyg_Clock::real_time_clock->current_value() - ticks; + + th->delay( 2*one_sec - ticks ); + } + } CYG_TEST_PASS_FINISH("Wallclock OK"); diff --git a/packages/kernel/current/ChangeLog b/packages/kernel/current/ChangeLog --- a/packages/kernel/current/ChangeLog +++ b/packages/kernel/current/ChangeLog @@ -1,3 +1,10 @@ +2000-04-12 Jesper Skov + + * cdl/interrupts.cdl: + * cdl/scheduler.cdl: + * cdl/counters.cdl: + Don't let interfaces define anything. + 2000-03-28 John Dallaway * cdl/counters.cdl, diff --git a/packages/kernel/current/cdl/counters.cdl b/packages/kernel/current/cdl/counters.cdl --- a/packages/kernel/current/cdl/counters.cdl +++ b/packages/kernel/current/cdl/counters.cdl @@ -130,6 +130,7 @@ cdl_component CYGPKG_KERNEL_COUNTERS_CLO cdl_interface CYGINT_KERNEL_COUNTERS { requires 1 == CYGINT_KERNEL_COUNTERS + no_define } # NOTE: these option should really be a single enum. diff --git a/packages/kernel/current/cdl/interrupts.cdl b/packages/kernel/current/cdl/interrupts.cdl --- a/packages/kernel/current/cdl/interrupts.cdl +++ b/packages/kernel/current/cdl/interrupts.cdl @@ -59,6 +59,7 @@ cdl_component CYGIMP_KERNEL_INTERRUPTS_D cdl_interface CYGINT_KERNEL_INTERRUPTS_DSRS { requires 1 == CYGINT_KERNEL_INTERRUPTS_DSRS + no_define } # NOTE: the choice of list vs table should not be two separate diff --git a/packages/kernel/current/cdl/scheduler.cdl b/packages/kernel/current/cdl/scheduler.cdl --- a/packages/kernel/current/cdl/scheduler.cdl +++ b/packages/kernel/current/cdl/scheduler.cdl @@ -42,6 +42,7 @@ cdl_interface CYGINT_KERNEL_SCHEDULER { display "Number of schedulers in this configuration" + no_define requires 1 == CYGINT_KERNEL_SCHEDULER } diff --git a/packages/language/c/libc/current/cdl/libc.cdl b/packages/language/c/libc/current/cdl/libc.cdl --- a/packages/language/c/libc/current/cdl/libc.cdl +++ b/packages/language/c/libc/current/cdl/libc.cdl @@ -322,7 +322,7 @@ cdl_package CYGPKG_LIBC { } cdl_option CYGPKG_LIBC_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/language/c/libm/current/cdl/libm.cdl b/packages/language/c/libm/current/cdl/libm.cdl --- a/packages/language/c/libm/current/cdl/libm.cdl +++ b/packages/language/c/libm/current/cdl/libm.cdl @@ -188,7 +188,7 @@ cdl_package CYGPKG_LIBM { } cdl_option CYGPKG_LIBM_CFLAGS_REMOVE { - display "Supressed compiler flags" + display "Suppressed compiler flags" flavor data no_define default_value { "" } diff --git a/packages/templates/all/ChangeLog b/packages/templates/all/ChangeLog --- a/packages/templates/all/ChangeLog +++ b/packages/templates/all/ChangeLog @@ -1,3 +1,46 @@ +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + 2000-04-05 Jesper Skov * current.ect: Wallclock moved. diff --git a/packages/templates/all/current.ect b/packages/templates/all/current.ect --- a/packages/templates/all/current.ect +++ b/packages/templates/all/current.ect @@ -11,6 +11,7 @@ cdl_configuration template_all { description "This configuration provides all packages." ; package CYGPKG_HAL current ; package CYGPKG_IO current ; + package CYGPKG_IO_SERIAL current ; package CYGPKG_INFRA current ; package CYGPKG_KERNEL current ; package CYGPKG_LIBC current ; diff --git a/packages/templates/cygmon/ChangeLog b/packages/templates/cygmon/ChangeLog --- a/packages/templates/cygmon/ChangeLog +++ b/packages/templates/cygmon/ChangeLog @@ -1,3 +1,46 @@ +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + 2000-01-27 Jesper Skov * current.ect: Removed CYGDAT_CYGMON_ENABLE. diff --git a/packages/templates/cygmon/current.ect b/packages/templates/cygmon/current.ect --- a/packages/templates/cygmon/current.ect +++ b/packages/templates/cygmon/current.ect @@ -13,6 +13,7 @@ This is the eCos CygMon configuration. I package CYGPKG_HAL current ; package CYGPKG_INFRA current ; package CYGPKG_IO current ; + package CYGPKG_IO_SERIAL current ; package CYGPKG_ERROR current ; package CYGPKG_CYGMON current ; package CYGPKG_KERNEL current ; diff --git a/packages/templates/default/ChangeLog b/packages/templates/default/ChangeLog --- a/packages/templates/default/ChangeLog +++ b/packages/templates/default/ChangeLog @@ -1,3 +1,46 @@ +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + 2000-04-05 Jesper Skov * current.ect: Wallclock moved. diff --git a/packages/templates/default/current.ect b/packages/templates/default/current.ect --- a/packages/templates/default/current.ect +++ b/packages/templates/default/current.ect @@ -13,6 +13,7 @@ This is a default eCos configuration. It kernel, C and maths libraries, plus their support packages." ; package CYGPKG_HAL current ; package CYGPKG_IO current ; + package CYGPKG_IO_SERIAL current ; package CYGPKG_INFRA current ; package CYGPKG_KERNEL current ; package CYGPKG_LIBC current ; diff --git a/packages/templates/kernel/ChangeLog b/packages/templates/kernel/ChangeLog --- a/packages/templates/kernel/ChangeLog +++ b/packages/templates/kernel/ChangeLog @@ -1,3 +1,46 @@ +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + 1999-12-09 Bart Veer * templates/kernel directory created diff --git a/packages/templates/kernel/current.ect b/packages/templates/kernel/current.ect --- a/packages/templates/kernel/current.ect +++ b/packages/templates/kernel/current.ect @@ -11,6 +11,7 @@ cdl_configuration template_kernel { description "This configuration provides HAL, infrastructure, and the kernel packages." ; package CYGPKG_HAL current ; package CYGPKG_IO current ; + package CYGPKG_IO_SERIAL current ; package CYGPKG_INFRA current ; package CYGPKG_KERNEL current ; package CYGPKG_ERROR current ; diff --git a/packages/templates/minimal/ChangeLog b/packages/templates/minimal/ChangeLog --- a/packages/templates/minimal/ChangeLog +++ b/packages/templates/minimal/ChangeLog @@ -1,3 +1,46 @@ +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + 1999-12-09 Bart Veer * templates/minimal directory created diff --git a/packages/templates/stubs/ChangeLog b/packages/templates/stubs/ChangeLog --- a/packages/templates/stubs/ChangeLog +++ b/packages/templates/stubs/ChangeLog @@ -1,3 +1,46 @@ +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + 2000-02-18 Jonathan Larmour * current.ect: Shrink template so that it only enables a single option diff --git a/packages/templates/stubs/current.ect b/packages/templates/stubs/current.ect --- a/packages/templates/stubs/current.ect +++ b/packages/templates/stubs/current.ect @@ -13,6 +13,7 @@ This is the eCos stubs configuration. It package CYGPKG_HAL current ; package CYGPKG_INFRA current ; package CYGPKG_IO current ; + package CYGPKG_IO_SERIAL current ; package CYGPKG_ERROR current ; }; diff --git a/packages/templates/uitron/ChangeLog b/packages/templates/uitron/ChangeLog --- a/packages/templates/uitron/ChangeLog +++ b/packages/templates/uitron/ChangeLog @@ -1,3 +1,50 @@ +2000-04-07 Hugo Tyson + + * ecos.db: Re-organize device packages. This is a massive change + involving deleting all the sources for serial and ethernet drivers + from where they used to live in + packages/io/serial/current/src/ARCH/PLATFORM.[ch] + packages/net/drivers/eth/PLATFORM/current/src/... + and reinstating them in + packages/devs/serial/ARCH/PLATFORM/current/src/... + packages/devs/eth/ARCH/PLATFORM/current/src/... + + All these new packages are properly defined in ecos.db, and are + all of type "hardware" so that a "target" can grab them. + + This directory layout is descriptive of the devices we have right + now, arch and platform are separate levels just to make it easier + to navigate in the filesystem and similar to the HAL structure in + the filesystem. + + It is *not* prescriptive of future work; for example, the mythical + common highly-portable 16550 serial driver which works on many + targets would be called "devs/serial/s16550/current", or a serial + device for a particular board (cogent springs to mind) that can + work with different CPUs fitted is "devs/serial/cogent/current". + + Changelogs have been preserved and replicated over all the new + packages, so that no history is lost. + + The contents of individual source files are unchanged; they build + in just the same emvironment except for a very few cases where the + config file name changed in this movement. + + Targets in ecos.db have been redefined to bring in all relevant + hardware packages including net and serial drivers (but the newly + included packages are only active if their desired parent is + available.) + + The names of CDL options (and their #defines of course) stay the + same for the serial drivers, for backward compatibility. + + * templates/*/current.ect: these have had CYGPKG_IO_SERIAL added + rather than it being in (almost) all target definitions. + +2000-04-10 Jesper Skov + + * current.ect: Wallclock moved. + 1999-12-09 Bart Veer * templates/uitron directory created diff --git a/packages/templates/uitron/current.ect b/packages/templates/uitron/current.ect --- a/packages/templates/uitron/current.ect +++ b/packages/templates/uitron/current.ect @@ -14,12 +14,13 @@ version 3.02 of the uITRON standard, plu features." ; package CYGPKG_HAL current ; package CYGPKG_IO current ; + package CYGPKG_IO_SERIAL current ; package CYGPKG_INFRA current ; package CYGPKG_KERNEL current ; package CYGPKG_UITRON current ; package CYGPKG_LIBC current ; package CYGPKG_LIBM current ; - package CYGPKG_DEVICES_WALLCLOCK current ; + package CYGPKG_IO_WALLCLOCK current ; package CYGPKG_ERROR current ; };