From c10fa7a627eefebf62c32c406949c8f2ef9d804c Mon Sep 17 00:00:00 2001 From: jlarmour <devnull@localhost> Date: Fri, 30 Jun 2000 16:27:35 +0000 Subject: [PATCH] Merge from eCos master repository on 2000-06-30-08:18:49-BST --- host/libcdl/ChangeLog | 14 + host/libcdl/TODO | 7 + host/libcdl/cdlcore.hxx | 12 +- host/libcdl/transact.cxx | 39 +- host/libcdl/value.cxx | 9 + host/tools/configtool/ChangeLog | 7 + .../configtool/standalone/common/ChangeLog | 5 + .../configtool/standalone/common/cdl_exec.cxx | 1099 +++++++++++------ .../configtool/standalone/common/cdl_exec.hxx | 64 +- .../standalone/common/ecosconfig.cxx | 564 +++++---- .../configtool/standalone/win32/Configtool.rc | 2 +- packages/ChangeLog | 4 + packages/NEWS | 2 +- .../devs/eth/arm/ebsa285/current/ChangeLog | 21 + .../current/cdl/ebsa285_eth_drivers.cdl | 14 +- .../ebsa285/current/include/ebsa285_info.h | 6 +- .../eth/arm/ebsa285/current/src/if_ebsa285.c | 76 +- .../devs/serial/sh/cq7708/current/ChangeLog | 32 + .../sh/cq7708/current/cdl/ser_sh_cq7708.cdl | 136 ++ .../sh/cq7708/current/src/sh_sci_cq7708.inl | 98 ++ .../sh/cq7708/current/src/sh_sci_serial.c | 496 ++++++++ packages/ecos.db | 12 +- packages/hal/arm/arch/current/ChangeLog | 6 + packages/hal/arm/arch/current/src/arm_stub.c | 54 +- .../hal/arm/arch/current/src/hal_mk_defs.c | 2 + packages/hal/common/current/ChangeLog | 27 + .../common/current/include/dbg-threads-api.h | 20 +- packages/hal/common/current/include/hal_if.h | 51 +- packages/hal/common/current/src/hal_if.c | 191 ++- packages/hal/common/current/src/hal_misc.c | 25 +- packages/hal/common/current/src/hal_stub.c | 56 +- packages/hal/powerpc/arch/current/ChangeLog | 5 + .../hal/powerpc/arch/current/src/vectors.S | 26 - packages/hal/powerpc/cogent/current/ChangeLog | 14 + .../cogent/current/cdl/hal_powerpc_cogent.cdl | 22 +- .../powerpc/cogent/current/include/plf_intr.h | 16 - .../powerpc/cogent/current/include/plf_stub.h | 1 - .../hal/powerpc/cogent/current/src/hal_diag.c | 274 ++-- .../hal/powerpc/cogent/current/src/plf_misc.c | 97 -- packages/hal/powerpc/fads/current/ChangeLog | 4 + .../fads/current/cdl/hal_powerpc_fads.cdl | 16 - packages/hal/powerpc/mbx/current/ChangeLog | 6 + .../powerpc/mbx/current/include/hal_diag.h | 4 - .../hal/powerpc/mbx/current/src/hal_diag.c | 2 +- packages/hal/powerpc/quicc/current/ChangeLog | 16 + .../quicc/current/include/quicc_smc1.h | 19 +- .../powerpc/quicc/current/src/quicc_smc1.c | 246 ++-- packages/hal/powerpc/sim/current/ChangeLog | 7 + .../sim/current/cdl/hal_powerpc_sim.cdl | 2 + .../hal/powerpc/sim/current/src/hal_aux.c | 6 + packages/hal/sh/arch/current/ChangeLog | 35 + packages/hal/sh/arch/current/cdl/hal_sh.cdl | 2 +- .../hal/sh/arch/current/include/sh3_sci.h | 81 ++ .../hal/sh/arch/current/include/sh3_scif.h | 88 ++ packages/hal/sh/arch/current/src/hal_misc.c | 14 +- packages/hal/sh/arch/current/src/sh.ld | 5 +- packages/hal/sh/arch/current/src/sh3_sci.c | 303 +++++ packages/hal/sh/arch/current/src/sh3_scif.c | 337 +++++ packages/hal/sh/arch/current/src/vectors.S | 547 ++++---- packages/hal/sh/cq7708/current/ChangeLog | 20 + .../current/cdl/hal_sh_sh7708_cq7708.cdl | 36 +- .../hal/sh/cq7708/current/include/hal_diag.h | 12 + .../pkgconf/mlt_sh_sh7708_cq7708_rom.h | 4 +- .../pkgconf/mlt_sh_sh7708_cq7708_rom.ldi | 4 +- .../pkgconf/mlt_sh_sh7708_cq7708_rom.mlt | 4 +- .../hal/sh/cq7708/current/include/plf_stub.h | 28 +- packages/hal/sh/cq7708/current/src/hal_diag.c | 98 +- packages/hal/sh/cq7708/current/src/plf_misc.c | 57 +- packages/hal/sh/edk/current/ChangeLog | 27 + .../hal/sh/edk/current/cdl/hal_sh_edk7708.cdl | 36 +- .../hal/sh/edk/current/include/hal_diag.h | 12 + .../include/pkgconf/mlt_sh_edk7708_rom.h | 4 +- .../include/pkgconf/mlt_sh_edk7708_rom.ldi | 4 +- .../include/pkgconf/mlt_sh_edk7708_rom.mlt | 4 +- .../include/pkgconf/mlt_sh_edk7708_romram.h | 4 +- .../include/pkgconf/mlt_sh_edk7708_romram.ldi | 4 +- .../include/pkgconf/mlt_sh_edk7708_romram.mlt | 4 +- .../hal/sh/edk/current/include/plf_stub.h | 30 +- packages/hal/sh/edk/current/src/hal_diag.c | 103 +- packages/hal/sh/edk/current/src/plf_misc.c | 57 +- packages/hal/v85x/arch/current/ChangeLog | 9 + packages/hal/v85x/arch/current/src/hal_misc.c | 5 - .../hal/v85x/arch/current/src/hal_mk_defs.c | 2 + packages/hal/v85x/arch/current/src/vectors.S | 21 +- packages/hal/v85x/ceb_v850/current/ChangeLog | 12 + .../v85x/ceb_v850/current/include/hal_diag.h | 22 +- .../v85x/ceb_v850/current/include/plf_intr.h | 12 - .../v85x/ceb_v850/current/include/plf_stub.h | 11 +- .../hal/v85x/ceb_v850/current/src/hal_diag.c | 309 +++-- .../hal/v85x/ceb_v850/current/src/plf_misc.c | 13 +- .../hal/v85x/ceb_v850/current/src/plf_stub.c | 78 -- packages/io/serial/current/ChangeLog | 4 + .../current/tests/ser_test_protocol.inl | 9 + packages/kernel/current/ChangeLog | 8 + packages/kernel/current/include/kapi.h | 3 + packages/kernel/current/src/common/kapi.cxx | 7 + packages/net/snmp/agent/current/ChangeLog | 11 + .../agent/current/src/mibgroup/mibII/dot3.c | 4 + .../net/snmp/agent/current/src/snmptask.c | 2 +- packages/net/tcpip/current/ChangeLog | 20 + packages/net/tcpip/current/src/ecos/support.c | 167 ++- packages/net/tcpip/current/tests/ping_test.c | 59 +- packages/net/tcpip/current/tests/tcp_echo.c | 48 + 103 files changed, 4816 insertions(+), 1918 deletions(-) create mode 100644 packages/devs/serial/sh/cq7708/current/ChangeLog create mode 100644 packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl create mode 100644 packages/devs/serial/sh/cq7708/current/src/sh_sci_cq7708.inl create mode 100644 packages/devs/serial/sh/cq7708/current/src/sh_sci_serial.c create mode 100644 packages/hal/sh/arch/current/include/sh3_sci.h create mode 100644 packages/hal/sh/arch/current/include/sh3_scif.h create mode 100644 packages/hal/sh/arch/current/src/sh3_sci.c create mode 100644 packages/hal/sh/arch/current/src/sh3_scif.c diff --git a/host/libcdl/ChangeLog b/host/libcdl/ChangeLog index d485e0e5e..0051bba4a 100644 --- a/host/libcdl/ChangeLog +++ b/host/libcdl/ChangeLog @@ -1,3 +1,17 @@ +2000-06-28 Bart Veer <bartv@redhat.com> + + * transact.cxx, cdlcore.hxx: + Add details of the current transaction to the transaction callback + class. Previously there was no way of getting hold of the current + transaction and hence the toplevel from inside the callback + without using statics. + + * value.cxx (set_flavor): + Temporarily undo some of the previous value clean-ups, they were + causing problems at the application level. The API needs to be + changed to eliminate confusion between value and the data part + of a bool/value pair. + 2000-06-22 Bart Veer <bartv@redhat.com> * value.cxx, interface.cxx: diff --git a/host/libcdl/TODO b/host/libcdl/TODO index df0f8c414..950112c0a 100644 --- a/host/libcdl/TODO +++ b/host/libcdl/TODO @@ -18,6 +18,10 @@ Minor 5) make cdl_interfaces into containers? How about cdl_options as well, to avoid reparenting problems? + cdl_interfaces as containers is actually a problem because interfaces + are part of the core, and hence do not know about the existence of + options and components. + 6) allow components and options to be used interchangeably in savefiles. 7) ecosconfig, create a paths file with details of the source tree @@ -156,6 +160,9 @@ Intermediate 13) friend packages, allowing one package to see the implementation details of another. Also, handle documentation links between these. +14) API clean-up. Eliminate the confusion between "value" and the data part of + a bool/data pair. + Major ----- diff --git a/host/libcdl/cdlcore.hxx b/host/libcdl/cdlcore.hxx index be2eb8680..d019f5e77 100644 --- a/host/libcdl/cdlcore.hxx +++ b/host/libcdl/cdlcore.hxx @@ -4656,11 +4656,16 @@ class CdlTransactionCallback { friend class CdlTransactionBody; public: - CdlTransactionCallback(); ~CdlTransactionCallback(); static void (*get_callback_fn())(const CdlTransactionCallback&); static void set_callback_fn(void (*)(const CdlTransactionCallback&)); + // Callback functions should be able to retrieve information + // about the current transaction and toplevel, to avoid the use + // of statics. + CdlTransaction get_transaction() const; + CdlToplevel get_toplevel() const; + // active_changes and legal_values_changes get updated as the // transaction proceeds, so a set implementation is more // efficient. The others get filled in during a commit operation. @@ -4681,7 +4686,12 @@ class CdlTransactionCallback { protected: private: + CdlTransactionCallback(CdlTransaction); + CdlTransaction transact; + // Illegal operation. + CdlTransactionCallback(); + enum { CdlTransactionCallback_Invalid = 0, CdlTransactionCallback_Magic = 0x0cec3a95 diff --git a/host/libcdl/transact.cxx b/host/libcdl/transact.cxx index aaed42df6..533b2aa4e 100644 --- a/host/libcdl/transact.cxx +++ b/host/libcdl/transact.cxx @@ -66,12 +66,14 @@ // The callback class is very straightforward. The hard work is done in // the transaction class. -CdlTransactionCallback::CdlTransactionCallback() +CdlTransactionCallback::CdlTransactionCallback(CdlTransaction transact_arg) { CYG_REPORT_FUNCNAME("CdlTransactionCallback:: constructor"); - CYG_REPORT_FUNCARG1XV(this); - + CYG_REPORT_FUNCARG2XV(this, transact_arg); + CYG_PRECONDITION_CLASSC(transact_arg); + // The vectors etc. will take care of themselves. + transact = transact_arg; cdltransactioncallback_cookie = CdlTransactionCallback_Magic; CYG_POSTCONDITION_THISC(); @@ -85,6 +87,7 @@ CdlTransactionCallback::~CdlTransactionCallback() CYG_PRECONDITION_THISC(); cdltransactioncallback_cookie = CdlTransactionCallback_Invalid; + transact = 0; value_changes.clear(); active_changes.clear(); legal_values_changes.clear(); @@ -118,6 +121,32 @@ void (*CdlTransactionCallback::get_callback_fn())(const CdlTransactionCallback&) return result; } +CdlTransaction +CdlTransactionCallback::get_transaction() const +{ + CYG_REPORT_FUNCNAMETYPE("CdlTransactionCallback::get_transaction", "result %p"); + CYG_PRECONDITION_THISC(); + + CdlTransaction result = transact; + CYG_POSTCONDITION_CLASSC(result); + + CYG_REPORT_RETVAL(result); + return result; +} + +CdlToplevel +CdlTransactionCallback::get_toplevel() const +{ + CYG_REPORT_FUNCNAMETYPE("CdlTransactionCallback::get_toplevel", "result %p"); + CYG_PRECONDITION_THISC(); + + CdlToplevel result = transact->get_toplevel(); + CYG_POSTCONDITION_CLASSC(result); + + CYG_REPORT_RETVAL(result); + return result; +} + bool CdlTransactionCallback::check_this(cyg_assert_class_zeal zeal) const { @@ -1953,7 +1982,6 @@ CdlTransactionBody::commit() CYG_LOOP_INVARIANT_CLASSC(map_i->first); CYG_LOOP_INVARIANT_CLASSOC(map_i->second); parent->changes[map_i->first] = map_i->second; - for (conf_i = parent->new_conflicts.begin(); conf_i != parent->new_conflicts.end(); conf_i++) { CYG_LOOP_INVARIANT_CLASSC(*conf_i); (*conf_i)->update_solution_validity(map_i->first); @@ -2035,11 +2063,10 @@ CdlTransactionBody::commit() // should happen before any conflicts get deleted. The actual callback // is invoked at the end, once all the changes have been moved to // the toplevel. - CdlTransactionCallback all_changes; + CdlTransactionCallback all_changes(this); if (0 != callback_fn) { for (map_i = changes.begin(); map_i != changes.end(); map_i++) { - if (0 == map_i->first->get_toplevel()) { continue; } diff --git a/host/libcdl/value.cxx b/host/libcdl/value.cxx index 453ed3597..966fa333e 100644 --- a/host/libcdl/value.cxx +++ b/host/libcdl/value.cxx @@ -902,7 +902,16 @@ CdlValue::set_flavor(CdlValueFlavor flavor_arg) enabled[CdlValueSource_Wizard] = false; enabled[CdlValueSource_User] = false; + // BLV - keep the data part at 0 for now. There is too + // much confusion in the code between value as a string + // representation, and value as the data part of the + // bool/data pair. This needs to be fixed, but it requires + // significant API changes. +#if 0 CdlSimpleValue simple_val(cdl_int(1)); +#else + CdlSimpleValue simple_val(cdl_int(0)); +#endif values[CdlValueSource_Default] = simple_val; values[CdlValueSource_Inferred] = simple_val; values[CdlValueSource_Wizard] = simple_val; diff --git a/host/tools/configtool/ChangeLog b/host/tools/configtool/ChangeLog index b0e0eb008..8d4d2d024 100644 --- a/host/tools/configtool/ChangeLog +++ b/host/tools/configtool/ChangeLog @@ -1,3 +1,10 @@ +2000-06-27 John Dallaway <jld@redhat.com> + + * standalone/win32/Configtool.rc: + + Update menu item text: + "eCos Services Page" -> "eCos Product Page". + 2000-06-22 John Dallaway <jld@redhat.com> * standalone/common/cdl_exec.cxx: diff --git a/host/tools/configtool/standalone/common/ChangeLog b/host/tools/configtool/standalone/common/ChangeLog index e77fbde83..ef7689503 100644 --- a/host/tools/configtool/standalone/common/ChangeLog +++ b/host/tools/configtool/standalone/common/ChangeLog @@ -1,3 +1,8 @@ +2000-06-28 Bart Veer <bartv@redhat.com> + + * cdl_exec.cxx, cdl_exec.hxx, ecosconfig.cxx: + Fix up the reporting of conflicts, inference engine changes, etc. + 2000-04-10 Bart Veer <bartv@redhat.com> * cdl_exec.cxx: diff --git a/host/tools/configtool/standalone/common/cdl_exec.cxx b/host/tools/configtool/standalone/common/cdl_exec.cxx index f4c9e1e05..39a5618d7 100644 --- a/host/tools/configtool/standalone/common/cdl_exec.cxx +++ b/host/tools/configtool/standalone/common/cdl_exec.cxx @@ -39,470 +39,747 @@ //========================================================================== #ifdef _MSC_VER - #include <direct.h> /* for getcwd() */ +#include <direct.h> /* for getcwd() */ #else - #include <unistd.h> /* for getcwd() */ +#include <unistd.h> /* for getcwd() */ #endif #ifdef __CYGWIN__ - #include <sys/cygwin.h> /* for cygwin_conv_to_win32_path() */ +#include <windows.h> +#include <sys/cygwin.h> /* for cygwin_conv_to_win32_path() */ #endif #include "build.hxx" #include "cdl_exec.hxx" -cdl_exec::cdl_exec (const std::string repository_tree, const std::string savefile_name, const std::string install_tree, bool no_resolve) : - pkgdata (NULL), - interp (NULL), - config (NULL) { - repository = repository_tree; - savefile = savefile_name; - install_prefix = install_tree; - CdlTransactionBody::set_inference_callback_fn (&inference_callback); - if (no_resolve) { - CdlTransactionBody::disable_automatic_inference (); - } +// ---------------------------------------------------------------------------- +bool cdl_exec::quiet = false; +bool cdl_exec::verbose = false; +bool cdl_exec::ignore_errors = false; + +cdl_exec::cdl_exec (const std::string repository_arg, const std::string savefile_arg, + const std::string install_arg, bool no_resolve_arg) + : repository(repository_arg), + savefile(savefile_arg), + install_prefix(install_arg), + no_resolve(no_resolve_arg), + pkgdata (NULL), + interp (NULL), + config (NULL) +{ + + // The inference callback does not actually do anything at present. + // In future it may be useful for diagnostic purposes. + CdlTransactionBody::set_inference_callback_fn (&inference_callback); + + // Automatic inference is always disabled. The inference engine + // only gets invoked explicitly, after a suitable transaction callback + // has been invoked. The problem here is that the transaction callback + // has to report changes made by the inference engine but there is + // no way of distinguishing between inferred values that come out of + // savefiles and inferred values determined by the inference engine. + CdlTransactionBody::disable_automatic_inference (); } -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, &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); - if (pkgdata->is_known_template (cdl_template) && ! cdl_version.empty ()) { - const std::vector<std::string> & versions = pkgdata->get_template_versions (cdl_template); - if (versions.end () == std::find (versions.begin (), versions.end (), cdl_version)) { - throw CdlStringException ("Unknown version " + cdl_version); - } - } - config->set_template (cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler); - config->save (savefile); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +void +cdl_exec::set_quiet_mode(bool new_val) +{ + quiet = new_val; } -bool cdl_exec::cmd_target (const std::string cdl_target) { - bool status = false; - try { - 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); - config->save (savefile); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +void +cdl_exec::set_verbose_mode(bool new_val) +{ + verbose = new_val; } -bool cdl_exec::cmd_template (const std::string cdl_template, const std::string cdl_version /* = "" */) { - bool status = false; - try { - 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 ()) { - const std::vector<std::string> & versions = pkgdata->get_template_versions (cdl_template); - if (versions.end () == std::find (versions.begin (), versions.end (), cdl_version)) { - throw CdlStringException ("Unknown version " + cdl_version); - } - } - config->set_template (cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler); - config->save (savefile); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +void +cdl_exec::set_ignore_errors_mode(bool new_val) +{ + ignore_errors = new_val; } -bool cdl_exec::cmd_export (const std::string cdl_savefile) { - bool status = false; - try { - 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); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +// ---------------------------------------------------------------------------- +void +cdl_exec::init(bool load_config) +{ + pkgdata = CdlPackagesDatabaseBody::make(repository, &diagnostic_handler, &diagnostic_handler); + interp = CdlInterpreterBody::make(); + if (load_config) { + config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); + } +} + +// ---------------------------------------------------------------------------- +void +cdl_exec::delete_cdl_data () +{ + if (0 != config) { + delete config; + config = 0; + } + if (0 != interp) { + delete interp; + interp = 0; + } + if (0 != pkgdata) { + delete pkgdata; + pkgdata = 0; + } } -bool cdl_exec::cmd_import (const std::string cdl_savefile) { - bool status = false; - try { - 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); - config->save (savefile); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +// ---------------------------------------------------------------------------- +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 { + init(false); + + config = CdlConfigurationBody::make ("eCos", pkgdata, interp); + + // The hardware and template should be loaded in a single transaction. + // Validating the target name etc. can be left to libcdl. + CdlTransaction transact = CdlTransactionBody::make(config); + config->set_hardware(transact, resolve_hardware_alias(cdl_hardware), &diagnostic_handler, &diagnostic_handler); + config->set_template(transact, cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler); + transact->body(); + delete transact; + + // Unless inference has been suppressed, make sure that the + // inference engine gets invoked and that its results get + // reported. + if (!no_resolve) { + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts(); + } + + // Now report any conflicts which the inference engine could not report. + report_conflicts(); + + // A savefile should be generated/updated even if there are conflicts. + // Otherwise the user does not have a chance to edit the savefile + // and fix things. + config->save (savefile); + if (ignore_errors || (0 == config->get_all_conflicts().size())) { + status = true; + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; } -bool cdl_exec::cmd_add (const std::vector<std::string> cdl_packages) { - bool status = false; - try { - 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++) { - config->load_package (resolve_package_alias (cdl_packages [n]), "", &diagnostic_handler, &diagnostic_handler); - } - config->save (savefile); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_target (const std::string cdl_target) +{ + bool status = false; + try { + init(true); + config->set_hardware (resolve_hardware_alias (cdl_target), &diagnostic_handler, &diagnostic_handler); + if (!no_resolve) { + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts(); + } + report_conflicts(); + config->save (savefile); + if (ignore_errors || (0 == config->get_all_conflicts().size())) { + status = true; + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; } -bool cdl_exec::cmd_remove (const std::vector<std::string> cdl_packages) { - unsigned int n; - bool status = false; - try { - 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++) { - if (! config->lookup (resolve_package_alias (cdl_packages [n]))) { - throw CdlStringException ("Unknown package " + cdl_packages [n]); - } - } - for (n = 0; n < cdl_packages.size (); n++) { - config->unload_package (resolve_package_alias (cdl_packages [n])); - } - config->save (savefile); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_template (const std::string cdl_template, const std::string cdl_version /* = "" */) +{ + bool status = false; + try { + init(true); + config->set_template (cdl_template, cdl_version, &diagnostic_handler, &diagnostic_handler); + if (!no_resolve) { + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts(); + } + report_conflicts(); + config->save (savefile); + if (ignore_errors || (0 == config->get_all_conflicts().size())) { + status = true; + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; } -bool cdl_exec::cmd_version (const std::string cdl_version, const std::vector<std::string> cdl_packages) { - bool status = false; - try { - 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++) { - config->change_package_version (resolve_package_alias (cdl_packages [n]), cdl_version, &diagnostic_handler, &diagnostic_handler, true); - } - config->save (savefile); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_export (const std::string cdl_savefile) +{ + bool status = false; + try { + init(true); + if (!no_resolve) { + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts(); + } + report_conflicts(); + // Exporting to another file should only happen if the + // configuration is conflict-free. This is different from + // updating the savefile. + if (ignore_errors || (0 == config->get_all_conflicts().size())) { + config->save (cdl_savefile, /* minimal = */ true); + status = true; + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; } -bool cdl_exec::cmd_tree () { - bool status = false; - try { - pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); - interp = CdlInterpreterBody::make (); - config = CdlConfigurationBody::load (savefile, pkgdata, interp, &diagnostic_handler, &diagnostic_handler); +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_import (const std::string cdl_savefile) +{ + bool status = false; + try { + init(true); + config->add(cdl_savefile, &diagnostic_handler, &diagnostic_handler); + if (!no_resolve) { + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts(); + } + report_conflicts(); + config->save (savefile); + if (ignore_errors || (0 == config->get_all_conflicts().size())) { + status = true; + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; +} + +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_add (const std::vector<std::string> cdl_packages) +{ + bool status = false; + try { + init(true); + for (unsigned int n = 0; n < cdl_packages.size (); n++) { + config->load_package (resolve_package_alias (cdl_packages [n]), "", &diagnostic_handler, &diagnostic_handler); + } + if (!no_resolve) { + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts(); + } + report_conflicts(); + config->save (savefile); + if (ignore_errors || (0 == config->get_all_conflicts().size())) { + status = true; + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; +} + +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_remove (const std::vector<std::string> cdl_packages) +{ + unsigned int n; + bool status = false; + try { + init(true); + for (n = 0; n < cdl_packages.size (); n++) { + if (! config->lookup (resolve_package_alias (cdl_packages [n]))) { + throw CdlStringException ("Unknown package " + cdl_packages [n]); + } + } + for (n = 0; n < cdl_packages.size (); n++) { + config->unload_package (resolve_package_alias (cdl_packages [n])); + } + if (!no_resolve) { + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts(); + } + report_conflicts(); + config->save (savefile); + if (ignore_errors || (0 == config->get_all_conflicts().size())) { + status = true; + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; +} + +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_version (const std::string cdl_version, const std::vector<std::string> cdl_packages) +{ + bool status = false; + try { + init(true); + for (unsigned int n = 0; n < cdl_packages.size (); n++) { + config->change_package_version(resolve_package_alias (cdl_packages [n]), cdl_version, + &diagnostic_handler, &diagnostic_handler, true); + } + if (!no_resolve) { + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts(); + } + report_conflicts(); + config->save (savefile); + if (ignore_errors || (0 == config->get_all_conflicts().size())) { + status = true; + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; +} + +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_tree () +{ + bool status = false; + try { + init(true); + if (!no_resolve) { + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts(); + } + report_conflicts(); + config->save (savefile); + // A build tree should only be generated if there are no conflicts. + if (ignore_errors || (0 == config->get_all_conflicts().size())) { #ifdef _MSC_VER - char cwd [_MAX_PATH + 1]; + char cwd [_MAX_PATH + 1]; #else - char cwd [PATH_MAX + 1]; + char cwd [PATH_MAX + 1]; #endif - getcwd (cwd, sizeof cwd); + getcwd (cwd, sizeof cwd); #ifdef __CYGWIN__ - char cwd_win32 [MAXPATHLEN + 1]; - cygwin_conv_to_win32_path (cwd, cwd_win32); - generate_build_tree (config, cwd_win32, install_prefix); + char cwd_win32 [MAXPATHLEN + 1]; + cygwin_conv_to_win32_path (cwd, cwd_win32); + generate_build_tree (config, cwd_win32, install_prefix); #else - generate_build_tree (config, cwd, install_prefix); + generate_build_tree (config, cwd, install_prefix); #endif - config->generate_config_headers (install_prefix.empty () ? "install/include/pkgconf" : install_prefix + "/include/pkgconf"); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; + config->generate_config_headers (install_prefix.empty () ? "install/include/pkgconf" : install_prefix + "/include/pkgconf"); + status = true; + } else { + printf("\nUnable to generate build tree, this configuration still contains conflicts.\n"); + printf("Either resolve the conflicts or use --ignore-errors\n"); + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; } -bool cdl_exec::cmd_list () { - bool status = false; - try { - pkgdata = CdlPackagesDatabaseBody::make (repository, &diagnostic_handler, &diagnostic_handler); - - // list the installed packages - std::vector<std::string> packages = pkgdata->get_packages (); - std::sort (packages.begin (), packages.end ()); - for (unsigned int package = 0; package < packages.size (); package++) { - const std::vector<std::string> & 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 ()); - } - const std::vector<std::string> & versions = pkgdata->get_package_versions (packages [package]); - printf ("\n versions:"); - for (unsigned int version = 0; version < versions.size (); version++) { - printf (" %s", versions [version].c_str ()); - } - printf ("\n"); - } - - // list the available targets - std::vector<std::string> targets = pkgdata->get_targets (); - std::sort (targets.begin (), targets.end ()); - for (unsigned int target = 0; target < targets.size (); target++) { - const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [target]); - printf ("Target %s (%s):\n aliases:", targets [target].c_str (), aliases [0].c_str ()); - for (unsigned int alias = 1; alias < aliases.size (); alias++) { - printf (" %s", aliases [alias].c_str ()); - } - printf ("\n"); - } - - // list the available templates - std::vector<std::string> templates = pkgdata->get_templates (); - std::sort (templates.begin (), templates.end ()); - for (unsigned int templ = 0; templ < templates.size (); templ++) { - const std::vector<std::string> & versions = pkgdata->get_template_versions (templates [templ]); - printf ("Template %s:\n versions:", templates [templ].c_str ()); - for (unsigned int version = 0; version < versions.size (); version++) { - printf (" %s", versions [version].c_str ()); - } - printf ("\n"); - } - - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_list () +{ + bool status = false; + try { + init(false); + + // list the installed packages + std::vector<std::string> packages = pkgdata->get_packages (); + std::sort (packages.begin (), packages.end ()); + for (unsigned int package = 0; package < packages.size (); package++) { + const std::vector<std::string> & 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 ()); + } + const std::vector<std::string> & versions = pkgdata->get_package_versions (packages [package]); + printf ("\n versions:"); + for (unsigned int version = 0; version < versions.size (); version++) { + printf (" %s", versions [version].c_str ()); + } + printf ("\n"); + } + + // list the available targets + std::vector<std::string> targets = pkgdata->get_targets (); + std::sort (targets.begin (), targets.end ()); + for (unsigned int target = 0; target < targets.size (); target++) { + const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [target]); + printf ("Target %s (%s):\n aliases:", targets [target].c_str (), aliases [0].c_str ()); + for (unsigned int alias = 1; alias < aliases.size (); alias++) { + printf (" %s", aliases [alias].c_str ()); + } + printf ("\n"); + } + + // list the available templates + std::vector<std::string> templates = pkgdata->get_templates (); + std::sort (templates.begin (), templates.end ()); + for (unsigned int templ = 0; templ < templates.size (); templ++) { + const std::vector<std::string> & versions = pkgdata->get_template_versions (templates [templ]); + printf ("Template %s:\n versions:", templates [templ].c_str ()); + for (unsigned int version = 0; version < versions.size (); version++) { + printf (" %s", versions [version].c_str ()); + } + printf ("\n"); + } + + status = true; + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; } -bool cdl_exec::cmd_check () { - bool status = false; - unsigned int n; - - try { - CdlTransactionBody::disable_automatic_inference (); - 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 - - // report current target and template - printf ("Target: %s\n", config->get_hardware ().c_str ()); - printf ("Template: %s\n", config->get_template ().c_str ()); - std::vector<std::string> template_packages = pkgdata->get_template_packages (config->get_template ()); - const std::vector<std::string> & hardware_packages = pkgdata->get_target_packages (config->get_hardware ()); - for (n = 0; n < hardware_packages.size (); n++) { - template_packages.push_back (hardware_packages [n]); - } - - // report loaded packages not in the templates - const std::vector<CdlLoadable> & loadables = config->get_loadables (); - std::vector<std::string> added_packages; - std::vector<CdlLoadable>::const_iterator loadable_i; - for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) { - const CdlNode & node = dynamic_cast<CdlNode> (* loadable_i); - if (template_packages.end () == std::find (template_packages.begin (), template_packages.end (), node->get_name ())) { - added_packages.push_back (node->get_name ()); - } - } - if (added_packages.size ()) { - printf ("Added:\n"); - } - for (n = 0; n < added_packages.size (); n++) { - printf (" %s\n", added_packages [n].c_str ()); - } - - // report template packages not in the configuration - std::vector<std::string> removed_packages; - for (n = 0; n < template_packages.size (); n++) { - if (! config->lookup (template_packages [n])) { - removed_packages.push_back (template_packages [n]); - } - } - if (removed_packages.size ()) { - printf ("Removed:\n"); - } - for (n = 0; n < removed_packages.size (); n++) { - printf (" %s\n", removed_packages [n].c_str ()); - } - - // report packages of non-default version - std::vector<CdlValuable> version_packages; - for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) { - const CdlValuable & valuable = dynamic_cast<CdlValuable> (* loadable_i); - if (pkgdata->get_package_versions (valuable->get_name ()) [0] != valuable->get_value ()) { - version_packages.push_back (valuable); - } - } - if (version_packages.size ()) { - printf ("Version(s):\n"); - } - for (n = 0; n < version_packages.size (); n++) { - printf (" %s %s\n", version_packages [n]->get_name ().c_str (), version_packages [n]->get_value ().c_str ()); - } - - // report conflicts - const std::list<CdlConflict> & conflicts = config->get_all_conflicts (); - if (conflicts.size ()) { - printf ("%u conflict(s):\n", conflicts.size ()); - } else { - printf ("No conflicts\n"); - } - std::list<CdlConflict>::const_iterator conf_i; - for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) { // for each conflict - report_conflict (* conf_i); - } - - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_check () +{ + bool status = false; + unsigned int n; + + try { + init(true); + // check() should never invoke the inference engine. The user + // wants to determine the current status, which should not + // change. + // However, updating the savefile is worthwhile because it + // will now contain more accurate information about the state. + config->save (savefile); + + // report current target and template + printf ("Target: %s\n", config->get_hardware ().c_str ()); + printf ("Template: %s\n", config->get_template ().c_str ()); + std::vector<std::string> template_packages = pkgdata->get_template_packages (config->get_template ()); + const std::vector<std::string> & hardware_packages = pkgdata->get_target_packages (config->get_hardware ()); + for (n = 0; n < hardware_packages.size (); n++) { + template_packages.push_back (hardware_packages [n]); + } + + // report loaded packages not in the templates + const std::vector<CdlLoadable> & loadables = config->get_loadables (); + std::vector<std::string> added_packages; + std::vector<CdlLoadable>::const_iterator loadable_i; + for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) { + const CdlNode & node = dynamic_cast<CdlNode> (* loadable_i); + if (template_packages.end () == std::find (template_packages.begin (), template_packages.end (), node->get_name ())) { + added_packages.push_back (node->get_name ()); + } + } + if (added_packages.size ()) { + printf ("Added:\n"); + } + for (n = 0; n < added_packages.size (); n++) { + printf (" %s\n", added_packages [n].c_str ()); + } + + // report template packages not in the configuration + std::vector<std::string> removed_packages; + for (n = 0; n < template_packages.size (); n++) { + if (! config->lookup (template_packages [n])) { + removed_packages.push_back (template_packages [n]); + } + } + if (removed_packages.size ()) { + printf ("Removed:\n"); + } + for (n = 0; n < removed_packages.size (); n++) { + printf (" %s\n", removed_packages [n].c_str ()); + } + + // report packages of non-default version + std::vector<CdlValuable> version_packages; + for (loadable_i = loadables.begin (); loadable_i != loadables.end (); loadable_i++) { + const CdlValuable & valuable = dynamic_cast<CdlValuable> (* loadable_i); + if (pkgdata->get_package_versions (valuable->get_name ()) [0] != valuable->get_value ()) { + version_packages.push_back (valuable); + } + } + if (version_packages.size ()) { + printf ("Version(s):\n"); + } + for (n = 0; n < version_packages.size (); n++) { + printf (" %s %s\n", version_packages [n]->get_name ().c_str (), version_packages [n]->get_value ().c_str ()); + } + + // report conflicts + const std::list<CdlConflict> & conflicts = config->get_all_conflicts (); + if (conflicts.size ()) { + printf ("%u conflict(s):\n", conflicts.size ()); + } else { + printf ("No conflicts\n"); + } + report_conflicts(); + + status = true; + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; } -bool cdl_exec::cmd_resolve () { - bool status = false; - - try { - 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 (); - config->save (savefile); - status = true; - } catch (CdlStringException exception) { - exception_handler (exception); - } catch (...) { - exception_handler (); - } - - delete_cdl_data (); - return status; +// ---------------------------------------------------------------------------- +bool +cdl_exec::cmd_resolve () +{ + bool status = false; + + try { + init(true); + CdlTransactionBody::set_callback_fn(&transaction_callback); + config->resolve_all_conflicts (); + report_conflicts(); + config->save (savefile); + if (ignore_errors || (0 == config->get_all_conflicts().size())) { + status = true; + } + } catch (CdlStringException exception) { + exception_handler (exception); + } catch (...) { + exception_handler (); + } + + delete_cdl_data (); + return status; } -CdlInferenceCallbackResult cdl_exec::inference_callback (CdlTransaction transaction) { - const std::vector<CdlConflict> & resolved_conflicts = transaction->get_resolved_conflicts (); +// ---------------------------------------------------------------------------- +// The inference callback. This could give some useful diagnostics, or it +// could do useful things when running in some interactive mode. In batch +// mode it should not do anything. + +CdlInferenceCallbackResult +cdl_exec::inference_callback (CdlTransaction transaction) +{ + return CdlInferenceCallbackResult_Continue; +} - // report resolved conflicts - if (resolved_conflicts.size ()) { - printf ("%u conflict(s) resolved:\n", resolved_conflicts.size ()); - } - for (unsigned int n = 0; n < resolved_conflicts.size (); n++) { - report_conflict (resolved_conflicts [n]); - } +// ---------------------------------------------------------------------------- +// Output a message with indentation after newlines. +static void +dump_string(unsigned int indent, const std::string& str) +{ + bool newline_pending = false; + unsigned int i, j; + for (i = 0; i < str.size(); i++) { + if (newline_pending) { + putchar('\n'); + if ('\n' != str[i]) { + for (j = 0; j < indent; j++) { + putchar(' '); + } + } + newline_pending = false; + } + if ('\n' == str[i]) { + newline_pending = true; + } else { + putchar(str[i]); + } + } + if (newline_pending) { + putchar('\n'); // But not the indentation. + } +} - // accept all changes - return CdlInferenceCallbackResult_Continue; +// ---------------------------------------------------------------------------- +// The transaction callback. This should report any changes that have been +// made to the configuration. The amount of output depends on the verbosity +// level selected by the user. +// +// 1) quiet - no output at all +// 2) default - list updates done by the inference engine. +// 3) verbose - this does not currently add anything. +// +// There is no reporting of new or resolved conflicts. Resolved +// conflicts are probably of no interest in batch mode. New conflicts +// will be handled by report_conflicts(). There is also no information +// given about active state changes, although arguably there should be +// especially in the case of containers. + +void +cdl_exec::transaction_callback(const CdlTransactionCallback& callback_data) +{ + if (quiet) { + return; + } + + unsigned int i; + for (i = 0; i < callback_data.value_changes.size(); i++) { + CdlValuable valuable = callback_data.value_changes[i]; + if (CdlValueSource_Inferred == valuable->get_source()) { + std::string msg = std::string("U ") + valuable->get_name() + ", new inferred value "; + std::string value = valuable->get_value(); + if ("" == value) { + msg += "\"\""; + } else { + msg += value; + } + msg += "\n"; + dump_string(4, msg); + } + } } -void cdl_exec::report_conflict (CdlConflict conflict) { - printf (" %s:\n %s\n", conflict->get_node ()->get_name ().c_str (), conflict->get_explanation ().c_str ()); +// ---------------------------------------------------------------------------- +// Report the remaining conflicts in the configuration. These indicate +// problems that the user should fix before going further with the +// configuration, e.g. before generating a build tree. +// +// Quiet verbosity level has no effect on this, but at the verbose level +// it is a good idea to look for a possible solution to the conflict. + + +void +cdl_exec::report_conflicts() +{ + const std::list<CdlConflict>& all_conflicts = config->get_all_conflicts(); + std::list<CdlConflict>::const_iterator conf_i; + for (conf_i = all_conflicts.begin(); conf_i != all_conflicts.end(); conf_i++) { + CdlNode node = (*conf_i)->get_node(); + + std::string msg = std::string("C ") + node->get_name() + ", " + (*conf_i)->get_explanation() + "\n"; + dump_string(2, msg); + + if (verbose && (*conf_i)->resolution_implemented()) { + // See if there is a possible solution to this conflict. + // This involves creating a transaction, invoking the + // inference engine, and cancelling the transaction + // (thus making sure that nothing actually changes). + // + // NOTE: at some stage libcdl may keep track of solutions + // globally. However, although it will know when a solution + // becomes invalid it will not necessarily try to resolve + // all global conflicts after every change, so attempting + // to do this in a transaction may still be necessary. + CdlTransaction transact = CdlTransactionBody::make(config); + transact->resolve(*conf_i); + if ((*conf_i)->has_known_solution()) { + std::string soln_msg = " Possible solution:\n"; + const std::vector<std::pair<CdlValuable, CdlValue> > & soln = (*conf_i)->get_solution(); + unsigned int i; + for (i = 0; i < soln.size(); i++) { + soln_msg += soln[i].first->get_name() + " -> " + soln[i].second.get_value() + "\n"; + } +#if 0 + // FIXME: currently this member only works for nested sub-transactions. + if (transact->user_confirmation_required()) { + msg += "This change affects previous user settings.\n"; + } +#endif + dump_string(4, soln_msg); + } + transact->cancel(); + delete transact; + } + } } -void cdl_exec::diagnostic_handler (std::string message) { - printf ("%s\n", message.c_str ()); +// ---------------------------------------------------------------------------- +void +cdl_exec::diagnostic_handler (std::string message) +{ + printf ("%s\n", message.c_str ()); } void cdl_exec::exception_handler (CdlStringException exception) { - printf ("%s\n", exception.get_message ().c_str ()); + printf ("%s\n", exception.get_message ().c_str ()); } -void cdl_exec::exception_handler () { - printf ("Unknown error\n"); +void +cdl_exec::exception_handler () +{ + printf ("Unknown error\n"); } -void cdl_exec::delete_cdl_data () { - delete config; - config = NULL; - delete interp; - interp = NULL; - delete pkgdata; - pkgdata = NULL; -} -std::string cdl_exec::resolve_package_alias (const std::string alias) { - std::string package = alias; - - if (! pkgdata->is_known_package (alias)) { // if the alias is not a package name - const std::vector<std::string> & packages = pkgdata->get_packages (); // get packages - for (unsigned int n = 0; n < packages.size (); n++) { // for each package - const std::vector<std::string> & aliases = pkgdata->get_package_aliases (packages [n]); // get package aliases - if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found - package = packages [n]; // note the package - break; - } - } - } - return package; +// ---------------------------------------------------------------------------- +std::string +cdl_exec::resolve_package_alias (const std::string alias) +{ + std::string package = alias; + + if (! pkgdata->is_known_package (alias)) { // if the alias is not a package name + const std::vector<std::string> & packages = pkgdata->get_packages (); // get packages + for (unsigned int n = 0; n < packages.size (); n++) { // for each package + const std::vector<std::string> & aliases = pkgdata->get_package_aliases (packages [n]); // get package aliases + if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found + package = packages [n]; // note the package + break; + } + } + } + return package; } -std::string cdl_exec::resolve_hardware_alias (const std::string alias) { - std::string target = alias; - - if (! pkgdata->is_known_target (alias)) { // if the alias is not a target name - const std::vector<std::string> & targets = pkgdata->get_targets (); // get targets - for (unsigned int n = 0; n < targets.size (); n++) { // for each target - const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [n]); // get target aliases - if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found - target = targets [n]; // note the target - break; - } - } - } - return target; +std::string +cdl_exec::resolve_hardware_alias (const std::string alias) +{ + std::string target = alias; + + if (! pkgdata->is_known_target (alias)) { // if the alias is not a target name + const std::vector<std::string> & targets = pkgdata->get_targets (); // get targets + for (unsigned int n = 0; n < targets.size (); n++) { // for each target + const std::vector<std::string> & aliases = pkgdata->get_target_aliases (targets [n]); // get target aliases + if (aliases.end () != std::find (aliases.begin (), aliases.end (), alias)) { // if alias is found + target = targets [n]; // note the target + break; + } + } + } + return target; } diff --git a/host/tools/configtool/standalone/common/cdl_exec.hxx b/host/tools/configtool/standalone/common/cdl_exec.hxx index ed0f6c0b6..1c1d297ba 100644 --- a/host/tools/configtool/standalone/common/cdl_exec.hxx +++ b/host/tools/configtool/standalone/common/cdl_exec.hxx @@ -26,33 +26,43 @@ class cdl_exec { public: - cdl_exec (const std::string repository_tree, const std::string savefile_name, const std::string install_tree, bool no_resolve); - bool cmd_new (const std::string cdl_hardware, const std::string cdl_template = "default", const std::string cdl_version = ""); - bool cmd_tree (); - bool cmd_check (); - bool cmd_list (); - bool cmd_add (const std::vector<std::string> cdl_packages); - bool cmd_remove (const std::vector<std::string> cdl_packages); - bool cmd_version (const std::string cdl_version, const std::vector<std::string> cdl_packages); - bool cmd_template (const std::string cdl_template, const std::string cdl_version = ""); - bool cmd_export (const std::string cdl_savefile); - bool cmd_import (const std::string cdl_savefile); - bool cmd_target (const std::string cdl_target); - bool cmd_resolve (); + cdl_exec (const std::string repository_tree, const std::string savefile_name, const std::string install_tree, bool no_resolve); + bool cmd_new (const std::string cdl_hardware, const std::string cdl_template = "default", const std::string cdl_version = ""); + bool cmd_tree (); + bool cmd_check (); + bool cmd_list (); + bool cmd_add (const std::vector<std::string> cdl_packages); + bool cmd_remove (const std::vector<std::string> cdl_packages); + bool cmd_version (const std::string cdl_version, const std::vector<std::string> cdl_packages); + bool cmd_template (const std::string cdl_template, const std::string cdl_version = ""); + bool cmd_export (const std::string cdl_savefile); + bool cmd_import (const std::string cdl_savefile); + bool cmd_target (const std::string cdl_target); + bool cmd_resolve (); + static void set_quiet_mode(bool); + static void set_verbose_mode(bool); + static void set_ignore_errors_mode(bool); + protected: - std::string repository; - std::string savefile; - std::string install_prefix; - CdlPackagesDatabase pkgdata; - CdlInterpreter interp; - CdlConfiguration config; - void delete_cdl_data (); - static void diagnostic_handler (std::string message); - void exception_handler (CdlStringException exception); - void exception_handler (); - static void report_conflict (CdlConflict conflict); - static CdlInferenceCallbackResult inference_callback (CdlTransaction transaction); - std::string resolve_package_alias (const std::string alias); - std::string resolve_hardware_alias (const std::string alias); + static bool quiet; + static bool verbose; + static bool ignore_errors; + std::string repository; + std::string savefile; + std::string install_prefix; + bool no_resolve; + CdlPackagesDatabase pkgdata; + CdlInterpreter interp; + CdlConfiguration config; + void init(bool /* load */); + void delete_cdl_data (); + static void diagnostic_handler (std::string message); + void exception_handler (CdlStringException exception); + void exception_handler (); + void report_conflicts(); + static CdlInferenceCallbackResult inference_callback (CdlTransaction transaction); + static void transaction_callback(const CdlTransactionCallback&); + std::string resolve_package_alias (const std::string alias); + std::string resolve_hardware_alias (const std::string alias); }; diff --git a/host/tools/configtool/standalone/common/ecosconfig.cxx b/host/tools/configtool/standalone/common/ecosconfig.cxx index 52cbaa34e..3e98a831b 100644 --- a/host/tools/configtool/standalone/common/ecosconfig.cxx +++ b/host/tools/configtool/standalone/common/ecosconfig.cxx @@ -39,11 +39,12 @@ //========================================================================== #ifndef _MSC_VER - #include <sys/param.h> - #include <unistd.h> /* for realpath() */ +#include <sys/param.h> +#include <unistd.h> /* for realpath() */ #endif #ifdef __CYGWIN__ - #include <sys/cygwin.h> /* for cygwin_conv_to_win32_path() */ +#include <windows.h> +#include <sys/cygwin.h> /* for cygwin_conv_to_win32_path() */ #endif #include "cdl_exec.hxx" #include "ecosconfig.hxx" @@ -51,243 +52,376 @@ #define TOOL_VERSION "1.3.net" #define TOOL_COPYRIGHT "Copyright (c) 2000 Red Hat, Inc." #define DEFAULT_SAVE_FILE "ecos.ecc" +static char* tool = "ecosconfig"; int main (int argc, char * argv []) { - // process command qualifiers - std::string repository; // --srcdir= - std::string savefile; // --config= - std::string install_prefix; // --prefix= - bool version = false; // --version - bool no_resolve = false; // --no-resolve - int command_index; - for (command_index = 1; command_index < argc; command_index++) { // for each command line argument - if (0 == strncmp (argv [command_index], "--srcdir=", 9)) { - repository = & argv [command_index] [9]; - } else if (0 == strncmp (argv [command_index], "--config=", 9)) { - savefile = & argv [command_index] [9]; - } else if (0 == strncmp (argv [command_index], "--prefix=", 9)) { - install_prefix = & argv [command_index] [9]; - } else if (0 == strcmp (argv [command_index], "--version")) { - version = true; - } else if (0 == strcmp (argv [command_index], "--no-resolve")) { - no_resolve = true; - } else { // the argument is not a qualifier - break; // end of qualifiers - } - } + // process command qualifiers + std::string repository; // --srcdir= + std::string savefile; // --config= + std::string install_prefix; // --prefix= + bool version = false; // --version + bool no_resolve = false; // --no-resolve + bool quiet = false; // -q, --quiet + bool verbose = false; // -v, --verbose + bool ignore_errors = false; // -i, --ignore-errors + bool help = false; // --help + + // getopt() cannot easily be used here since this code has to + // build with VC++ as well. + bool args_ok = true; + int command_index; + for (command_index = 1; command_index < argc; command_index++) { // for each command line argument + char* arg = argv[command_index]; + if (0 == strcmp(arg, "--help")) { + help = true; + } else if ((0 == strcmp(arg, "-q")) || (0 == strcmp(arg, "--quiet"))) { + // Allow repeated use of -q and -v to override each other. + // This is useful in conjunction with shell aliases. + quiet = true; + verbose = false; + } else if ((0 == strcmp(arg, "-v")) || (0 == strcmp(arg, "--verbose"))) { + verbose = true; + quiet = false; + } else if ((0 == strcmp(arg, "-i")) || (0 == strcmp(arg, "--ignore-errors"))) { + // Duplicate use of -i and the other flags is harmless. + ignore_errors = true; + } else if (0 == strcmp(arg, "--version")) { + version = true; + } else if (0 == strcmp(arg, "--no-resolve")) { + no_resolve = true; + } else if (0 == strncmp(arg, "--srcdir", 8)) { + // Duplicate use of --srcdir and other data-containing options should + // be marked as an error. + if ("" != repository) { + fprintf(stderr, "%s: the `--srcdir' option should be used only once.\n", tool); + args_ok = false; + } else { + if ('=' == arg[8]) { + repository = std::string(arg + 9); + if ("" == repository) { + fprintf(stderr, "%s: missing component repository after `--srcdir='\n", tool); + args_ok = false; + } + } else if ('\0' == arg[8]) { + command_index++; + if (command_index == argc) { + fprintf(stderr, "%s: missing component repository after `--srcdir'\n", tool); + args_ok = false; + } else { + repository = argv[command_index]; + } + } else { + fprintf(stderr, "%s: invalid option `%s'\n", tool, arg); + args_ok = false; + } + } + } else if (0 == strncmp(arg, "--config", 8)) { + if ("" != savefile) { + fprintf(stderr, "%s: the `--config' option should be used only once.\n", tool); + args_ok = false; + } else { + if ('=' == arg[8]) { + savefile = std::string(arg + 9); + if ("" == savefile) { + fprintf(stderr, "%s: missing configuration savefile after `--config='\n", tool); + args_ok = false; + } + } else if ('\0' == arg[8]) { + command_index++; + if (command_index == argc) { + fprintf(stderr, "%s: missing configuration savefile after `--config'\n", tool); + args_ok = false; + } else { + savefile = argv[command_index]; + } + } else { + fprintf(stderr, "%s: invalid option `%s'\n", tool, arg); + args_ok = false; + } + } + } else if (0 == strncmp(arg, "--prefix", 8)) { + if ("" != install_prefix) { + fprintf(stderr, "%s: the `--prefix' option should be used only once.\n", tool); + args_ok = false; + } else { + if ('=' == arg[8]) { + install_prefix = std::string(arg + 9); + if ("" == install_prefix) { + fprintf(stderr, "%s: missing install prefix after `--prefix='\n", tool); + args_ok = false; + } + } else if ('\0' == arg[8]) { + command_index++; + if (command_index == argc) { + fprintf(stderr, "%s: missing install prefix after `--prefix'\n", tool); + args_ok = false; + } else { + install_prefix = argv[command_index]; + } + } else { + fprintf(stderr, "%s: invalid option `%s'\n", tool, arg); + args_ok = false; + } + } + } else { + // The argument is not a qualifier + // However, none of the sub-commands begin with a - + if ('-' == arg[0]) { + fprintf(stderr, "%s: unknown option `%s'\n", tool, arg); + args_ok = false; + } + break; // end of qualifiers + } + } - // usage message - if (command_index == argc) { // if there is no command - if (version) { // if the tool version was requested - printf ("ecosconfig %s (%s %s)\n%s\n", TOOL_VERSION, __DATE__, __TIME__, TOOL_COPYRIGHT); - } else { // the tool version was not requested - usage_message (); // print the usage message - } - return EXIT_SUCCESS; - } - - // set the default save file - if (savefile.empty ()) { // if the save file was not specified on the command line - savefile = DEFAULT_SAVE_FILE; // use the default save file - } +#if 0 + printf("args_ok is %d\n", args_ok); + printf("help is %d\n", help); + printf("version is %d\n", version); + printf("no_resolve is %d\n", no_resolve); + printf("quiet is %d\n", quiet); + printf("verbose is %d\n", verbose); + printf("ignore_errors is %d\n", ignore_errors); + printf("repository is %s\n", repository.c_str()); + printf("savefile is %s\n", savefile.c_str()); + printf("install_prefix is %s\n", install_prefix.c_str()); + exit(EXIT_SUCCESS); +#endif + + // Usually argv[command_index] will be a sub-command, unless + // --help or --version has been used. + + // Always output the version number, irrespective of subsequent + // commands or any problems. This can be useful in batch jobs. + if (version) { + printf ("ecosconfig %s (%s %s)\n%s\n", TOOL_VERSION, __DATE__, __TIME__, TOOL_COPYRIGHT); + if (command_index == argc) { + return EXIT_SUCCESS; + } + } + // Cope with --help and any user errors. If --help is used then + // subsequent arguments should be ignored, as should any problems + // with the arguments. This allows the user to type a partial + // command, then switch to --help, and use shell history editing + // to complete/correct the command. + if (help || !args_ok || (command_index == argc)) { + usage_message(); + return help ? EXIT_SUCCESS : EXIT_FAILURE; + } + + // set the default save file + if (savefile.empty ()) { // if the save file was not specified on the command line + savefile = DEFAULT_SAVE_FILE; // use the default save file + } - // find the repository - if (repository.empty ()) { // if the repository was not specified on the command line - const char * env_var = getenv ("ECOS_REPOSITORY"); - if (env_var) { // if the ECOS_REPOSITORY environment variable is defined - repository = env_var; - } else { // the ECOS_REPOSITORY environment variable is not defined - // assume that the tool is located in the root of the repository + // find the repository + if (repository.empty ()) { // if the repository was not specified on the command line + const char * env_var = getenv ("ECOS_REPOSITORY"); + if (env_var) { // if the ECOS_REPOSITORY environment variable is defined + repository = env_var; + } else { // the ECOS_REPOSITORY environment variable is not defined + // assume that the tool is located in the root of the repository #ifdef _MSC_VER - char toolpath [_MAX_PATH + 1]; - _fullpath (toolpath, argv [0], sizeof (toolpath)); // get the absolute path to the tool + char toolpath [_MAX_PATH + 1]; + _fullpath (toolpath, argv [0], sizeof (toolpath)); // get the absolute path to the tool #else - char toolpath [MAXPATHLEN + 1]; - realpath (argv [0], toolpath); // get the absolute path to the tool + // NOTE: portability problem. realpath() is not a POSIX function. + // Alternative code may be needed on some platforms. + char toolpath [MAXPATHLEN + 1]; + realpath (argv [0], toolpath); // get the absolute path to the tool #endif - repository = toolpath; - for (unsigned int n = repository.size () - 1; n > 0; n--) { // for each char starting at the tail - if (('\\' == repository [n]) || ('/' == repository [n])) { // if the char is a directory separator - repository.resize (n); // remove the filename from the filepath - break; - } - } - } - } + repository = toolpath; + for (unsigned int n = repository.size () - 1; n > 0; n--) { // for each char starting at the tail + if (('\\' == repository [n]) || ('/' == repository [n])) { // if the char is a directory separator + repository.resize (n); // remove the filename from the filepath + break; + } + } + } + } #ifdef __CYGWIN__ - // convert cygwin paths to win32 paths - char buffer [MAXPATHLEN + 1]; - cygwin_conv_to_win32_path (repository.c_str (), buffer); - repository = buffer; - cygwin_conv_to_win32_path (savefile.c_str (), buffer); - savefile = buffer; - if (! install_prefix.empty ()) { // cygwin_conv_to_win32_path() does not copy an empty string - cygwin_conv_to_win32_path (install_prefix.c_str (), buffer); - install_prefix = buffer; - } + // convert cygwin paths to win32 paths + char buffer [MAXPATHLEN + 1]; + cygwin_conv_to_win32_path (repository.c_str (), buffer); + repository = buffer; + cygwin_conv_to_win32_path (savefile.c_str (), buffer); + savefile = buffer; + if (! install_prefix.empty ()) { // cygwin_conv_to_win32_path() does not copy an empty string + cygwin_conv_to_win32_path (install_prefix.c_str (), buffer); + install_prefix = buffer; + } #endif - // process the command - cdl_exec exec (trim_path (repository), savefile, trim_path (install_prefix), no_resolve); - const std::string command = argv [command_index]; - bool status = true; - - if ("new" == command) { - if (command_index + 2 == argc) { - status = exec.cmd_new (argv [command_index + 1]); - } else if (command_index + 3 == argc) { - status = exec.cmd_new (argv [command_index + 1], argv [command_index + 2]); - } else if (command_index + 4 == argc) { - status = exec.cmd_new (argv [command_index + 1], argv [command_index + 2], argv [command_index + 3]); - } else { - status = false; - usage_message (); - } - - } else if ("tree" == command) { - if (command_index + 1 == argc) { - status = exec.cmd_tree (); - } else { - status = false; - usage_message (); - } - - } else if ("list" == command) { - if (command_index + 1 == argc) { - status = exec.cmd_list (); - } else { - status = false; - usage_message (); - } - - } else if ("check" == command) { - if (command_index + 1 == argc) { - status = exec.cmd_check (); - } else { - status = false; - usage_message (); - } - - } else if ("resolve" == command) { - if (command_index + 1 == argc) { - status = exec.cmd_resolve (); - } else { - status = false; - usage_message (); - } - - } else if ("add" == command) { - if (command_index + 1 < argc) { - std::vector<std::string> packages; - for (int n = command_index + 1; n < argc; n++) { - packages.push_back (argv [n]); - } - status = exec.cmd_add (packages); - } else { - status = false; - usage_message (); - } - - } else if ("remove" == command) { - if (command_index + 1 < argc) { - std::vector<std::string> packages; - for (int n = command_index + 1; n < argc; n++) { - packages.push_back (argv [n]); - } - status = exec.cmd_remove (packages); - } else { - status = false; - usage_message (); - } + // Initialize the cdl_exec code (not quite sure why this needs a + // separate object rather than just a bunch of statics). + cdl_exec exec (trim_path (repository), savefile, trim_path (install_prefix), no_resolve); + cdl_exec::set_quiet_mode(quiet); + cdl_exec::set_verbose_mode(verbose); + cdl_exec::set_ignore_errors_mode(ignore_errors); + + // Now identify and process the sub-command. + const std::string command = argv [command_index]; + command_index++; + bool status = false; - } else if ("version" == command) { - if (command_index + 2 < argc) { - std::vector<std::string> packages; - for (int n = command_index + 2; n < argc; n++) { - packages.push_back (argv [n]); - } - status = exec.cmd_version (argv [command_index + 1], packages); - } else { - status = false; - usage_message (); - } + if ("new" == command) { + // Usage: ecosconfig new <target> [template [version]] + if ((command_index == argc) || ((command_index + 3) <= argc)) { + usage_message(); + } else { + // The default values for template and template_version + // are part of the cdl_exec class, so cdl_exec::cmd_new() has + // to be invoked with the right number of arguments. + if ((command_index + 1) == argc) { + status = exec.cmd_new(argv[command_index]); + } else if ((command_index + 2) == argc) { + status = exec.cmd_new(argv[command_index], argv[command_index + 1]); + } else { + status = exec.cmd_new(argv[command_index], argv[command_index + 1], argv[command_index + 2]); + } + } + } else if ("tree" == command) { + // Usage: ecosconfig tree + if (command_index == argc) { + status = exec.cmd_tree (); + } else { + usage_message (); + } + } else if ("list" == command) { + // Usage: ecosconfig list + if (command_index == argc) { + status = exec.cmd_list (); + } else { + usage_message (); + } + } else if ("check" == command) { + // Usage: ecosconfig check + if (command_index == argc) { + status = exec.cmd_check (); + } else { + usage_message (); + } + } else if ("resolve" == command) { + // Usage: ecosconfig resolve + if (command_index == argc) { + status = exec.cmd_resolve (); + } else { + usage_message (); + } + } else if ("add" == command) { + // Usage: ecosconfig add <package> [<package2> ...] + if (command_index < argc) { + std::vector<std::string> packages; + for (int n = command_index; n < argc; n++) { + packages.push_back (argv [n]); + } + status = exec.cmd_add (packages); + } else { + usage_message (); + } + } else if ("remove" == command) { + // Usage: ecosconfig remove <package> [<package2> ...] + if (command_index < argc) { + std::vector<std::string> packages; + for (int n = command_index; n < argc; n++) { + packages.push_back (argv [n]); + } + status = exec.cmd_remove (packages); + } else { + usage_message (); + } + } else if ("version" == command) { + // Usage: ecosconfig version <version> <package> [<package2> ...] + // Note that it is not possible to change several packages to different versions. + if (command_index + 1 < argc) { + std::vector<std::string> packages; + for (int n = command_index + 1; n < argc; n++) { + packages.push_back (argv [n]); + } + status = exec.cmd_version (argv [command_index], packages); + } else { + usage_message (); + } - } else if ("target" == command) { - if (command_index + 2 == argc) { - status = exec.cmd_target (argv [command_index + 1]); - } else { - status = false; - usage_message (); - } + } else if ("target" == command) { + // Usage: ecosconfig target <target> + if (command_index + 1 == argc) { + status = exec.cmd_target (argv [command_index]); + } else { + usage_message (); + } - } else if ("template" == command) { - if (command_index + 2 == argc) { - status = exec.cmd_template (argv [command_index + 1]); - } else if (command_index + 3 == argc) { - status = exec.cmd_template (argv [command_index + 1], argv [command_index + 2]); - } else { - status = false; - usage_message (); - } + } else if ("template" == command) { + // Usage: ecosconfig template <template> [<version>] + if (command_index + 1 == argc) { + status = exec.cmd_template (argv [command_index]); + } else if (command_index + 2 == argc) { + status = exec.cmd_template (argv [command_index], argv [command_index]); + } else { + usage_message (); + } - } else if ("export" == command) { - if (command_index + 2 == argc) { - status = exec.cmd_export (argv [command_index + 1]); - } else { - status = false; - usage_message (); - } + } else if ("export" == command) { + // Usage: ecosconfige export <filename> + if (command_index + 1 == argc) { + status = exec.cmd_export (argv [command_index]); + } else { + usage_message (); + } - } else if ("import" == command) { - if (command_index + 2 == argc) { - status = exec.cmd_import (argv [command_index + 1]); - } else { - status = false; - usage_message (); - } + } else if ("import" == command) { + // Usage: ecosconfig import <filename> + if (command_index + 1 == argc) { + status = exec.cmd_import (argv [command_index]); + } else { + usage_message (); + } - } else { - status = false; - usage_message (); - } + } else { + usage_message (); + } - return status ? EXIT_SUCCESS : EXIT_FAILURE; + return status ? EXIT_SUCCESS : EXIT_FAILURE; } // remove the trailing directory separator from a file path if present std::string trim_path (const std::string input) { - std::string output = input; - if (! output.empty ()) { - const char last_char = output [output.size () - 1]; - if (('\\' == last_char) || ('/' == last_char)) { // if the last char is a directory separator - output.resize (output.size () - 1); // remove the last char - } - } - return output; + std::string output = input; + if (! output.empty ()) { + const char last_char = output [output.size () - 1]; + if (('\\' == last_char) || ('/' == last_char)) { // if the last char is a directory separator + output.resize (output.size () - 1); // remove the last char + } + } + return output; } // print a usage message void usage_message () { - printf ("Usage: ecosconfig [ qualifier ... ] [ command ]\n"); - printf (" commands are:\n"); - printf (" list : list repository contents\n"); - printf (" new TARGET [ TEMPLATE [ VERSION ] ] : create a configuration\n"); - printf (" target TARGET : change the target hardware\n"); - printf (" template TEMPLATE [ VERSION ] : change the template\n"); - printf (" add PACKAGE [ PACKAGE ... ] : add package(s)\n"); - printf (" remove PACKAGE [ PACKAGE ... ] : remove package(s)\n"); - printf (" version VERSION PACKAGE [ PACKAGE ... ] : change version of package(s)\n"); - printf (" export FILE : export minimal config info\n"); - printf (" import FILE : import additional config info\n"); - printf (" check : check the configuration\n"); - printf (" resolve : resolve conflicts\n"); - printf (" tree : create a build tree\n"); - printf (" qualifiers are:\n"); - printf (" --config=FILE : the configuration file\n"); - printf (" --prefix=DIRECTORY : the install prefix\n"); - printf (" --srcdir=DIRECTORY : the source repository\n"); - printf (" --no-resolve : disable conflict resolution\n"); - printf (" --version : show version and copyright\n"); + printf ("Usage: ecosconfig [ qualifier ... ] [ command ]\n"); + printf (" commands are:\n"); + printf (" list : list repository contents\n"); + printf (" new TARGET [ TEMPLATE [ VERSION ] ] : create a configuration\n"); + printf (" target TARGET : change the target hardware\n"); + printf (" template TEMPLATE [ VERSION ] : change the template\n"); + printf (" add PACKAGE [ PACKAGE ... ] : add package(s)\n"); + printf (" remove PACKAGE [ PACKAGE ... ] : remove package(s)\n"); + printf (" version VERSION PACKAGE [ PACKAGE ... ] : change version of package(s)\n"); + printf (" export FILE : export minimal config info\n"); + printf (" import FILE : import additional config info\n"); + printf (" check : check the configuration\n"); + printf (" resolve : resolve conflicts\n"); + printf (" tree : create a build tree\n"); + printf (" qualifiers are:\n"); + printf (" --config=FILE : the configuration file\n"); + printf (" --prefix=DIRECTORY : the install prefix\n"); + printf (" --srcdir=DIRECTORY : the source repository\n"); + printf (" --no-resolve : disable conflict resolution\n"); + printf (" --version : show version and copyright\n"); + printf (" -q, --quiet : reduce verbosity\n"); + printf (" -v, --verbose : increase verbosity\n"); + printf (" -i, --ignore-errors : ignore unresolved conflicts\n"); + printf (" --help : display this message\n"); } diff --git a/host/tools/configtool/standalone/win32/Configtool.rc b/host/tools/configtool/standalone/win32/Configtool.rc index 4a83d8aa1..05f7eb7ba 100644 --- a/host/tools/configtool/standalone/win32/Configtool.rc +++ b/host/tools/configtool/standalone/win32/Configtool.rc @@ -158,7 +158,7 @@ BEGIN POPUP "Red Hat on the &Web" BEGIN MENUITEM "&Red Hat Home Page", ID_HELP_RED_HATONTHEWEB - MENUITEM "&eCos Services Page", ID_HELP_ECOSHOME + MENUITEM "&eCos Product Page", ID_HELP_ECOSHOME MENUITEM "eCos &Net Release Page", ID_HELP_ECOS MENUITEM SEPARATOR MENUITEM "µ&ITRON Specification", ID_HELP_UITRON diff --git a/packages/ChangeLog b/packages/ChangeLog index 1ee876232..880f27623 100644 --- a/packages/ChangeLog +++ b/packages/ChangeLog @@ -1,3 +1,7 @@ +2000-06-23 Jesper Skov <jskov@redhat.com> + + * ecos.db: Added CqREEK serial package. + 2000-06-22 Jesper Skov <jskov@redhat.com> * ecos.db: Added io_wallclock alias. diff --git a/packages/NEWS b/packages/NEWS index 95ebcd104..71772b0c1 100644 --- a/packages/NEWS +++ b/packages/NEWS @@ -9,7 +9,7 @@ * Serial device drivers added for systems based on NEC V850 SA1 (70F3017) or SB1 (70F3033) processors * Hitachi SH3 CqREEK (cq7708) platform HAL support added - Contributed by Haruki Kashiwaya [Still untested, serial not imported] + Contributed by Haruki Kashiwaya * Watchdog reworked much like wallclock. Common code and API in io/watchdog, simpler (smaller) low-level drivers in devs/watchdog/<arch>. diff --git a/packages/devs/eth/arm/ebsa285/current/ChangeLog b/packages/devs/eth/arm/ebsa285/current/ChangeLog index e966cb378..74502f10c 100644 --- a/packages/devs/eth/arm/ebsa285/current/ChangeLog +++ b/packages/devs/eth/arm/ebsa285/current/ChangeLog @@ -1,3 +1,24 @@ +2000-06-27 Hugo Tyson <hmt@cygnus.co.uk> + + * cdl/ebsa285_eth_drivers.cdl: Add sesquipedalian option + CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS in (now) + component CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_STATISTICS to control + keeping (well, harvesting really) the i82559's internal stats. + Reputedly, it doesn't service the net whilst this is happening, so + it could be viewed a bad thing. Hence the option. + + * include/ebsa285_info.h: Only describe the I82559_COUNTERS + i82559_counters[2]; structs if full stats are to be kept. + + * src/if_ebsa285.c (update_statistics): Only include this if full + stats are to be kept. + +2000-06-27 Hugo Tyson <hmt@cygnus.co.uk> + + * src/if_ebsa285.c (ResetRxRing): Re-do the management of the + RxRing; have an end-of-list flag (EL) in the last entry, and as + you unload filled slots, drag it round after you. + 2000-06-14 Hugo Tyson <hmt@cygnus.co.uk> * cdl/ebsa285_eth_drivers.cdl: Add option to control statistics 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 index 3eae3dbc4..fc1c1691c 100644 --- a/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl +++ b/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl @@ -83,7 +83,7 @@ cdl_package CYGPKG_DEVS_ETH_ARM_EBSA285 { connection." } - cdl_option CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_STATISTICS { + cdl_component CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_STATISTICS { display "Keep Ethernet statistics" default_value 1 description " @@ -92,6 +92,18 @@ cdl_package CYGPKG_DEVS_ETH_ARM_EBSA285 { for network management. SNMP for example uses this information. There is some performance cost in maintaining this information; disable this option to recoup that." + + cdl_option CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS { + display "Keep i82559 Internal statistics" + default_value 1 + description " + The i82559 keeps internal counters, and it is possible to + acquire these. But the i82559 (reputedly) does not service + the network whilst uploading the data to RAM from its + internal registers. If throughput is a problem, disable + this option to acquire only those statistics gathered by + software, so that the i82559 never sleeps." + } } cdl_component CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM { diff --git a/packages/devs/eth/arm/ebsa285/current/include/ebsa285_info.h b/packages/devs/eth/arm/ebsa285/current/include/ebsa285_info.h index 7a76c7b3c..0a244a9d5 100644 --- a/packages/devs/eth/arm/ebsa285/current/include/ebsa285_info.h +++ b/packages/devs/eth/arm/ebsa285/current/include/ebsa285_info.h @@ -97,7 +97,9 @@ typedef struct { extern STATISTICS statistics[2]; +#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS extern I82559_COUNTERS i82559_counters[2]; +#endif #endif // KEEP_STATISTICS @@ -183,7 +185,7 @@ void update_statistics(struct i82559* p_i82559); #endif -#ifdef KEEP_STATISTICS +#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS #define ETH_STATS_INIT( p ) \ int _tmp; \ update_statistics( (struct i82559 *)((p)->driver_private) ) @@ -223,6 +225,7 @@ void update_statistics(struct i82559* p_i82559); (statistics[ ((struct i82559 *)((p)->driver_private))->index \ ].tx_dropped) +#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS #define ETH_DEV_STATSALIGNMENTERRORS( p ) \ (i82559_counters[ ((struct i82559 *)((p)->driver_private))->index \ ].rx_align_errors) @@ -277,6 +280,7 @@ void update_statistics(struct i82559* p_i82559); // (i82559_counters[ ((struct i82559 *)((p)->driver_private))->index \ // ].) +#endif // CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS #endif // KEEP_STATISTICS diff --git a/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c index 97908db85..001dc31cb 100644 --- a/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c +++ b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c @@ -242,7 +242,10 @@ static inline cyg_uint32 bus_to_virt(cyg_uint32 p_memory) // // ------------------------------------------------------------------------ typedef struct rfd { - volatile cyg_uint32 status; // result of receive operation + volatile union { + cyg_uint32 u32_status; // result of receive operation + cyg_uint16 u16_status[2]; + } u_status; 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 + @@ -252,6 +255,16 @@ typedef struct rfd { volatile cyg_uint8 buffer[0]; // data buffer (simple mode) } RFD; +// The status is split into two shorts to get atomic access to the EL bit; +// the upper word is not written by the device, so we can just hit it, +// leaving the lower word (which the device updates) alone. Otherwise +// there's a race condition between software moving the end-of-list (EL) +// bit round and the device writing into the previous slot. + +#define rxstatus u_status.u32_status +#define rxstatus_hi u_status.u16_status[1] +#define rxstatus_lo u_status.u16_status[0] + #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 @@ -259,6 +272,14 @@ typedef struct rfd { #define RFD_STATUS_C 0x00008000 // completion of received frame #define RFD_STATUS_OK 0x00002000 // frame received with no errors +#define RFD_STATUS_HI_EL 0x8000 // 1=last RFD in RFA +#define RFD_STATUS_HI_S 0x4000 // 1=suspend RU after receiving frame +#define RFD_STATUS_HI_H 0x0010 // 1=RFD is a header RFD +#define RFD_STATUS_HI_SF 0x0008 // 0=simplified, 1=flexible mode + +#define RFD_STATUS_LO_C 0x8000 // completion of received frame +#define RFD_STATUS_LO_OK 0x2000 // 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 @@ -288,7 +309,7 @@ typedef struct rbd { // // ------------------------------------------------------------------------ typedef struct txcb { - volatile cyg_uint32 status:16, // result of transmit operation + volatile cyg_uint32 txstatus: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 @@ -931,6 +952,7 @@ static void i82559_start( struct eth_drv_sc *sc, ioaddr = p_i82559->io_address; // get 82559's I/O address #ifdef KEEP_STATISTICS +#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS p_i82559->p_statistics = p_statistics = pciwindow_mem_alloc(sizeof(I82559_COUNTERS)); memset(p_statistics, 0xFFFFFFFF, sizeof(I82559_COUNTERS)); @@ -941,6 +963,7 @@ static void i82559_start( struct eth_drv_sc *sc, wait_for_cmd_done(ioaddr); // make sure no command operating OUTW(SCB_M | CU_DUMPSTATS, ioaddr + SCBCmd); // start register dump +#endif #endif // Set the base address @@ -1075,7 +1098,7 @@ static void ResetRxRing(struct i82559* p_i82559) 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->rxstatus = 0; p_rfd->count = 0; p_rfd->f = 0; p_rfd->eof = 0; @@ -1083,6 +1106,8 @@ static void ResetRxRing(struct i82559* p_i82559) p_rfd->size = MAX_RX_PACKET_SIZE; } p_i82559->next_rx_descriptor = 0; + // And set an end-of-list marker in the previous one. + p_rfd->rxstatus = RFD_STATUS_EL; } // ------------------------------------------------------------------------ @@ -1113,8 +1138,8 @@ static void PacketRxReady(struct i82559* p_i82559) 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; + while ( p_rfd->rxstatus & RFD_STATUS_C ) { + p_rfd->rxstatus_hi |= RFD_STATUS_HI_EL; length = p_rfd->count; #ifdef DEBUG_82559 @@ -1130,7 +1155,18 @@ static void PacketRxReady(struct i82559* p_i82559) p_rfd->count = 0; p_rfd->f = 0; p_rfd->eof = 0; - p_rfd->status = 0; + p_rfd->rxstatus_lo = 0; + + // The just-emptied slot is now ready for re-use and already marked EL; + // we can now remove the EL marker from the previous one. + if ( 0 == next_descriptor ) + p_rfd = p_i82559->rx_ring[ MAX_RX_DESCRIPTORS-1 ]; + else + p_rfd = p_i82559->rx_ring[ next_descriptor-1 ]; + // The previous one: check it *was* marked before clearing. + CYG_ASSERT( p_rfd->rxstatus_hi & RFD_STATUS_HI_EL, "No prev EL" ); + p_rfd->rxstatus_hi = 0; // that word is not written by the device. + #ifdef KEEP_STATISTICS statistics[p_i82559->index].rx_deliver++; #endif @@ -1154,6 +1190,9 @@ static void PacketRxReady(struct i82559* p_i82559) #ifdef KEEP_STATISTICS statistics[p_i82559->index].rx_restart++; #endif + // There's an end-of-list marker out there somewhere... + // So mop it up; it takes a little time but this is infrequent. + ResetRxRing( p_i82559 ); next_descriptor = 0; // re-initialize next desc. // wait for SCB command complete wait_for_cmd_done(ioaddr); @@ -1195,17 +1234,20 @@ static void i82559_recv( struct eth_drv_sc *sc, 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" ); + CYG_ASSERT( p_rfd->rxstatus & RFD_STATUS_C, "No complete frame" ); + CYG_ASSERT( p_rfd->rxstatus & RFD_STATUS_EL, "No marked frame" ); + + CYG_ASSERT( p_rfd->rxstatus_lo & RFD_STATUS_LO_C, "No complete frame 2" ); + CYG_ASSERT( p_rfd->rxstatus_hi & RFD_STATUS_HI_EL, "No marked frame 2" ); - if ( 0 == (p_rfd->status & RFD_STATUS_C) ) + if ( 0 == (p_rfd->rxstatus & 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)p_i82559, p_rfd->status, sg_len, total_len); + p_i82559->index, (int)p_i82559, p_rfd->rxstatus, sg_len, total_len); #endif // Copy the data to the network stack @@ -1292,7 +1334,7 @@ static void ResetTxRing(struct i82559* p_i82559) 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->txstatus = 0; p_txcb->command = 0; p_txcb->link = VIRT_TO_BUS((cyg_uint32)p_txcb); p_txcb->tbd_address = 0xFFFFFFFF; @@ -1385,7 +1427,7 @@ static void TxDone(struct i82559* p_i82559) // the remove one if the queue is full AND its status is nonzero: while ( (tx_descriptor_remove != p_i82559->tx_descriptor_active) || ( p_i82559->tx_queue_full && - (0 != p_i82559->tx_ring[ tx_descriptor_remove ]->status) ) ) { + (0 != p_i82559->tx_ring[ tx_descriptor_remove ]->txstatus) ) ) { unsigned long key = p_i82559->tx_keys[ tx_descriptor_remove ]; #ifdef DEBUG_82559 os_printf("TxDone %d %x: KEY %x\n", @@ -1491,7 +1533,7 @@ i82559_send(struct eth_drv_sc *sc, 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->txstatus = 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); @@ -2304,6 +2346,7 @@ static int i82559_ioctl(struct eth_drv_sc *sc, unsigned long key, // ------------------------------------------------------------------------ #ifdef KEEP_STATISTICS +#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_KEEP_82559_STATISTICS void update_statistics(struct i82559* p_i82559) { I82559_COUNTERS *p_statistics; @@ -2335,6 +2378,7 @@ void update_statistics(struct i82559* p_i82559) Acknowledge82559Interrupt(p_i82559); UnMask82559Interrupt(p_i82559); } +#endif #endif // KEEP_STATISTICS // ------------------------------------------------------------------------ @@ -2347,7 +2391,7 @@ void update_statistics(struct i82559* p_i82559) void dump_txcb(TxCB *p_txcb) { os_printf("TxCB @ %x\n", (int)p_txcb); - os_printf("status = %04X ", p_txcb->status); + os_printf("status = %04X ", p_txcb->txstatus); os_printf("command = %04X ", p_txcb->command); os_printf("link = %08X ", p_txcb->link); os_printf("tbd = %08X ", p_txcb->tbd_address); @@ -2461,9 +2505,9 @@ void DisplayStatistics(void) void dump_rfd(RFD *p_rfd, int anyway ) { - if ( (0 != p_rfd->status) || anyway ) { + if ( (0 != p_rfd->rxstatus) || anyway ) { os_printf("RFD @ %x = ", (int)p_rfd); - os_printf("status = %x ", p_rfd->status); + os_printf("status = %x ", p_rfd->rxstatus); os_printf("link = %x ", p_rfd->link); // os_printf("rdb_address = %x ", p_rfd->rdb_address); os_printf("count = %x ", p_rfd->count); diff --git a/packages/devs/serial/sh/cq7708/current/ChangeLog b/packages/devs/serial/sh/cq7708/current/ChangeLog new file mode 100644 index 000000000..ee3f8f71b --- /dev/null +++ b/packages/devs/serial/sh/cq7708/current/ChangeLog @@ -0,0 +1,32 @@ +2000-06-23 Jesper Skov <jskov@redhat.com> + + + * Imported sources contributed by Haruki Kashiwaya + (kashiwaya at redhat dot com). Still need to fix this to properly + share the driver with the EDK (and any other platform using SCI). + +//=========================================================================== +//####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/cq7708/current/cdl/ser_sh_cq7708.cdl b/packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl new file mode 100644 index 000000000..b6cf54fc2 --- /dev/null +++ b/packages/devs/serial/sh/cq7708/current/cdl/ser_sh_cq7708.cdl @@ -0,0 +1,136 @@ +# ==================================================================== +# +# ser_sh_cq7708.cdl +# +# eCos serial SH/CQ7708 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_CQ7708 { + display "SH3 cq7708 serial device drivers" + + parent CYGPKG_IO_SERIAL_DEVICES + active_if CYGPKG_IO_SERIAL + active_if CYGPKG_HAL_SH_SH7708_CQ7708 + + requires CYGPKG_ERROR + include_dir cyg/io + include_files ; # none _exported_ whatsoever + description " + This option enables the serial device drivers for the + CQ SH3 cq7708 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 <pkgconf/io_serial_sh_cq7708.h>" + puts $::cdl_system_header "/***** serial driver proc output end *****/" + } + +cdl_component CYGPKG_IO_SERIAL_SH_CQ7708_SCI { + display "SH3 CQ7708 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_CQ7708_SCI_NAME { + display "Device name for SH3 CQ7708 SCI" + flavor data + default_value {"\"/dev/ser1\""} + description " + This option specifies the device name for the SCI port." + } + + cdl_option CYGNUM_IO_SERIAL_SH_CQ7708_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_CQ7708_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_CQ7708_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_CQ7708_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_CQ7708_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_cq7708.cdl diff --git a/packages/devs/serial/sh/cq7708/current/src/sh_sci_cq7708.inl b/packages/devs/serial/sh/cq7708/current/src/sh_sci_cq7708.inl new file mode 100644 index 000000000..6a70d790b --- /dev/null +++ b/packages/devs/serial/sh/cq7708/current/src/sh_sci_cq7708.inl @@ -0,0 +1,98 @@ +//========================================================================== +// +// io/serial/sh/sh_sci_cq7708.c +// +// Serial I/O Interface Module definitions for SH3/CQ7708 +// +//========================================================================== +//####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/CQ7708. +// Description: +// +//####DESCRIPTIONEND#### +//========================================================================== + +// Controller bases in the SH3/CQ7708 (only one) +#define SH_SERIAL_SCI_BASE 0xfffffe80 + +// The SCI controller register layout on the SH3/CQ7708. +#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_CQ7708_SCI_BUFSIZE > 0 +static unsigned char sh_serial_out_buf[CYGNUM_IO_SERIAL_SH_CQ7708_SCI_BUFSIZE]; +static unsigned char sh_serial_in_buf[CYGNUM_IO_SERIAL_SH_CQ7708_SCI_BUFSIZE]; + +static SERIAL_CHANNEL_USING_INTERRUPTS(sh_serial_channel, + sh_serial_funs, + sh_serial_info, + CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_SH_CQ7708_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_CQ7708_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_CQ7708_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/cq7708/current/src/sh_sci_serial.c b/packages/devs/serial/sh/cq7708/current/src/sh_sci_serial.c new file mode 100644 index 000000000..976fbb36f --- /dev/null +++ b/packages/devs/serial/sh/cq7708/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 <pkgconf/io_serial.h> +#include <pkgconf/io.h> + +#include <cyg/io/io.h> +#include <cyg/hal/hal_intr.h> +#include <cyg/io/devtab.h> +#include <cyg/infra/diag.h> +#include <cyg/io/serial.h> + +#include <cyg/hal/sh_regs.h> + +#ifdef CYGPKG_IO_SERIAL_SH_CQ7708 +#define __CYGPKG_IO_SERIAL_SH_SCI_INL "sh_sci_cq7708.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/ecos.db b/packages/ecos.db index df43f30aa..1c4b47507 100644 --- a/packages/ecos.db +++ b/packages/ecos.db @@ -208,6 +208,16 @@ package CYGPKG_IO_SERIAL_SH_EDK7708 { description "SH3 EDK7708 serial device drivers" } +package CYGPKG_IO_SERIAL_SH_CQ7708 { + alias { "SH3 cq7708 serial device drivers" + devs_serial_sh3_cq7708 + devs_serial_sh_cq7708 cq7708_serial_driver } + hardware + directory devs/serial/sh/cq7708 + script ser_sh_cq7708.cdl + description "SH3 cq7708 serial device drivers" +} + package CYGPKG_IO_SERIAL_V85X_V850 { alias { "NEC V850 serial device drivers" @@ -507,7 +517,6 @@ package CYGPKG_HAL_SH_EDK7708 { The edk HAL package provides the support needed to run eCos on a Hitachi SH3 EDK7708 board." } - package CYGPKG_HAL_SH_SH7708_CQ7708 { alias { "CqREEK SH7708 board" hal_sh_cq sh_cq_hal } directory hal/sh/cq7708 @@ -940,6 +949,7 @@ target cq7708 { alias { "CqREEK SH7708 board" cq7708 } packages { CYGPKG_HAL_SH CYGPKG_HAL_SH_SH7708_CQ7708 + CYGPKG_IO_SERIAL_SH_CQ7708 } enable { CYGPKG_HAL_SH_7708 } description " diff --git a/packages/hal/arm/arch/current/ChangeLog b/packages/hal/arm/arch/current/ChangeLog index ce0c42ef2..3821cfb0b 100644 --- a/packages/hal/arm/arch/current/ChangeLog +++ b/packages/hal/arm/arch/current/ChangeLog @@ -1,3 +1,9 @@ +2000-06-28 Jesper Skov <jskov@redhat.com> + + * src/hal_mk_defs.c: + * src/arm_stub.c: + Fix compiler warnings. + 2000-06-19 Gary Thomas <gthomas@redhat.com> * src/vectors.S: Changes for virtual vector support. diff --git a/packages/hal/arm/arch/current/src/arm_stub.c b/packages/hal/arm/arch/current/src/arm_stub.c index 1b85acffe..36714a88d 100644 --- a/packages/hal/arm/arch/current/src/arm_stub.c +++ b/packages/hal/arm/arch/current/src/arm_stub.c @@ -553,33 +553,6 @@ static instrBuffer break_buffer; volatile int cyg_hal_gdb_running_step = 0; -void -cyg_hal_gdb_interrupt (target_register_t pc) -{ - // Clear flag that we Continued instead of Stepping - cyg_hal_gdb_running_step = 0; - // and override existing break? So that a ^C takes effect... - if (0 != break_buffer.targetAddr) - cyg_hal_gdb_remove_break( break_buffer.targetAddr ); - - if (0 == break_buffer.targetAddr) { - cyg_uint32 cpsr = get_register(PS); - - if (cpsr & CPSR_THUMB_ENABLE) { - break_buffer.targetAddr = MAKE_THUMB_ADDR((cyg_uint32)pc); - break_buffer.savedInstr.thumb_instr = *(cyg_uint16*)pc; - *(cyg_uint16*)pc = HAL_BREAKINST_THUMB; - } else { - break_buffer.targetAddr = (cyg_uint32)pc; - break_buffer.savedInstr.arm_instr = *(cyg_uint32*)pc; - *(cyg_uint32*)pc = HAL_BREAKINST_ARM; - } - - __data_cache(CACHE_FLUSH); - __instruction_cache(CACHE_FLUSH); - } -} - // This function is passed thumb/arm information about the PC address // in bit 0. This information is passed on to the break_buffer. void @@ -627,6 +600,33 @@ cyg_hal_gdb_remove_break (target_register_t pc) return 0; } +void +cyg_hal_gdb_interrupt (target_register_t pc) +{ + // Clear flag that we Continued instead of Stepping + cyg_hal_gdb_running_step = 0; + // and override existing break? So that a ^C takes effect... + if (0 != break_buffer.targetAddr) + cyg_hal_gdb_remove_break( break_buffer.targetAddr ); + + if (0 == break_buffer.targetAddr) { + cyg_uint32 cpsr = get_register(PS); + + if (cpsr & CPSR_THUMB_ENABLE) { + break_buffer.targetAddr = MAKE_THUMB_ADDR((cyg_uint32)pc); + break_buffer.savedInstr.thumb_instr = *(cyg_uint16*)pc; + *(cyg_uint16*)pc = HAL_BREAKINST_THUMB; + } else { + break_buffer.targetAddr = (cyg_uint32)pc; + break_buffer.savedInstr.arm_instr = *(cyg_uint32*)pc; + *(cyg_uint32*)pc = HAL_BREAKINST_ARM; + } + + __data_cache(CACHE_FLUSH); + __instruction_cache(CACHE_FLUSH); + } +} + int cyg_hal_gdb_break_is_set (void) { diff --git a/packages/hal/arm/arch/current/src/hal_mk_defs.c b/packages/hal/arm/arch/current/src/hal_mk_defs.c index 2344c0862..8994973c5 100644 --- a/packages/hal/arm/arch/current/src/hal_mk_defs.c +++ b/packages/hal/arm/arch/current/src/hal_mk_defs.c @@ -106,6 +106,8 @@ main(void) #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT) DEFINE(CYGNUM_CALL_IF_TABLE_SIZE, CYGNUM_CALL_IF_TABLE_SIZE); #endif + + return 0; } diff --git a/packages/hal/common/current/ChangeLog b/packages/hal/common/current/ChangeLog index 6aa00d8cf..e811f4e70 100644 --- a/packages/hal/common/current/ChangeLog +++ b/packages/hal/common/current/ChangeLog @@ -1,3 +1,30 @@ +2000-06-29 Jesper Skov <jskov@redhat.com> + + * src/hal_stub.c (cyg_hal_gdb_diag_putc): Check console interrupt + flag and breakpoint if set. + +2000-06-28 Jesper Skov <jskov@redhat.com> + + * src/hal_stub.c (cyg_hal_gdb_diag_putc): Don't try to set + breakpoints in ROM startup - just disable interrupts. Also, use + procs table function to disable device interrupts. + + * include/hal_if.h: Mark vector/comms arrays volatile to avoid + compiler confusion. + + * include/dbg-threads-api.h: Fix C/C++ declaration issues. + + * src/hal_stub.c: Moved stub platform init call below vector table + setup. + + * src/hal_misc.c: + * src/hal_if.c: + * include/hal_if.h: DBG_ISR_VECTOR and SET_TIMEOUT functions added + to comms table. Added DELAY_US function to vector table. Made + switching of debug channel dis/enable Ctrl-c interrupts as + well. Made ctrlc_isr code use new vector entries. All this amounts + to a properly switchable debug channel. + 2000-06-21 Jesper Skov <jskov@redhat.com> * src/hal_stub.c: Fixed clients of vector procs tables to pass diff --git a/packages/hal/common/current/include/dbg-threads-api.h b/packages/hal/common/current/include/dbg-threads-api.h index 046b0a1a3..effdd007e 100644 --- a/packages/hal/common/current/include/dbg-threads-api.h +++ b/packages/hal/common/current/include/dbg-threads-api.h @@ -66,21 +66,21 @@ struct dbg_capabilities /* fill in the list of thread aware capabilities */ -extern int dbg_thread_capabilities(struct dbg_capabilities * cbp) ; +externC int dbg_thread_capabilities(struct dbg_capabilities * cbp) ; /* Fillin the identifier of the current thread */ /* return 1 if defined, 0 if not defined */ -extern int dbg_currthread(threadref * varparm) ; +externC int dbg_currthread(threadref * varparm) ; /* Return the unique ID number of the current thread. */ -extern int dbg_currthread_id(void); +externC int dbg_currthread_id(void); /* get the first or next member of the list of known threads */ -extern int dbg_threadlist(int startflag, - threadref * lastthreadid, - threadref * next_thread - ) ; +externC int dbg_threadlist(int startflag, + threadref * lastthreadid, + threadref * next_thread + ) ; /* return 1 if next_threadid has been filled in with a value */ /* return 0 if there are none or no more */ @@ -106,7 +106,7 @@ struct cygmon_thread_debug_info -extern int dbg_threadinfo( +externC int dbg_threadinfo( threadref * threadid, struct cygmon_thread_debug_info * info) ; @@ -119,7 +119,7 @@ registers which are NOT in the O.S. thread context. Their default values have already been assigned. */ -extern int dbg_getthreadreg( +externC int dbg_getthreadreg( threadref * osthreadid, int regcount, /* count of registers in the array */ void * regval) ; /* fillin this array */ @@ -131,7 +131,7 @@ which are defined in the saved context of thread or process identified by osthreadid. Return 0 if the threadis does not map to a known process or other error. Return 1 if the setting is successful. */ -extern int dbg_setthreadreg( +externC int dbg_setthreadreg( threadref * osthreadid, int regcount , /* number of registers */ void * regval) ; diff --git a/packages/hal/common/current/include/hal_if.h b/packages/hal/common/current/include/hal_if.h index 17bd6f97d..07f91fc58 100644 --- a/packages/hal/common/current/include/hal_if.h +++ b/packages/hal/common/current/include/hal_if.h @@ -51,6 +51,8 @@ #include <cyg/hal/dbg-threads-api.h> #include <cyg/hal/dbg-thread-syscall.h> +#include <stdarg.h> + #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT //-------------------------------------------------------------------------- @@ -93,6 +95,20 @@ typedef enum { * Enable comm port interrupt. */ __COMMCTL_IRQ_ENABLE, + + /* + * Returns the number of the interrupt vector used by the debug + * interrupt handler. + */ + __COMMCTL_DBG_ISR_VECTOR, + + /* + * Returns the current timeout value and sets a new timeout. + * Timeout resolution is in milliseconds. + * old_timeout = (*__control)(__COMMCTL_SET_TIMEOUT, + * cyg_int32 new_timeout); + */ + __COMMCTL_SET_TIMEOUT, } __comm_control_cmd_t; @@ -102,10 +118,12 @@ typedef enum { #define CYGNUM_COMM_IF_PUTC 3 #define CYGNUM_COMM_IF_GETC 4 #define CYGNUM_COMM_IF_CONTROL 5 +#define CYGNUM_COMM_IF_DBG_ISR 6 +#define CYGNUM_COMM_IF_GETC_TIMEOUT 7 #define CYGNUM_COMM_IF_TABLE_SIZE 8 -typedef CYG_ADDRWORD hal_virtual_comm_table_t[CYGNUM_COMM_IF_TABLE_SIZE]; +typedef volatile CYG_ADDRWORD hal_virtual_comm_table_t[CYGNUM_COMM_IF_TABLE_SIZE]; // The below is a (messy) attempt at adding some type safety to the // above array. At the same time, the accessors allow the @@ -151,6 +169,19 @@ typedef int (*__comm_if_control_t)(void *__ch_data, #define CYGACC_COMM_IF_CONTROL_SET(_t_, _x_) \ (_t_)[CYGNUM_COMM_IF_CONTROL]=(CYG_ADDRWORD)(_x_) +typedef int (*__comm_if_dbg_isr_t)(void *__ch_data, + int* __ctrlc, CYG_ADDRWORD __vector, + CYG_ADDRWORD __data); +#define CYGACC_COMM_IF_DBG_ISR(_t_) \ + ((__comm_if_dbg_isr_t)(((_t_))[CYGNUM_COMM_IF_DBG_ISR])) +#define CYGACC_COMM_IF_DBG_ISR_SET(_t_, _x_) \ + (_t_)[CYGNUM_COMM_IF_DBG_ISR]=(CYG_ADDRWORD)(_x_) + +typedef cyg_bool (*__comm_if_getc_timeout_t)(void* __ch_data, cyg_uint8* __ch); +#define CYGACC_COMM_IF_GETC_TIMEOUT(_t_) \ + ((__comm_if_getc_timeout_t)(((_t_))[CYGNUM_COMM_IF_GETC_TIMEOUT])) +#define CYGACC_COMM_IF_GETC_TIMEOUT_SET(_t_, _x_) \ + (_t_)[CYGNUM_COMM_IF_GETC_TIMEOUT]=(CYG_ADDRWORD)(_x_) //-------------------------------------------------------------------------- // Main calling interface table. Will be assigned a location by the @@ -175,14 +206,15 @@ typedef int (*__comm_if_control_t)(void *__ch_data, #define CYGNUM_CALL_IF_DBG_SYSCALL 15 // conflict! #define CYGNUM_CALL_IF_RESET 16 #define CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG 17 +#define CYGNUM_CALL_IF_DELAY_US 18 -#define CYGNUM_CALL_IF_LAST_ENTRY CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG +#define CYGNUM_CALL_IF_LAST_ENTRY CYGNUM_CALL_IF_DELAY_US #define CYGNUM_CALL_IF_INSTALL_BPT_FN 35 #define CYGNUM_CALL_IF_TABLE_SIZE 64 -externC CYG_ADDRWORD hal_virtual_vector_table[CYGNUM_CALL_IF_TABLE_SIZE]; +externC volatile CYG_ADDRWORD hal_virtual_vector_table[CYGNUM_CALL_IF_TABLE_SIZE]; // Table version is simply the number of the last active entry in the table // (except INSTALL_BPT_FN since it's so high). @@ -323,6 +355,12 @@ typedef int __call_if_console_interrupt_flag_t; #define CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(_x_) \ hal_virtual_vector_table[CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG]=(CYG_ADDRWORD)(_x_) +typedef void (*__call_if_delay_us_t)(cyg_int32 usecs); +#define CYGACC_CALL_IF_DELAY_US() \ + ((__call_if_delay_us_t)hal_virtual_vector_table[CYGNUM_CALL_IF_DELAY_US]) +#define CYGACC_CALL_IF_DELAY_US_SET(_x_) \ + hal_virtual_vector_table[CYGNUM_CALL_IF_DELAY_US]=(CYG_ADDRWORD)(_x_) + typedef void (*__call_if_install_bpt_fn_t)(void *__epc); #define CYGACC_CALL_IF_INSTALL_BPT_FN() \ ((__call_if_install_bpt_fn_t)hal_virtual_vector_table[CYGNUM_CALL_IF_INSTALL_BPT_FN]) @@ -335,13 +373,18 @@ externC void hal_if_diag_init(void); externC void hal_if_diag_write_char(char c); externC void hal_if_diag_read_char(char *c); +//-------------------------------------------------------------------------- +// Ctrl-c support. +externC cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data); + +#define HAL_CTRLC_ISR hal_ctrlc_isr + #endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT //-------------------------------------------------------------------------- // Functions provided by the HAL interface. externC void hal_if_init(void); - //-------------------------------------------------------------------------- // Configuration control for the interface services. // When this is set, code should initialize the vector table wherever diff --git a/packages/hal/common/current/src/hal_if.c b/packages/hal/common/current/src/hal_if.c index a05f4f03a..b4d5a30ef 100644 --- a/packages/hal/common/current/src/hal_if.c +++ b/packages/hal/common/current/src/hal_if.c @@ -41,6 +41,10 @@ #include <pkgconf/hal.h> +#ifdef CYGPKG_KERNEL +# include <pkgconf/kernel.h> +#endif + #include <cyg/infra/cyg_ass.h> // assertions #include <cyg/hal/hal_arch.h> // set/restore GP @@ -49,26 +53,64 @@ #include <cyg/hal/hal_if.h> // our interface #include <cyg/hal/hal_diag.h> // Diag IO +#include <cyg/hal/hal_misc.h> // User break #include <cyg/hal/hal_stub.h> // stub functionality #include <cyg/hal/plf_stub.h> // reset entry - FIXME, should be moved +#include <cyg/hal/hal_intr.h> // hal_vsr_table and others + //-------------------------------------------------------------------------- externC void patch_dbg_syscalls(void * vector); externC void init_thread_syscall(void * vector); -externC CYG_ADDRWORD hal_interrupt_handlers[]; -externC CYG_ADDRWORD hal_vsr_table[]; - //-------------------------------------------------------------------------- // Implementations and function wrappers for monitor services + #ifdef CYGPRI_HAL_IMPLEMENTS_IF_SERVICES +static void +delay_us(cyg_int32 usecs) +{ +#ifdef CYGPKG_KERNEL + cyg_int32 start, elapsed; + cyg_int32 usec_ticks, slice; + CYGARC_HAL_SAVE_GP(); + + // How many ticks total we should wait for. + usec_ticks = usecs*CYGNUM_KERNEL_COUNTERS_RTC_PERIOD; + usec_ticks /= CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR/1000; + + do { + // Spin in slices of 1/2 the RTC period. Allows interrupts + // time to run without messing up the algorithm. If we spun + // for 1 period (or more) of the RTC, there'd be also problems + // figuring out when the timer wrapped. We may lose a tick or + // two for each cycle but it shouldn't matter much. + slice = usec_ticks % (CYGNUM_KERNEL_COUNTERS_RTC_PERIOD / 2); + + HAL_CLOCK_READ(&start); + do { + HAL_CLOCK_READ(&elapsed); + elapsed = (elapsed - start); // counts up! + if (elapsed < 0) + elapsed += CYGNUM_KERNEL_COUNTERS_RTC_PERIOD; + } while (elapsed < slice); + + // Adjust by elapsed, not slice, since an interrupt may have + // been stalling us for some time. + usec_ticks -= elapsed; + } while (usec_ticks > 0); + + CYGARC_HAL_RESTORE_GP(); +#endif +} static void reset(void) { + CYGARC_HAL_SAVE_GP(); // With luck, the platform defines some magic that will cause a hardware // reset. HAL_STUB_PLATFORM_RESET(); @@ -83,6 +125,8 @@ reset(void) #else #error " no RESET_ENTRY" #endif + + CYGARC_HAL_RESTORE_GP(); } // This is the system's default kill signal routine. Unless overridden @@ -92,7 +136,11 @@ reset(void) static int kill_by_reset(int __irq_nr, void* __regs) { + CYGARC_HAL_SAVE_GP(); + reset(); + + CYGARC_HAL_RESTORE_GP(); return 0; } @@ -110,12 +158,14 @@ nop_service(void) static hal_virtual_comm_table_t comm_channels[CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS+1]; - - static int set_debug_comm(int __comm_id) { static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY; + hal_virtual_comm_table_t* __chan; + int interrupt_state = 0; + int res = 1, update = 0; + CYGARC_HAL_SAVE_GP(); CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS, @@ -124,36 +174,56 @@ set_debug_comm(int __comm_id) switch (__comm_id) { case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT: if (__selected_id > 0) - return __selected_id-1; - if (__selected_id == 0) - return CYGNUM_CALL_IF_SET_COMM_ID_MANGLER; - return __selected_id; + res = __selected_id-1; + else if (__selected_id == 0) + res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER; + else + res = __selected_id; + break; case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY: CYGACC_CALL_IF_DEBUG_PROCS_SET(0); __selected_id = __comm_id; - return 1; + break; case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER: __comm_id = 0; + update = 1; break; default: __comm_id++; // skip mangler entry + update = 1; break; } - - __selected_id = __comm_id; - - CYGACC_CALL_IF_DEBUG_PROCS_SET(comm_channels[__comm_id]); - return 1; + if (update) { + // Find the interrupt state of the channel. + __chan = CYGACC_CALL_IF_DEBUG_PROCS(); + if (__chan) + interrupt_state = CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_DISABLE); + + __selected_id = __comm_id; + CYGACC_CALL_IF_DEBUG_PROCS_SET(comm_channels[__comm_id]); + + // Set interrupt state on the new channel. + __chan = CYGACC_CALL_IF_DEBUG_PROCS(); + if (interrupt_state) + CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_ENABLE); + else + CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_DISABLE); + } + + CYGARC_HAL_RESTORE_GP(); + return res; } static int set_console_comm(int __comm_id) { static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY; + int res = 1, update = 0; + CYGARC_HAL_SAVE_GP(); CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS, @@ -162,30 +232,37 @@ set_console_comm(int __comm_id) switch (__comm_id) { case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT: if (__selected_id > 0) - return __selected_id-1; - if (__selected_id == 0) - return CYGNUM_CALL_IF_SET_COMM_ID_MANGLER; - return __selected_id; + res = __selected_id-1; + else if (__selected_id == 0) + res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER; + else + res = __selected_id; + break; case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY: CYGACC_CALL_IF_CONSOLE_PROCS_SET(0); __selected_id = __comm_id; - return 1; + break; case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER: __comm_id = 0; + update = 1; break; default: __comm_id++; // skip mangler entry + update = 1; break; } - __selected_id = __comm_id; + if (update) { + __selected_id = __comm_id; - CYGACC_CALL_IF_CONSOLE_PROCS_SET(comm_channels[__comm_id]); + CYGACC_CALL_IF_CONSOLE_PROCS_SET(comm_channels[__comm_id]); + } - return 1; + CYGARC_HAL_RESTORE_GP(); + return res; } //---------------------------------- @@ -194,21 +271,25 @@ set_console_comm(int __comm_id) static void flush_icache(void *__p, int __nbytes) { + CYGARC_HAL_SAVE_GP(); #ifdef HAL_ICACHE_FLUSH HAL_ICACHE_FLUSH( __p , __nbytes ); #elif defined(HAL_ICACHE_INVALIDATE) HAL_ICACHE_INVALIDATE(); #endif + CYGARC_HAL_RESTORE_GP(); } static void flush_dcache(void *__p, int __nbytes) { + CYGARC_HAL_SAVE_GP(); #ifdef HAL_DCACHE_FLUSH HAL_DCACHE_FLUSH( __p , __nbytes ); #elif defined(HAL_DCACHE_INVALIDATE) HAL_DCACHE_INVALIDATE(); #endif + CYGARC_HAL_RESTORE_GP(); } #endif @@ -222,10 +303,10 @@ flush_dcache(void *__p, int __nbytes) // routines for that channel. The platform HAL also has the necessary // information to determine if the channel is already initialized by // a debug agent (either builtin or in ROM). -void +void hal_if_diag_init(void) { -#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG +#ifdef CYGPRI_HAL_IMPLEMENTS_IF_SERVICES cyg_hal_plf_comms_init(); #endif @@ -249,6 +330,12 @@ hal_if_diag_write_char(char c) __chan = CYGACC_CALL_IF_DEBUG_PROCS(); CYGACC_COMM_IF_PUTC(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), c); } + + // Check interrupt flag + if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) { + cyg_hal_user_break(0); + CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0); + } } void @@ -265,6 +352,43 @@ hal_if_diag_read_char(char *c) } #endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG +//============================================================================= +// CtrlC support +//============================================================================= + +#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \ + || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) + +struct Hal_SavedRegisters *hal_saved_interrupt_state; + +void +hal_ctrlc_isr_init(void) +{ + hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS(); + +#if 1 // Prevents crash on older stubs + if (CYGNUM_CALL_IF_TABLE_VERSION != CYGACC_CALL_IF_VERSION()) + return; +#endif + + CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), + __COMMCTL_IRQ_ENABLE); +} + +cyg_uint32 +hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) +{ + hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS(); + int isr_ret, ctrlc = 0; + + isr_ret = CYGACC_COMM_IF_DBG_ISR(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), + &ctrlc, vector, data); + if (ctrlc) + cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state ); + return isr_ret; +} +#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT || CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT + //-------------------------------------------------------------------------- // Init function. It should be called from the platform initialization code. // For monitor configurations it will initialize the calling interface table, @@ -298,9 +422,10 @@ hal_if_init(void) CYGACC_CALL_IF_ICTRL_TABLE_SET(hal_interrupt_handlers); CYGACC_CALL_IF_EXC_TABLE_SET(hal_vsr_table); - // Reset and kill vector + // Miscellaneous services with wrappers in this file. CYGACC_CALL_IF_RESET_SET(reset); CYGACC_CALL_IF_KILL_VECTOR_SET(kill_by_reset); + CYGACC_CALL_IF_DELAY_US_SET(delay_us); // Comm controls CYGACC_CALL_IF_SET_DEBUG_COMM_SET(set_debug_comm); @@ -310,11 +435,12 @@ hal_if_init(void) CYGACC_CALL_IF_FLUSH_ICACHE_SET(flush_icache); CYGACC_CALL_IF_FLUSH_DCACHE_SET(flush_dcache); - // Clear console procs entry. If platform has been configured - // to use a separate console port, it will be set up later - // (hal_diag_init). Alternatively (if this is a stub) it will - // be initialized with the output mangler (O-packetizer for - // GDB) which uses the debug comms. + // Clear debug and console procs entries. If platform has been + // configured to use a separate console port, it will be set + // up later (hal_diag_init). Alternatively (if this is a stub) + // it will be initialized with the output mangler + // (O-packetizer for GDB) which uses the debug comms. + set_debug_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY); set_console_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY); // Data entries not currently supported in eCos @@ -324,6 +450,9 @@ hal_if_init(void) } #endif + // Reset console interrupt flag. + CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0); + // Set up services provided by clients #if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \ ( defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) \ diff --git a/packages/hal/common/current/src/hal_misc.c b/packages/hal/common/current/src/hal_misc.c index 70c81eeaf..d838efaeb 100644 --- a/packages/hal/common/current/src/hal_misc.c +++ b/packages/hal/common/current/src/hal_misc.c @@ -120,13 +120,28 @@ hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) { cyg_uint32 result; -#if (defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)) && \ - defined(CYGHWR_HAL_GDB_PORT_VECTOR) && \ - defined(HAL_CTRLC_ISR) +#if (defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ + || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT)) && \ + (defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT) || \ + defined(CYGHWR_HAL_GDB_PORT_VECTOR) && \ + defined(HAL_CTRLC_ISR)) #ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN +#if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT + int gdb_vector = -1; + // This check only to avoid crash on older stubs in case of unhandled + // interrupts. It is a bit messy, but required in a transition period. + if (CYGNUM_CALL_IF_TABLE_VERSION == CYGACC_CALL_IF_VERSION()) { + hal_virtual_comm_table_t* comm = CYGACC_CALL_IF_DEBUG_PROCS(); + gdb_vector + = CYGACC_COMM_IF_CONTROL(*comm)(CYGACC_COMM_IF_CH_DATA(*comm), + __COMMCTL_DBG_ISR_VECTOR); + } + if( vector == gdb_vector ) +#else + // Old code using hardwired channels. This should go away eventually. if( vector == CYGHWR_HAL_GDB_PORT_VECTOR ) +#endif #endif { result = HAL_CTRLC_ISR( vector, data ); @@ -137,7 +152,7 @@ hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) result = hal_arch_default_isr (vector, data); if( 0 != result) return result; - CYG_TRACE1(true, "Interrupt: %d", vector); + CYG_TRACE2(true, "Interrupt: %d, Data: 0x%08x", vector, data); CYG_FAIL("Spurious Interrupt!!!"); return 0; } diff --git a/packages/hal/common/current/src/hal_stub.c b/packages/hal/common/current/src/hal_stub.c index c9d90804e..391529d3d 100644 --- a/packages/hal/common/current/src/hal_stub.c +++ b/packages/hal/common/current/src/hal_stub.c @@ -72,8 +72,10 @@ target_register_t registers[NUMREGS]; target_register_t alt_registers[NUMREGS] ; // Thread or saved process state target_register_t * _registers = registers; // Pointer to current set of registers +#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away // Interrupt control. static volatile __PFI __interruptible_control; +#endif //----------------------------------------------------------------------------- // Register access @@ -240,18 +242,34 @@ interruptible(int state) { static int __interrupts_suspended = 0; - if (__interruptible_control) { - if (state) { - __interrupts_suspended--; - if (0 >= __interrupts_suspended) { - __interrupts_suspended = 0; + if (state) { + __interrupts_suspended--; + if (0 >= __interrupts_suspended) { + __interrupts_suspended = 0; +#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away + { + hal_virtual_comm_table_t* __chan; + __chan = CYGACC_CALL_IF_DEBUG_PROCS(); + CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_ENABLE); + } +#else + if (__interruptible_control) __interruptible_control(1); +#endif + } + } else { + __interrupts_suspended++; + if (1 == __interrupts_suspended) +#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away + { + hal_virtual_comm_table_t* __chan; + __chan = CYGACC_CALL_IF_DEBUG_PROCS(); + CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_DISABLE); } - } else { - __interrupts_suspended++; - if (1 == __interrupts_suspended) +#else + if (__interruptible_control) __interruptible_control(0); - } +#endif } } @@ -299,7 +317,11 @@ cyg_hal_gdb_diag_putc(void* __ch_data, cyg_uint8 c) // while we are in the middle of sending a packet. The serial // receive interrupt will be seen when we re-enable interrupts // later. +#ifdef CYG_HAL_STARTUP_ROM + HAL_DISABLE_INTERRUPTS(old); +#else CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old); +#endif while(1) { @@ -336,7 +358,11 @@ cyg_hal_gdb_diag_putc(void* __ch_data, cyg_uint8 c) pos = 0; // And re-enable interrupts +#ifdef CYG_HAL_STARTUP_ROM + HAL_RESTORE_INTERRUPTS(old); +#else CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old); +#endif } CYGARC_HAL_RESTORE_GP(); @@ -454,9 +480,11 @@ __install_traps (void) __cleanup_vec = &handle_exception_cleanup; __init_vec = &handle_exception_init; +#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT // Control of GDB interrupts. __interruptible_control = HAL_STUB_PLATFORM_INTERRUPTIBLE; +#endif #endif // Nothing further to do, handle_exception will be called when an @@ -474,11 +502,6 @@ initHardware (void) initialized = 1; #if !defined(CYGPKG_CYGMON) -#ifdef HAL_STUB_PLATFORM_INIT - // If the platform defines any initialization code, call it here. - HAL_STUB_PLATFORM_INIT(); -#endif - // Get serial port initialized. HAL_STUB_PLATFORM_INIT_SERIAL(); @@ -507,6 +530,11 @@ initHardware (void) // Set the debug channel. CYGACC_CALL_IF_SET_DEBUG_COMM()(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL); } + +#ifdef HAL_STUB_PLATFORM_INIT + // If the platform defines any initialization code, call it here. + HAL_STUB_PLATFORM_INIT(); +#endif #endif #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT diff --git a/packages/hal/powerpc/arch/current/ChangeLog b/packages/hal/powerpc/arch/current/ChangeLog index ec4e46d63..4397e3766 100644 --- a/packages/hal/powerpc/arch/current/ChangeLog +++ b/packages/hal/powerpc/arch/current/ChangeLog @@ -1,3 +1,8 @@ +2000-06-27 Jesper Skov <jskov@redhat.com> + + * src/vectors.S: Removed unnecessary + CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT checks. + 2000-06-15 Jesper Skov <jskov@redhat.com> * include/hal_intr.h: Added HAL_DEFAULT_ISR. diff --git a/packages/hal/powerpc/arch/current/src/vectors.S b/packages/hal/powerpc/arch/current/src/vectors.S index 10dc01d02..f31a2add3 100644 --- a/packages/hal/powerpc/arch/current/src/vectors.S +++ b/packages/hal/powerpc/arch/current/src/vectors.S @@ -347,10 +347,8 @@ _start: # Variant HALs may need to do something special before we continue bl hal_variant_init -#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away # Platform initialization bl hal_platform_init -#endif # MMU and cache are controlled by the same option since caching # on the PPC does not make sense without the MMU to mark regions @@ -378,12 +376,10 @@ _start: #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS bl initialize_stub #endif -#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) .extern hal_ctrlc_isr_init bl hal_ctrlc_isr_init -#endif #endif bl cyg_start # call cyg_start @@ -657,19 +653,6 @@ cyg_hal_default_interrupt_vsr: hal_intc_decode r15,r14 # get table index -#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - .extern cyg_hal_gdb_isr - lwz r3,CYGARC_PPCREG_PC(r14) # for serial receive irq. - bl cyg_hal_gdb_isr # (arg1 is PC) - cmpwi r3,0x0000 # Call ISR proper? - beq 2f # (r3 is 0 when skipping - # to avoid DSR call) -1: -#endif - -#else // the below should remain - #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) # If we are supporting Ctrl-C interrupts from GDB, we must squirrel @@ -681,7 +664,6 @@ cyg_hal_default_interrupt_vsr: stw r14,0(r3) #endif -#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT #ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING @@ -707,14 +689,6 @@ cyg_hal_default_interrupt_vsr: bctrl # branch to ctr reg and link -#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this should go away -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - # If interrupt was caused by GDB, the ISR call above - # is skipped by jumping here. -2: -#endif -#endif - #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK # If we are returning from the last nested interrupt, move back diff --git a/packages/hal/powerpc/cogent/current/ChangeLog b/packages/hal/powerpc/cogent/current/ChangeLog index 686caa614..799fb58d2 100644 --- a/packages/hal/powerpc/cogent/current/ChangeLog +++ b/packages/hal/powerpc/cogent/current/ChangeLog @@ -1,3 +1,17 @@ +2000-06-28 Jesper Skov <jskov@redhat.com> + + * src/hal_diag.c: Cleanup. + +2000-06-26 Jesper Skov <jskov@redhat.com> + + * cdl/hal_powerpc_cogent.cdl: Removed ROM_DEBUG option. + + * include/plf_intr.h: + * src/plf_misc.c: Removed Ctrl-c code. + + * src/hal_diag.c: Snip cruft. Added non-block/timout + features. Moved Ctrl-c support code here. + 2000-06-21 Jesper Skov <jskov@redhat.com> * src/plf_stub.c: Provide plf stub init which prints build date diff --git a/packages/hal/powerpc/cogent/current/cdl/hal_powerpc_cogent.cdl b/packages/hal/powerpc/cogent/current/cdl/hal_powerpc_cogent.cdl index 12d1a1e23..484808020 100644 --- a/packages/hal/powerpc/cogent/current/cdl/hal_powerpc_cogent.cdl +++ b/packages/hal/powerpc/cogent/current/cdl/hal_powerpc_cogent.cdl @@ -90,10 +90,10 @@ cdl_package CYGPKG_HAL_POWERPC_COGENT { cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL { display "Debug serial port" flavor data - legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1 + legal_values 0 to 1 default_value 1 description " - The MBX board has only one serial port. This option + The Cogent board has two serial ports. This option chooses which port will be used to connect to a host running GDB." } @@ -104,26 +104,10 @@ cdl_package CYGPKG_HAL_POWERPC_COGENT { legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1 default_value 1 description " - The MBX board has only one serial port. This option + The Cogent board has two serial ports and an LCD. This option chooses which port will be used for diagnostic output." } - # This option is only used when USE_ROM_MONITOR is enabled - but - # it cannot be a sub-option to that option, since the code uses the - # definition in a preprocessor comparison. - cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_ROM_DEBUG_CHANNEL { - display "Debug serial port used by ROM monitor" - flavor data - legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1 - default_value 1 - description " - The MBX board has only one serial port. This - option tells the code which port is in use by the ROM - monitor. It should only be necessary to change this - option if a non-standard configurated eCos GDB stub is - used." - } - cdl_option CYGHWR_HAL_POWERPC_BOARD_SPEED { display "Development board clock speed (MHz)" flavor data diff --git a/packages/hal/powerpc/cogent/current/include/plf_intr.h b/packages/hal/powerpc/cogent/current/include/plf_intr.h index 1ce9235ff..e5098f631 100644 --- a/packages/hal/powerpc/cogent/current/include/plf_intr.h +++ b/packages/hal/powerpc/cogent/current/include/plf_intr.h @@ -48,22 +48,6 @@ // //========================================================================== -//-------------------------------------------------------------------------- -// Control-C support. - -#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) - -// Serial interrupts are feed to IRQ1 (vector 0x08) on the Cogent -// board. -# define CYGHWR_HAL_GDB_PORT_VECTOR CYGNUM_HAL_INTERRUPT_SIU_IRQ1 - -externC cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data); - -# define HAL_CTRLC_ISR hal_ctrlc_isr - -#endif - //-------------------------------------------------------------------------- #endif // ifndef CYGONCE_HAL_PLF_INTR_H // End of plf_intr.h diff --git a/packages/hal/powerpc/cogent/current/include/plf_stub.h b/packages/hal/powerpc/cogent/current/include/plf_stub.h index 240472710..fcbf2aa1a 100644 --- a/packages/hal/powerpc/cogent/current/include/plf_stub.h +++ b/packages/hal/powerpc/cogent/current/include/plf_stub.h @@ -69,7 +69,6 @@ externC void cyg_hal_plf_comms_init(void); #define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud)) #define HAL_STUB_PLATFORM_INTERRUPTIBLE 0 -#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ() hal_cma_stub_init_break_irq() //---------------------------------------------------------------------------- // Stub initializer. diff --git a/packages/hal/powerpc/cogent/current/src/hal_diag.c b/packages/hal/powerpc/cogent/current/src/hal_diag.c index bb0f6bb58..d7a832a03 100644 --- a/packages/hal/powerpc/cogent/current/src/hal_diag.c +++ b/packages/hal/powerpc/cogent/current/src/hal_diag.c @@ -45,11 +45,9 @@ #include <cyg/hal/hal_diag.h> // our header. -#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) -#include <cyg/hal/hal_stub.h> // CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION -#endif - #include <cyg/infra/cyg_type.h> // base types, externC +#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED +#include <cyg/hal/hal_misc.h> // Helper functions #include <cyg/hal/hal_io.h> // IO macros #include <cyg/hal/hal_intr.h> // Interrupt macros @@ -57,6 +55,9 @@ #include <cyg/hal/hal_if.h> // Calling-if API +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ + || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) + static void cyg_hal_plf_serial_init(void); static void cyg_hal_plf_lcd_init(void); @@ -73,17 +74,7 @@ cyg_hal_plf_comms_init(void) cyg_hal_plf_serial_init(); cyg_hal_plf_lcd_init(); } - -#if 0 -#ifdef CYGSEM_HAL_ROM_MONITOR - // It's handy to have the LCD initialized at reset when using it - // for debugging output. - { - diag_write_string ("eCos ROM " __TIME__ "\n"); - diag_write_string (__DATE__ "\n"); - } -#endif -#endif +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES //============================================================================= // Serial driver @@ -127,6 +118,8 @@ cyg_hal_plf_comms_init(void) // 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 +#define ISR_Tx 0x02 +#define ISR_Rx 0x04 // The line status register bits. #define SIO_LSR_DR 0x01 // data ready @@ -163,7 +156,6 @@ cyg_hal_plf_comms_init(void) #define SIO_FCR_FCR1 0x02 // clear RCVR FIFO #define SIO_FCR_FCR2 0x04 // clear XMIT FIFO - static void init_serial_channel( cyg_uint8* base ) { @@ -210,21 +202,32 @@ init_serial_channel( cyg_uint8* base ) (SIO_FCR_FCR0 | SIO_FCR_FCR1 | SIO_FCR_FCR2)); } +static cyg_bool +cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch) +{ + cyg_uint8* base = (cyg_uint8*)__ch_data; + cyg_uint8 lsr; + + HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr); + if ((lsr & SIO_LSR_DR) == 0) + return false; + + HAL_READ_UINT8(base+CYG_DEV_SERIAL_RBR, *ch); + + return true; +} + + cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data) { - cyg_uint8* base = (cyg_uint8*)__ch_data; - cyg_uint8 c, lsr; + cyg_uint8 ch; CYGARC_HAL_SAVE_GP(); - do { - HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr); - } while ((lsr & SIO_LSR_DR) == 0); - - HAL_READ_UINT8(base+CYG_DEV_SERIAL_RBR, c); + while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch)); CYGARC_HAL_RESTORE_GP(); - return c; + return ch; } void @@ -274,18 +277,116 @@ cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len) CYGARC_HAL_RESTORE_GP(); } +static cyg_int32 msec_timeout[2] = { 1000, 1000 }; + +cyg_bool +cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch) +{ + int delay_count; + cyg_bool res; + CYGARC_HAL_SAVE_GP(); + + // delay in .1 ms steps + delay_count = msec_timeout[__ch_data == (void*)CYG_DEV_SERIAL_BASE_A ? 0 : 1] * 10; + for(;;) { + res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch); + if (res || 0 == delay_count--) + break; + + CYGACC_CALL_IF_DELAY_US()(100); + } + + CYGARC_HAL_RESTORE_GP(); + return res; +} + static int cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...) { - // Do nothing (yet). - return 0; + static int irq_state = 0; + cyg_uint8* base = (cyg_uint8*)__ch_data; + cyg_uint8 ier; + int ret = 0; + CYGARC_HAL_SAVE_GP(); + + switch (__func) { + case __COMMCTL_IRQ_ENABLE: + HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_SIU_IRQ1); + HAL_INTERRUPT_SET_LEVEL(CYGNUM_HAL_INTERRUPT_SIU_IRQ1, 1); + HAL_READ_UINT8(base+CYG_DEV_SERIAL_IER, ier); + ier |= SIO_IER_ERDAI; + HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_IER, ier); + irq_state = 1; + break; + case __COMMCTL_IRQ_DISABLE: + ret = irq_state; + irq_state = 0; + HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_SIU_IRQ1); + HAL_READ_UINT8(base+CYG_DEV_SERIAL_IER, ier); + ier &= ~SIO_IER_ERDAI; + HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_IER, ier); + break; + case __COMMCTL_DBG_ISR_VECTOR: + ret = CYGNUM_HAL_INTERRUPT_SIU_IRQ1; + break; + case __COMMCTL_SET_TIMEOUT: + { + va_list ap; + + va_start(ap, __func); + + ret = msec_timeout[__ch_data == (void*)CYG_DEV_SERIAL_BASE_A ? 0 : 1]; + msec_timeout[__ch_data == (void*)CYG_DEV_SERIAL_BASE_A ? 0 : 1] + = va_arg(ap, cyg_uint32); + + va_end(ap); + } + default: + break; + } + CYGARC_HAL_RESTORE_GP(); + return ret; } -#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES +static int +cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, + CYG_ADDRWORD __vector, CYG_ADDRWORD __data) +{ + cyg_uint8* base = (cyg_uint8*)__ch_data; + cyg_uint8 _iir; + int res = 0; + CYGARC_HAL_SAVE_GP(); + + HAL_READ_UINT8(base+CYG_DEV_SERIAL_IIR, _iir); + _iir &= SIO_IIR_ID_MASK; + + *__ctrlc = 0; + if ( ISR_Rx == _iir ) { + cyg_uint8 c, lsr; + HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr); + if (lsr & SIO_LSR_DR) { + + HAL_READ_UINT8(base+CYG_DEV_SERIAL_RBR, c); + + if( cyg_hal_is_break( &c , 1 ) ) + *__ctrlc = 1; + } + + // Acknowledge the interrupt + HAL_INTERRUPT_ACKNOWLEDGE(CYGNUM_HAL_INTERRUPT_SIU_IRQ1); + res = CYG_ISR_HANDLED; + } + + CYGARC_HAL_RESTORE_GP(); + return res; +} static void cyg_hal_plf_serial_init(void) { + hal_virtual_comm_table_t* comm; + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + // Disable interrupts. HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_SIU_IRQ1); @@ -293,43 +394,48 @@ cyg_hal_plf_serial_init(void) init_serial_channel((cyg_uint8*)CYG_DEV_SERIAL_BASE_A); init_serial_channel((cyg_uint8*)CYG_DEV_SERIAL_BASE_B); -#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ - || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) - { - // Setup procs in the vector table - hal_virtual_comm_table_t* comm; - int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - - // Set channel 0 - CYGACC_CALL_IF_SET_CONSOLE_COMM()(0); - comm = CYGACC_CALL_IF_CONSOLE_PROCS(); - CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_A); - CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); - CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); - CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); - CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); - CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); - - // Set channel 1 - CYGACC_CALL_IF_SET_CONSOLE_COMM()(1); - comm = CYGACC_CALL_IF_CONSOLE_PROCS(); - CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_B); - CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); - CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); - CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); - CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); - CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); - - // Restore original console - CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); - } -#endif + // Setup procs in the vector table + + // Set channel 0 + CYGACC_CALL_IF_SET_CONSOLE_COMM()(0); + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_A); + CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); + CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); + CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); + CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); + CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr); + CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout); + + // Set channel 1 + CYGACC_CALL_IF_SET_CONSOLE_COMM()(1); + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CH_DATA_SET(*comm, CYG_DEV_SERIAL_BASE_B); + CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); + CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); + CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); + CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); + CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr); + CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout); + + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); } +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES + //============================================================================= // LCD driver //============================================================================= + +// The LCD driver is only used by the new vector code. Cannot be used +// by the old compatibility cruft. +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ + || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) + // FEMA 162B 16 character x 2 line LCD // base addresses and register offsets * @@ -486,9 +592,6 @@ cyg_hal_plf_lcd_getc(void* __ch_data) return 0; } -#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ - || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) - static void cyg_hal_plf_lcd_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len) @@ -519,36 +622,31 @@ cyg_hal_plf_lcd_control(void *__ch_data, __comm_control_cmd_t __func, ...) return 0; } -#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES - static void cyg_hal_plf_lcd_init(void) { + hal_virtual_comm_table_t* comm; + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + // Init channel init_lcd_channel((cyg_uint8*)LCD_BASE); -#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ - || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) - { - // Setup procs in the vector table - hal_virtual_comm_table_t* comm; - int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - - // Set channel 2 - CYGACC_CALL_IF_SET_CONSOLE_COMM()(2); - comm = CYGACC_CALL_IF_CONSOLE_PROCS(); - CYGACC_COMM_IF_CH_DATA_SET(*comm, LCD_BASE); - CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_lcd_write); - CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_lcd_read); - CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_lcd_putc); - CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_lcd_getc); - CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_lcd_control); - - // Restore original console - CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); - } -#endif + // Setup procs in the vector table + + // Set channel 2 + CYGACC_CALL_IF_SET_CONSOLE_COMM()(2); + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CH_DATA_SET(*comm, LCD_BASE); + CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_lcd_write); + CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_lcd_read); + CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_lcd_putc); + CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_lcd_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_lcd_control); + + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); } +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES //============================================================================= // Compatibility with older stubs @@ -556,6 +654,10 @@ cyg_hal_plf_lcd_init(void) #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG +#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) +#include <cyg/hal/hal_stub.h> // CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION +#endif + //----------------------------------------------------------------------------- // Assumption: all diagnostic output must be GDB packetized unless // this is a configuration for a stand-alone ROM system. @@ -575,7 +677,7 @@ cyg_hal_plf_lcd_init(void) void hal_diag_init(void) { - cyg_hal_plf_comms_init(); + init_serial_channel(__BASE); } void hal_diag_write_char(char __c) @@ -595,7 +697,7 @@ void hal_diag_init(void) { // Init devices - cyg_hal_plf_comms_init(); + init_serial_channel(__BASE); } void diff --git a/packages/hal/powerpc/cogent/current/src/plf_misc.c b/packages/hal/powerpc/cogent/current/src/plf_misc.c index 8e6354372..8708865d0 100644 --- a/packages/hal/powerpc/cogent/current/src/plf_misc.c +++ b/packages/hal/powerpc/cogent/current/src/plf_misc.c @@ -68,101 +68,4 @@ hal_platform_init(void) hal_if_init(); } - -//-------------------------------------------------------------------------- -// Control C ISR support - -#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) - -#if (1 == CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL) -#define CYG_DEVICE_SERIAL_RS232_16550_BASE CYG_DEVICE_SERIAL_RS232_16550_BASE_B -#else -#define CYG_DEVICE_SERIAL_RS232_16550_BASE CYG_DEVICE_SERIAL_RS232_16550_BASE_A -#endif - -//----------------------------------------------------------------------------- -// There are two serial ports. -#define CYG_DEVICE_SERIAL_RS232_16550_BASE_A 0xe900047 // port A -#define CYG_DEVICE_SERIAL_RS232_16550_BASE_B 0xe900007 // port B - -// receiver buffer register, read, dlab = 0 -#define CYG_DEVICE_SERIAL_RS232_16550_RBR \ - ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x00) -// interrupt enable register, read/write, dlab = 0 -#define CYG_DEVICE_SERIAL_RS232_16550_IER \ - ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x08) -// interrupt identification register, read, dlab = 0 -#define CYG_DEVICE_SERIAL_RS232_16550_IIR \ - ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x10) -// line status register, read -#define CYG_DEVICE_SERIAL_RS232_16550_LSR \ - ((volatile cyg_uint8 *) CYG_DEVICE_SERIAL_RS232_16550_BASE + 0x28) - - -// 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 -#define ISR_Tx 0x02 -#define ISR_Rx 0x04 - -// 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 - -struct Hal_SavedRegisters *hal_saved_interrupt_state; - -void hal_ctrlc_isr_init(void) -{ - // Enable serial receive interrupts. - HAL_WRITE_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_IER, SIO_IER_ERDAI); - - HAL_INTERRUPT_SET_LEVEL(CYGHWR_HAL_GDB_PORT_VECTOR, 1); - HAL_INTERRUPT_UNMASK(CYGHWR_HAL_GDB_PORT_VECTOR); -} - -cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) -{ - cyg_uint8 _iir; - - - HAL_READ_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_IIR, _iir); - _iir &= SIO_IIR_ID_MASK; - - if ( ISR_Rx == _iir ) { - - cyg_uint8 c, lsr; - - HAL_READ_UINT8 (CYG_DEVICE_SERIAL_RS232_16550_LSR, lsr); - if (lsr & SIO_LSR_DR) { - - HAL_READ_UINT8( CYG_DEVICE_SERIAL_RS232_16550_RBR, c ); - - if( cyg_hal_is_break( &c , 1 ) ) - cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state ); - } - - // Acknowledge the interrupt - HAL_INTERRUPT_ACKNOWLEDGE(CYGHWR_HAL_GDB_PORT_VECTOR); - - return CYG_ISR_HANDLED; - } - - return 0; -} - -#endif - // EOF plf_misc.c diff --git a/packages/hal/powerpc/fads/current/ChangeLog b/packages/hal/powerpc/fads/current/ChangeLog index 26b9f8f39..c5fe01258 100644 --- a/packages/hal/powerpc/fads/current/ChangeLog +++ b/packages/hal/powerpc/fads/current/ChangeLog @@ -1,3 +1,7 @@ +2000-06-26 Jesper Skov <jskov@redhat.com> + + * cdl/hal_powerpc_fads.cdl: Removed ROM_DEBUG_CHANNEL option. + 2000-06-15 Jesper Skov <jskov@redhat.com> * src/hal_diag.c: diff --git a/packages/hal/powerpc/fads/current/cdl/hal_powerpc_fads.cdl b/packages/hal/powerpc/fads/current/cdl/hal_powerpc_fads.cdl index 2d8cda44a..c2ef2b92c 100644 --- a/packages/hal/powerpc/fads/current/cdl/hal_powerpc_fads.cdl +++ b/packages/hal/powerpc/fads/current/cdl/hal_powerpc_fads.cdl @@ -102,22 +102,6 @@ cdl_package CYGPKG_HAL_POWERPC_FADS { chooses which port will be used for diagnostic output." } - # This option is only used when USE_ROM_MONITOR is enabled - but - # it cannot be a sub-option to that option, since the code uses the - # definition in a preprocessor comparison. - cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_ROM_DEBUG_CHANNEL { - display "Debug serial port used by ROM monitor" - flavor data - legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1 - default_value 0 - description " - The FADS board has only one serial port. This - option tells the code which port is in use by the ROM - monitor. It should only be necessary to change this - option if a non-standard configurated eCos GDB stub is - used." - } - # Real-time clock/counter specifics cdl_component CYGNUM_HAL_RTC_CONSTANTS { display "Real-time clock constants." diff --git a/packages/hal/powerpc/mbx/current/ChangeLog b/packages/hal/powerpc/mbx/current/ChangeLog index 8071d4c8f..d4a43206b 100644 --- a/packages/hal/powerpc/mbx/current/ChangeLog +++ b/packages/hal/powerpc/mbx/current/ChangeLog @@ -1,3 +1,9 @@ +2000-06-28 Jesper Skov <jskov@redhat.com> + + * include/hal_diag.h: + * src/hal_diag.c: + Cleanup. + 2000-06-22 John Dallaway <jld@redhat.com> * include/pkgconf/mlt_powerpc_mbx_rom.mlt: diff --git a/packages/hal/powerpc/mbx/current/include/hal_diag.h b/packages/hal/powerpc/mbx/current/include/hal_diag.h index b73f64b4f..974b6813a 100644 --- a/packages/hal/powerpc/mbx/current/include/hal_diag.h +++ b/packages/hal/powerpc/mbx/current/include/hal_diag.h @@ -69,10 +69,6 @@ #include <cyg/infra/cyg_type.h> -externC void cyg_hal_plf_serial_init(void); -externC void cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 __ch); -externC cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data); - #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) #include <cyg/hal/hal_if.h> diff --git a/packages/hal/powerpc/mbx/current/src/hal_diag.c b/packages/hal/powerpc/mbx/current/src/hal_diag.c index 399631745..a5e6e06ab 100644 --- a/packages/hal/powerpc/mbx/current/src/hal_diag.c +++ b/packages/hal/powerpc/mbx/current/src/hal_diag.c @@ -134,7 +134,7 @@ void hal_diag_init(void) eppc = eppc_base(); // init the actual serial port - cyg_hal_plf_serial_init(); + cyg_hal_plf_serial_init_channel(); #ifndef CYGDBG_HAL_DIAG_DISABLE_GDB_PROTOCOL #ifndef CYG_HAL_STARTUP_ROM // We are talking to GDB; ack the "go" packet! diff --git a/packages/hal/powerpc/quicc/current/ChangeLog b/packages/hal/powerpc/quicc/current/ChangeLog index 1f84dde09..c2da6b3f1 100644 --- a/packages/hal/powerpc/quicc/current/ChangeLog +++ b/packages/hal/powerpc/quicc/current/ChangeLog @@ -1,3 +1,19 @@ +2000-06-28 Jesper Skov <jskov@redhat.com> + + * include/quicc_smc1.h: + * src/quicc_smc1.c: Cleanup. + +2000-06-26 Jesper Skov <jskov@redhat.com> + + * include/quicc_smc1.h: + * src/quicc_smc1.c: Added non-block/timout features. Reworked + Ctrl-c support code. + +2000-06-22 Jesper Skov <jskov@redhat.com> + + * src/quicc_smc1.c: Fix compiler warning. Add functions to deal + with ctrl-c interrupts from the device. + 2000-06-21 Jesper Skov <jskov@redhat.com> * src/quicc_smc1.c: diff --git a/packages/hal/powerpc/quicc/current/include/quicc_smc1.h b/packages/hal/powerpc/quicc/current/include/quicc_smc1.h index 60dfd0463..945d7a71c 100644 --- a/packages/hal/powerpc/quicc/current/include/quicc_smc1.h +++ b/packages/hal/powerpc/quicc/current/include/quicc_smc1.h @@ -48,21 +48,14 @@ #include <cyg/infra/cyg_type.h> #include <cyg/hal/quicc/ppc8xx.h> // FIXME: bad, but need eppc_base + +#if !defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) +// This one should only be used by old-stub compatibility code! +externC void cyg_hal_plf_serial_init_channel(void); +#endif + externC void cyg_hal_plf_serial_init(void); externC void cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 __ch); externC cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data); -//-------------------------------------------------------------------------- -// Control-C support. - -#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) - -#define CYGHWR_HAL_GDB_PORT_VECTOR CYGNUM_HAL_INTERRUPT_CPM_SMC1 -externC cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data); - -# define HAL_CTRLC_ISR hal_ctrlc_isr - -#endif - #endif /* CYGONCE_HAL_PPC_QUICC_SMC1_H */ diff --git a/packages/hal/powerpc/quicc/current/src/quicc_smc1.c b/packages/hal/powerpc/quicc/current/src/quicc_smc1.c index b6795e70c..78e2ecfb6 100644 --- a/packages/hal/powerpc/quicc/current/src/quicc_smc1.c +++ b/packages/hal/powerpc/quicc/current/src/quicc_smc1.c @@ -60,14 +60,11 @@ #include <cyg/hal/quicc/quicc_smc1.h> -#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) #include <cyg/hal/hal_stub.h> // target_register_t #include <cyg/hal/hal_intr.h> // HAL_INTERRUPT_UNMASK(...) #include <cyg/hal/hal_if.h> // Calling interface definitions #include <cyg/hal/hal_misc.h> // Helper functions #include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED -#endif #define UART_BIT_RATE(n) (((int)(CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000)/16)/n) #define UART_BAUD_RATE CYGNUM_HAL_QUICC_DIAG_BAUD @@ -92,8 +89,8 @@ * The basic initialization steps are from Section 16.15.8 * of that manual. */ -static void -init_smc1_uart(void) +void +cyg_hal_plf_serial_init_channel(void) { EPPC *eppc; volatile struct smc_uart_pram *uart_pram; @@ -286,22 +283,22 @@ cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 ch) CYGARC_HAL_RESTORE_GP(); } -cyg_uint8 -cyg_hal_plf_serial_getc(void* __ch_data) + +static cyg_bool +cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch) { volatile struct cp_bufdesc *bd; - char ch; EPPC *eppc = (EPPC*) __ch_data; volatile struct smc_uart_pram *uart_pram = &eppc->pram[2].scc.pothers.smc_modem.psmc.u; int cache_state; - CYGARC_HAL_SAVE_GP(); /* rx buffer descriptor */ bd = (struct cp_bufdesc *)((char *)eppc + uart_pram->rbptr); - while (bd->ctrl & QUICC_BD_CTL_Ready) ; + if (bd->ctrl & QUICC_BD_CTL_Ready) + return false; - ch = bd->buffer[0]; + *ch = bd->buffer[0]; bd->length = 0; bd->buffer[0] = '\0'; @@ -312,10 +309,26 @@ cyg_hal_plf_serial_getc(void* __ch_data) HAL_DCACHE_INVALIDATE(bd->buffer, uart_pram->mrblr); // Make sure no stale data } + return true; +} + +cyg_uint8 +cyg_hal_plf_serial_getc(void* __ch_data) +{ + cyg_uint8 ch; + CYGARC_HAL_SAVE_GP(); + + while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch)); + CYGARC_HAL_RESTORE_GP(); return ch; } + + +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ + || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) + static void cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len) @@ -339,132 +352,82 @@ cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len) CYGARC_HAL_RESTORE_GP(); } -static int -cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...) -{ - // Do nothing (yet). - return 0; -} +cyg_int32 msec_timeout = 1000; -/* - * Early initialization of comm channels. Must not rely - * on interrupts, yet. Interrupt operation can be enabled - * in _bsp_board_init(). - */ -void -cyg_hal_plf_serial_init(void) +cyg_bool +cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch) { - volatile EPPC *eppc = eppc_base(); - int i; - - static int init = 0; // It's wrong to do this more than once - if (init) return; - init++; - - /* - * Reset communications processor - */ - eppc->cp_cr = QUICC_CPM_CR_RESET | QUICC_CPM_CR_BUSY; - for (i = 0; i < 100000; i++); - - init_smc1_uart(); + int delay_count = msec_timeout * 10; // delay in .1 ms steps + cyg_bool res; + CYGARC_HAL_SAVE_GP(); -#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ - || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) - { - // Setup procs in the vector table - hal_virtual_comm_table_t* comm; - int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); - - // Set channel 0 - CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);// Should be configurable! - comm = CYGACC_CALL_IF_CONSOLE_PROCS(); - CYGACC_COMM_IF_CH_DATA_SET(*comm, eppc_base()); - CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); - CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); - CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); - CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); - CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); - - // Restore original console - CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); + for(;;) { + res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch); + if (res || 0 == delay_count--) + break; + + CYGACC_CALL_IF_DELAY_US()(100); } -#endif -} - -#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // the below should be removed + CYGARC_HAL_RESTORE_GP(); + return res; +} -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT -// This ISR is called from the interrupt handler. This should only -// happen when there is no real serial driver, so the code shouldn't -// mess anything up. -int cyg_hal_gdb_isr( target_register_t pc ) +static int +cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...) { - EPPC *eppc = eppc_base(); - struct cp_bufdesc *bd; - char ch; - - eppc->smc_regs[0].smc_smce = 0xff; - - /* rx buffer descriptors */ - bd = (struct cp_bufdesc *)((char *)eppc_base() + Rxbd); + static int irq_state = 0; + int ret = 0; + CYGARC_HAL_SAVE_GP(); - if ((bd->ctrl & QUICC_BD_CTL_Ready) == 0) { - // then there be a character waiting - ch = bd->buffer[0]; - bd->length = 1; - bd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Wrap | QUICC_BD_CTL_Int; + switch (__func) { + case __COMMCTL_IRQ_ENABLE: + HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_CPM_SMC1); + irq_state = 1; + break; + case __COMMCTL_IRQ_DISABLE: + ret = irq_state; + irq_state = 0; + HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_CPM_SMC1); + break; + case __COMMCTL_DBG_ISR_VECTOR: + ret = CYGNUM_HAL_INTERRUPT_CPM_SMC1; + break; + case __COMMCTL_SET_TIMEOUT: + { + va_list ap; - if ( 3 == ch ) { - // Ctrl-C: set a breakpoint at PC so GDB will display the - // correct program context when stopping rather than the - // interrupt handler. - cyg_hal_gdb_interrupt( pc ); + va_start(ap, __func); - // Interrupt handled. Don't call ISR proper. At return - // from the VSR, execution will stop at the breakpoint - // just set. + ret = msec_timeout; + msec_timeout = va_arg(ap, cyg_uint32); - eppc->cpmi_cisr = 0x10; - return 0; - } + va_end(ap); + } + default: + break; } - eppc->cpmi_cisr = 0x10; // acknowledge the Rx event anyway - // in case it was left over from polled reception - // Not caused by GDB. Call ISR proper. - return 1; -} -#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - - -#else // the below stays - -#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) - -struct Hal_SavedRegisters *hal_saved_interrupt_state; - -void -hal_ctrlc_isr_init(void) -{ - HAL_INTERRUPT_UNMASK(CYGHWR_HAL_GDB_PORT_VECTOR); + CYGARC_HAL_RESTORE_GP(); + return ret; } - -cyg_uint32 -hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) +static int +cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, + CYG_ADDRWORD __vector, CYG_ADDRWORD __data) { - EPPC *eppc = eppc_base(); + EPPC *eppc = (EPPC*) __ch_data; struct cp_bufdesc *bd; char ch; + int res = 0; + CYGARC_HAL_SAVE_GP(); + *__ctrlc = 0; if (eppc->smc_regs[0].smc_smce & QUICC_SMCE_RX) { eppc->smc_regs[0].smc_smce = QUICC_SMCE_RX; /* rx buffer descriptors */ - bd = (struct cp_bufdesc *)((char *)eppc_base() + Rxbd); + bd = (struct cp_bufdesc *)((char *)eppc + Rxbd); if ((bd->ctrl & QUICC_BD_CTL_Ready) == 0) { @@ -474,19 +437,62 @@ hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) bd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Wrap | QUICC_BD_CTL_Int; if( cyg_hal_is_break( &ch , 1 ) ) - cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state ); + *__ctrlc = 1; } // Interrupt handled. Acknowledge it. eppc->cpmi_cisr = 0x10; - return CYG_ISR_HANDLED; + res = CYG_ISR_HANDLED; } - // Not a serial interrupt. - return 0; + CYGARC_HAL_RESTORE_GP(); + return res; } -#endif -#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT + +/* + * Early initialization of comm channels. Must not rely + * on interrupts, yet. Interrupt operation can be enabled + * in _bsp_board_init(). + */ +void +cyg_hal_plf_serial_init(void) +{ + hal_virtual_comm_table_t* comm; + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + volatile EPPC *eppc = eppc_base(); + int i; + + static int init = 0; // It's wrong to do this more than once + if (init) return; + init++; + + /* + * Reset communications processor + */ + eppc->cp_cr = QUICC_CPM_CR_RESET | QUICC_CPM_CR_BUSY; + for (i = 0; i < 100000; i++); + + cyg_hal_plf_serial_init_channel(); + + // Setup procs in the vector table + + // Set channel 0 + CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);// Should be configurable! + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CH_DATA_SET(*comm, eppc_base()); + CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); + CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); + CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); + CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); + CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr); + CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout); + + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); +} + +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES #endif // CYGPKG_HAL_POWERPC_MPC860 // EOF quicc_smc1.c diff --git a/packages/hal/powerpc/sim/current/ChangeLog b/packages/hal/powerpc/sim/current/ChangeLog index 5d1cecc33..0eb14046d 100644 --- a/packages/hal/powerpc/sim/current/ChangeLog +++ b/packages/hal/powerpc/sim/current/ChangeLog @@ -1,3 +1,10 @@ +2000-06-27 Jesper Skov <jskov@redhat.com> + + * src/hal_aux.c (hal_platform_init): Added. + + * cdl/hal_powerpc_sim.cdl: Does not support CTRLC (sim handles + that, no target code required). + 2000-04-11 Jesper Skov <jskov@redhat.com> * cdl/hal_powerpc_sim.cdl: Force inclusion of vectors, disable diff --git a/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl b/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl index 57ad89371..2c8fdde8d 100644 --- a/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl +++ b/packages/hal/powerpc/sim/current/cdl/hal_powerpc_sim.cdl @@ -55,6 +55,8 @@ cdl_package CYGPKG_HAL_POWERPC_SIM { compile sim.S hal_aux.c + implements CYGINT_HAL_DEBUG_GDB_CTRLC_UNSUPPORTED + define_proc { puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_powerpc_ppc60x.h>" puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_powerpc_sim.h>" diff --git a/packages/hal/powerpc/sim/current/src/hal_aux.c b/packages/hal/powerpc/sim/current/src/hal_aux.c index 13743d26e..0de5b2ef8 100644 --- a/packages/hal/powerpc/sim/current/src/hal_aux.c +++ b/packages/hal/powerpc/sim/current/src/hal_aux.c @@ -55,4 +55,10 @@ CYGARC_MEMDESC_TABLE CYGBLD_ATTRIB_WEAK = { CYGARC_MEMDESC_TABLE_END }; +//----------------------------------------------------------------------------- +void +hal_platform_init(void) +{ +} + // EOF hal_aux.c diff --git a/packages/hal/sh/arch/current/ChangeLog b/packages/hal/sh/arch/current/ChangeLog index fa58ab9ce..e5f65fe30 100644 --- a/packages/hal/sh/arch/current/ChangeLog +++ b/packages/hal/sh/arch/current/ChangeLog @@ -1,3 +1,38 @@ +2000-06-29 Gary Thomas <gthomas@redhat.com> + + * src/vectors.S: Reorg initialization (reset) code to be all + in one, non-fixed location. Required for platforms with more + complex initialization sequences. + +2000-06-29 Jesper Skov <jskov@redhat.com> + + * src/sh3_sci.c: + * src/sh3_scif.c: + Use per-channel data structure instead of code cruft. + +2000-06-28 Jesper Skov <jskov@redhat.com> + + * include/sh3_sci.h: [added] + * include/sh3_scif.h: [added] + * include/sh3_scif.inl: [removed] + * include/sh_sci.inl: [removed] + * src/sh3_sci.c: [added] + * src/sh3_scif.c: [added] + * cdl/hal_sh.cdl: + Rewrote serial drivers for comm procs usage. + +2000-06-27 Jesper Skov <jskov@redhat.com> + + * src/vectors.S: Added arch and platform init calls. Added ctrlc + init call. Replaced old BREAK magic with new ctrlc magic. + + * src/sh.ld: Added extra _ on NETDEVTAB labels. Define + hal_virtual_vector_table. + + * src/hal_misc.c: hal_default_isr moved to common HAL. + + * cdl/hal_sh.cdl: Also build simple drivers. + 2000-06-15 Jesper Skov <jskov@redhat.com> * include/hal_intr.h: Added HAL_DEFAULT_ISR. diff --git a/packages/hal/sh/arch/current/cdl/hal_sh.cdl b/packages/hal/sh/arch/current/cdl/hal_sh.cdl index 903204425..b133dfe02 100644 --- a/packages/hal/sh/arch/current/cdl/hal_sh.cdl +++ b/packages/hal/sh/arch/current/cdl/hal_sh.cdl @@ -58,7 +58,7 @@ cdl_package CYGPKG_HAL_SH { requires 1 == CYGINT_HAL_SH_VARIANT } - compile hal_misc.c context.S sh_stub.c + compile hal_misc.c context.S sh_stub.c sh3_sci.c sh3_scif.c # The "-o file" is a workaround for CR100958 - without it the # output file would end up in the source directory under CygWin. diff --git a/packages/hal/sh/arch/current/include/sh3_sci.h b/packages/hal/sh/arch/current/include/sh3_sci.h new file mode 100644 index 000000000..eab5879b7 --- /dev/null +++ b/packages/hal/sh/arch/current/include/sh3_sci.h @@ -0,0 +1,81 @@ +//============================================================================= +// +// sh3_sci.h +// +// Simple driver for the SH Serial Communication Interface (SCI) +// +//============================================================================= +//####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-05-17 +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include <pkgconf/hal.h> + +#ifdef CYGNUM_HAL_SH_SH3_SCI_PORTS + +//-------------------------------------------------------------------------- +// SCI register offsets +#ifdef CYGARC_SH_MOD_SCI_V2 +# define _REG_SCSPTR -0x4 // serial port register +#endif +#define _REG_SCSMR 0x0 // serial mode register +#define _REG_SCBRR 0x2 // bit rate register +#define _REG_SCSCR 0x4 // serial control register +#define _REG_SCTDR 0x6 // transmit data register +#define _REG_SCSSR 0x8 // serial status register +#define _REG_SCRDR 0xa // receive data register + +//-------------------------------------------------------------------------- + +typedef struct { + cyg_uint8* base; + cyg_int32 msec_timeout; + int isr_vector; +} channel_data_t; + +//-------------------------------------------------------------------------- + +#if !defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) +// This one should only be used by old-stub compatibility code! +externC void cyg_hal_plf_sci_init_channel(const channel_data_t* chan); +#endif + +externC cyg_uint8 cyg_hal_plf_sci_getc(void* __ch_data); +externC void cyg_hal_plf_sci_putc(void* __ch_data, cyg_uint8 c); +externC void cyg_hal_plf_sci_init(int sci_index, int comm_index, + int rcv_vect, cyg_uint8* base); + + +#endif // CYGNUM_HAL_SH_SH3_SCI_PORTS +//----------------------------------------------------------------------------- +// end of sh3_sci.h diff --git a/packages/hal/sh/arch/current/include/sh3_scif.h b/packages/hal/sh/arch/current/include/sh3_scif.h new file mode 100644 index 000000000..d88e1fa4a --- /dev/null +++ b/packages/hal/sh/arch/current/include/sh3_scif.h @@ -0,0 +1,88 @@ +//============================================================================= +// +// sh3_scif.h +// +// Simple driver for the SH3 Serial Communication Interface with FIFO +// +//============================================================================= +//####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-03-30 +// Description: Simple driver for the SH Serial Communication Interface +// The driver can be used for either the SCIF or the IRDA +// modules (the latter can act as the former). +// Clients of this file can configure the behavior with: +// CYGNUM_SCIF_PORTS: number of SCI ports +// +// Note: It should be possible to configure a channel to IRDA mode. +// Worry about that when some board needs it. +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include <pkgconf/hal.h> + +#ifdef CYGNUM_HAL_SH_SH3_SCIF_PORTS + +//-------------------------------------------------------------------------- +// SCIF register offsets +#define _REG_SCSMR 0x00 +#define _REG_SCBRR 0x02 +#define _REG_SCSCR 0x04 +#define _REG_SCFTDR 0x06 +#define _REG_SCSSR 0x08 +#define _REG_SCFRDR 0x0a +#define _REG_SCFCR 0x0c +#define _REG_SCFDR 0x0e + +//-------------------------------------------------------------------------- + +typedef struct { + cyg_uint8* base; + cyg_int32 msec_timeout; + int isr_vector; +} channel_data_t; + +//-------------------------------------------------------------------------- + +#if !defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) +// This one should only be used by old-stub compatibility code! +externC void cyg_hal_plf_scif_init_channel(const channel_data_t* chan); +#endif + +externC cyg_uint8 cyg_hal_plf_scif_getc(void* __ch_data); +externC void cyg_hal_plf_scif_putc(void* __ch_data, cyg_uint8 c); +void cyg_hal_plf_scif_init(int scif_index, int comm_index, + int rcv_vect, cyg_uint8* base); + + +#endif // CYGNUM_HAL_SH_SH3_SCIF_PORTS +//----------------------------------------------------------------------------- +// end of sh3_scif.h diff --git a/packages/hal/sh/arch/current/src/hal_misc.c b/packages/hal/sh/arch/current/src/hal_misc.c index c25decd28..b47723f22 100644 --- a/packages/hal/sh/arch/current/src/hal_misc.c +++ b/packages/hal/sh/arch/current/src/hal_misc.c @@ -125,12 +125,8 @@ cyg_hal_exception_handler(HAL_SavedRegisters *regs) //--------------------------------------------------------------------------- // Default ISR externC cyg_uint32 -hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) +hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) { - diag_printf("Interrupt: %d\n", vector); - - CYG_FAIL("Spurious Interrupt!!!"); - return 0; } @@ -205,5 +201,13 @@ cyg_hal_enable_caches(void) HAL_UCACHE_ENABLE(); } +//--------------------------------------------------------------------------- +// SH3 variant stuff +// This should be split out... +void +hal_variant_init(void) +{ +} + //--------------------------------------------------------------------------- // End of hal_misc.c diff --git a/packages/hal/sh/arch/current/src/sh.ld b/packages/hal/sh/arch/current/src/sh.ld index 332bd5170..b0bde1286 100644 --- a/packages/hal/sh/arch/current/src/sh.ld +++ b/packages/hal/sh/arch/current/src/sh.ld @@ -103,7 +103,7 @@ GROUP(libtarget.a libgcc.a) KEEP(*(SORT(.dtors*))) ___DTOR_END__ = ABSOLUTE(.); \ . = ALIGN(8); \ ___DEVTAB__ = ABSOLUTE (.); KEEP (*(SORT (.devtab*))) ___DEVTAB_END__ = ABSOLUTE (.); \ - __NETDEVTAB__ = ABSOLUTE (.); KEEP (*(SORT (.netdevtab*))) __NETDEVTAB_END__ = ABSOLUTE (.); \ + ___NETDEVTAB__ = ABSOLUTE (.); KEEP (*(SORT (.netdevtab*))) ___NETDEVTAB_END__ = ABSOLUTE (.); \ } > _region_ \ __rom_data_start = LOADADDR(.data); \ __ram_data_end = .; PROVIDE(__ram_data_end = .); \ @@ -122,6 +122,7 @@ GROUP(libtarget.a libgcc.a) #include CYGHWR_MEMORY_LAYOUT_LDI #include CYGBLD_HAL_PLATFORM_H -// Define VSR table to reside at fixed address. +// Define VSR and vector tables to reside at fixed address. _hal_vsr_table = CYGHWR_HAL_VSR_TABLE; +_hal_virtual_vector_table = CYGHWR_HAL_VECTOR_TABLE; diff --git a/packages/hal/sh/arch/current/src/sh3_sci.c b/packages/hal/sh/arch/current/src/sh3_sci.c new file mode 100644 index 000000000..f03ff64c7 --- /dev/null +++ b/packages/hal/sh/arch/current/src/sh3_sci.c @@ -0,0 +1,303 @@ +//============================================================================= +// +// sh3_sci.c +// +// Simple driver for the SH Serial Communication Interface (SCI) +// +//============================================================================= +//####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-05-17 +// Description: Simple driver for the SH Serial Communication Interface +// Clients of this file can configure the behavior with: +// CYGNUM_SCI_PORTS: number of SCI ports +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include <pkgconf/hal.h> + +#ifdef CYGNUM_HAL_SH_SH3_SCI_PORTS + +#include <cyg/hal/hal_io.h> // IO macros +#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED +#include <cyg/hal/hal_misc.h> // Helper functions +#include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS +#include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP +#include <cyg/hal/hal_if.h> // Calling-if API +#include <cyg/hal/sh_regs.h> // serial register definitions + +#include <cyg/hal/sh3_sci.h> // our header + +//-------------------------------------------------------------------------- + +void +cyg_hal_plf_sci_init_channel(const channel_data_t* chan) +{ + cyg_uint8 tmp; + cyg_uint8* base = chan->base; + + // Disable Tx/Rx interrupts, but enable Tx/Rx + HAL_WRITE_UINT8(base+_REG_SCSCR, + CYGARC_REG_SCSCR_TE|CYGARC_REG_SCSCR_RE); + + // 8-1-no parity. + HAL_WRITE_UINT8(base+_REG_SCSMR, 0); + + // Set speed to 38400 + HAL_READ_UINT8(base+_REG_SCSMR, tmp); + tmp &= ~CYGARC_REG_SCSMR_CKSx_MASK; + tmp |= CYGARC_SCBRR_CKSx(38400); + HAL_WRITE_UINT8(base+_REG_SCSMR, tmp); + HAL_WRITE_UINT8(base+_REG_SCBRR, CYGARC_SCBRR_N(38400)); +} + +static cyg_bool +cyg_hal_plf_sci_getc_nonblock(void* __ch_data, cyg_uint8* ch) +{ + cyg_uint8* base = ((channel_data_t*)__ch_data)->base; + cyg_uint8 sr; + + HAL_READ_UINT8(base+_REG_SCSSR, sr); + if ((sr & CYGARC_REG_SCSSR_RDRF) == 0) + return false; + + HAL_READ_UINT8(base+_REG_SCRDR, *ch); + + // Clear buffer full flag. + HAL_WRITE_UINT8(base+_REG_SCSSR, sr & ~CYGARC_REG_SCSSR_RDRF); + + return true; +} + +cyg_uint8 +cyg_hal_plf_sci_getc(void* __ch_data) +{ + cyg_uint8 ch; + CYGARC_HAL_SAVE_GP(); + + while(!cyg_hal_plf_sci_getc_nonblock(__ch_data, &ch)); + + CYGARC_HAL_RESTORE_GP(); + return ch; +} + +void +cyg_hal_plf_sci_putc(void* __ch_data, cyg_uint8 c) +{ + cyg_uint8* base = ((channel_data_t*)__ch_data)->base; + cyg_uint8 sr; + CYGARC_HAL_SAVE_GP(); + + do { + HAL_READ_UINT8(base+_REG_SCSSR, sr); + } while ((sr & CYGARC_REG_SCSSR_TDRE) == 0); + + HAL_WRITE_UINT8(base+_REG_SCTDR, c); + + // Clear empty flag. + HAL_WRITE_UINT8(base+_REG_SCSSR, sr & ~CYGARC_REG_SCSSR_TDRE); + + // Hang around until the character has been safely sent. + do { + HAL_READ_UINT8(base+_REG_SCSSR, sr); + } while ((sr & CYGARC_REG_SCSSR_TDRE) == 0); + + CYGARC_HAL_RESTORE_GP(); +} + +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ + || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) + +static channel_data_t channels[CYGNUM_HAL_SH_SH3_SCI_PORTS]; + +static void +cyg_hal_plf_sci_write(void* __ch_data, const cyg_uint8* __buf, + cyg_uint32 __len) +{ + CYGARC_HAL_SAVE_GP(); + + while(__len-- > 0) + cyg_hal_plf_sci_putc(__ch_data, *__buf++); + + CYGARC_HAL_RESTORE_GP(); +} + +static void +cyg_hal_plf_sci_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len) +{ + CYGARC_HAL_SAVE_GP(); + + while(__len-- > 0) + *__buf++ = cyg_hal_plf_sci_getc(__ch_data); + + CYGARC_HAL_RESTORE_GP(); +} + +cyg_bool +cyg_hal_plf_sci_getc_timeout(void* __ch_data, cyg_uint8* ch) +{ + channel_data_t* chan = (channel_data_t*)__ch_data; + int delay_count; + cyg_bool res; + CYGARC_HAL_SAVE_GP(); + + delay_count = chan->msec_timeout * 10; // delay in .1 ms steps + + for(;;) { + res = cyg_hal_plf_sci_getc_nonblock(__ch_data, ch); + if (res || 0 == delay_count--) + break; + + CYGACC_CALL_IF_DELAY_US()(100); + } + + CYGARC_HAL_RESTORE_GP(); + return res; +} + +static int +cyg_hal_plf_sci_control(void *__ch_data, __comm_control_cmd_t __func, ...) +{ + static int irq_state = 0; + channel_data_t* chan = (channel_data_t*)__ch_data; + cyg_uint8 scr; + int ret = 0; + CYGARC_HAL_SAVE_GP(); + + switch (__func) { + case __COMMCTL_IRQ_ENABLE: + irq_state = 1; + HAL_INTERRUPT_UNMASK(chan->isr_vector); + HAL_READ_UINT8(chan->base+_REG_SCSCR, scr); + scr |= CYGARC_REG_SCSCR_RIE; + HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr); + break; + case __COMMCTL_IRQ_DISABLE: + ret = irq_state; + irq_state = 0; + HAL_INTERRUPT_UNMASK(chan->isr_vector); + HAL_READ_UINT8(chan->base+_REG_SCSCR, scr); + scr &= ~CYGARC_REG_SCSCR_RIE; + HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr); + break; + case __COMMCTL_DBG_ISR_VECTOR: + ret = chan->isr_vector; + break; + case __COMMCTL_SET_TIMEOUT: + { + va_list ap; + + va_start(ap, __func); + + ret = chan->msec_timeout; + chan->msec_timeout = va_arg(ap, cyg_uint32); + + va_end(ap); + } + default: + break; + } + CYGARC_HAL_RESTORE_GP(); + return ret; +} + +static int +cyg_hal_plf_sci_isr(void *__ch_data, int* __ctrlc, + CYG_ADDRWORD __vector, CYG_ADDRWORD __data) +{ + cyg_uint8 c, sr; + cyg_uint8* base = ((channel_data_t*)__ch_data)->base; + int res = 0; + CYGARC_HAL_SAVE_GP(); + + *__ctrlc = 0; + HAL_READ_UINT8(base+_REG_SCSSR, sr); + if (sr & CYGARC_REG_SCSSR_RDRF) { + HAL_READ_UINT8(base+_REG_SCRDR, c); + + // Clear buffer full flag. + HAL_WRITE_UINT8(base+_REG_SCSSR, + CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF); + + if( cyg_hal_is_break( &c , 1 ) ) + *__ctrlc = 1; + + res = CYG_ISR_HANDLED; + } + + CYGARC_HAL_RESTORE_GP(); + return res; +} + +void +cyg_hal_plf_sci_init(int sci_index, int comm_index, + int rcv_vect, cyg_uint8* base) +{ + channel_data_t* chan = &channels[sci_index]; + hal_virtual_comm_table_t* comm; + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + + // Initialize channel table + chan->base = base; + chan->isr_vector = rcv_vect; + chan->msec_timeout = 1000; + + // Disable interrupts. + HAL_INTERRUPT_MASK(chan->isr_vector); + + // Init channel + + cyg_hal_plf_sci_init_channel(chan); + + // Setup procs in the vector table + + // Initialize channel procs + CYGACC_CALL_IF_SET_CONSOLE_COMM()(comm_index); + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CH_DATA_SET(*comm, chan); + CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_sci_write); + CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_sci_read); + CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_sci_putc); + CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_sci_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_sci_control); + CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_sci_isr); + CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_sci_getc_timeout); + + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); +} + +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES + +#endif // CYGNUM_HAL_SH_SH3_SCI_PORTS + +//----------------------------------------------------------------------------- +// end of sh_sci.c diff --git a/packages/hal/sh/arch/current/src/sh3_scif.c b/packages/hal/sh/arch/current/src/sh3_scif.c new file mode 100644 index 000000000..a87187656 --- /dev/null +++ b/packages/hal/sh/arch/current/src/sh3_scif.c @@ -0,0 +1,337 @@ +//============================================================================= +// +// sh3_scif.c +// +// Simple driver for the SH3 Serial Communication Interface with FIFO +// +//============================================================================= +//####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-03-30 +// Description: Simple driver for the SH Serial Communication Interface +// The driver can be used for either the SCIF or the IRDA +// modules (the latter can act as the former). +// Clients of this file can configure the behavior with: +// CYGNUM_SCIF_PORTS: number of SCI ports +// +// Note: It should be possible to configure a channel to IRDA mode. +// Worry about that when some board needs it. +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include <pkgconf/hal.h> + +#ifdef CYGNUM_HAL_SH_SH3_SCIF_PORTS + +#include <cyg/hal/hal_io.h> // IO macros +#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED +#include <cyg/hal/hal_misc.h> // Helper functions +#include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS +#include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP +#include <cyg/hal/hal_if.h> // Calling-if API +#include <cyg/hal/sh_regs.h> // serial register definitions +#include <cyg/hal/sh_stub.h> // target_register_t + +#include <cyg/hal/sh3_scif.h> // our header + +//-------------------------------------------------------------------------- + +void +cyg_hal_plf_scif_init_channel(const channel_data_t* chan) +{ + cyg_uint8* base = chan->base; + cyg_uint8 tmp; + cyg_uint16 sr; + + // Disable everything. + HAL_WRITE_UINT8(base+_REG_SCSCR, 0); + + // Reset FIFO. + HAL_WRITE_UINT8(base+_REG_SCFCR, + CYGARC_REG_SCFCR2_TFRST|CYGARC_REG_SCFCR2_RFRST); + + // 8-1-no parity. + HAL_WRITE_UINT8(base+_REG_SCSMR, 0); + + // Set speed to 38400 + HAL_READ_UINT8(base+_REG_SCSMR, tmp); + tmp &= ~CYGARC_REG_SCSMR2_CKSx_MASK; + tmp |= CYGARC_SCBRR2_CKSx(38400); + HAL_WRITE_UINT8(base+_REG_SCSMR, tmp); + HAL_WRITE_UINT8(base+_REG_SCBRR, CYGARC_SCBRR2_N(38400)); + + // Let things settle: Here we should should wait the equivalent of + // one bit interval, i.e. 1/38400 second, but until we have + // something like the Linux delay loop, it's hard to do reliably. So + // 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(base+_REG_SCSSR, sr); + HAL_WRITE_UINT16(base+_REG_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(base+_REG_SCFCR, + CYGARC_REG_SCFCR2_RTRG_1|CYGARC_REG_SCFCR2_TTRG_1); + + // Leave Tx/Rx interrupts disabled, but enable Tx/Rx + HAL_WRITE_UINT8(base+_REG_SCSCR, + CYGARC_REG_SCSCR2_TE|CYGARC_REG_SCSCR2_RE); +} + +static cyg_bool +cyg_hal_plf_scif_getc_nonblock(void* __ch_data, cyg_uint8* ch) +{ + cyg_uint8* base = ((channel_data_t*)__ch_data)->base; + cyg_uint16 fdr, sr; + + HAL_READ_UINT16(base+_REG_SCFDR, fdr); + if ((fdr & CYGARC_REG_SCFDR2_RCOUNT_MASK) == 0) + return false; + + HAL_READ_UINT8(base+_REG_SCFRDR, *ch); + + // Clear FIFO full flag (read before clearing) + HAL_READ_UINT16(base+_REG_SCSSR, sr); + HAL_WRITE_UINT16(base+_REG_SCSSR, + CYGARC_REG_SCSSR2_CLEARMASK & ~CYGARC_REG_SCSSR2_RDF); + + return true; +} + +cyg_uint8 +cyg_hal_plf_scif_getc(void* __ch_data) +{ + cyg_uint8 ch; + CYGARC_HAL_SAVE_GP(); + + while(!cyg_hal_plf_scif_getc_nonblock(__ch_data, &ch)); + + CYGARC_HAL_RESTORE_GP(); + return ch; +} + +void +cyg_hal_plf_scif_putc(void* __ch_data, cyg_uint8 c) +{ + cyg_uint8* base = ((channel_data_t*)__ch_data)->base; + cyg_uint16 fdr, sr; + CYGARC_HAL_SAVE_GP(); + + do { + HAL_READ_UINT16(base+_REG_SCFDR, fdr); + } while (((fdr & CYGARC_REG_SCFDR2_TCOUNT_MASK) >> CYGARC_REG_SCFDR2_TCOUNT_shift) == 16); + + HAL_WRITE_UINT8(base+_REG_SCFTDR, c); + + // Clear FIFO-empty/transmit end flags (read back SR first) + HAL_READ_UINT16(base+_REG_SCSSR, sr); + HAL_WRITE_UINT16(base+_REG_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(base+_REG_SCFDR, fdr); + } while ((fdr & CYGARC_REG_SCFDR2_TCOUNT_MASK) != 0); + + CYGARC_HAL_RESTORE_GP(); +} + +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ + || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) + +static channel_data_t channels[CYGNUM_HAL_SH_SH3_SCIF_PORTS]; + +static void +cyg_hal_plf_scif_write(void* __ch_data, const cyg_uint8* __buf, + cyg_uint32 __len) +{ + CYGARC_HAL_SAVE_GP(); + + while(__len-- > 0) + cyg_hal_plf_scif_putc(__ch_data, *__buf++); + + CYGARC_HAL_RESTORE_GP(); +} + +static void +cyg_hal_plf_scif_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len) +{ + CYGARC_HAL_SAVE_GP(); + + while(__len-- > 0) + *__buf++ = cyg_hal_plf_scif_getc(__ch_data); + + CYGARC_HAL_RESTORE_GP(); +} + +cyg_bool +cyg_hal_plf_scif_getc_timeout(void* __ch_data, cyg_uint8* ch) +{ + channel_data_t* chan = (channel_data_t*)__ch_data; + int delay_count; + cyg_bool res; + CYGARC_HAL_SAVE_GP(); + + delay_count = chan->msec_timeout * 10; // delay in .1 ms steps + + for(;;) { + res = cyg_hal_plf_scif_getc_nonblock(__ch_data, ch); + if (res || 0 == delay_count--) + break; + + CYGACC_CALL_IF_DELAY_US()(100); + } + + CYGARC_HAL_RESTORE_GP(); + return res; +} + +static int +cyg_hal_plf_scif_control(void *__ch_data, __comm_control_cmd_t __func, ...) +{ + static int irq_state = 0; + channel_data_t* chan = (channel_data_t*)__ch_data; + cyg_uint8 scr; + int ret = 0; + CYGARC_HAL_SAVE_GP(); + + switch (__func) { + case __COMMCTL_IRQ_ENABLE: + irq_state = 1; + HAL_INTERRUPT_UNMASK(chan->isr_vector); + HAL_READ_UINT8(chan->base+_REG_SCSCR, scr); + scr |= CYGARC_REG_SCSCR2_RIE; + HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr); + break; + case __COMMCTL_IRQ_DISABLE: + ret = irq_state; + irq_state = 0; + HAL_INTERRUPT_UNMASK(chan->isr_vector); + HAL_READ_UINT8(chan->base+_REG_SCSCR, scr); + scr &= ~CYGARC_REG_SCSCR2_RIE; + HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr); + break; + case __COMMCTL_DBG_ISR_VECTOR: + ret = chan->isr_vector; + break; + case __COMMCTL_SET_TIMEOUT: + { + va_list ap; + + va_start(ap, __func); + + ret = chan->msec_timeout; + chan->msec_timeout = va_arg(ap, cyg_uint32); + + va_end(ap); + } + default: + break; + } + CYGARC_HAL_RESTORE_GP(); + return ret; +} + +static int +cyg_hal_plf_scif_isr(void *__ch_data, int* __ctrlc, + CYG_ADDRWORD __vector, CYG_ADDRWORD __data) +{ + cyg_uint8 c; + cyg_uint16 fdr, sr; + cyg_uint8* base = ((channel_data_t*)__ch_data)->base; + int res = 0; + CYGARC_HAL_SAVE_GP(); + + *__ctrlc = 0; + HAL_READ_UINT16(base+_REG_SCFDR, fdr); + if ((fdr & CYGARC_REG_SCFDR2_RCOUNT_MASK) != 0) { + HAL_READ_UINT8(base+_REG_SCFRDR, c); + + // Clear buffer full flag (read back first). + HAL_READ_UINT16(base+_REG_SCSSR, sr); + HAL_WRITE_UINT16(base+_REG_SCSSR, + CYGARC_REG_SCSSR2_CLEARMASK & ~CYGARC_REG_SCSSR2_RDF); + + if( cyg_hal_is_break( &c , 1 ) ) + *__ctrlc = 1; + + res = CYG_ISR_HANDLED; + } + + CYGARC_HAL_RESTORE_GP(); + return res; +} + +void +cyg_hal_plf_scif_init(int scif_index, int comm_index, + int rcv_vect, cyg_uint8* base) +{ + channel_data_t* chan = &channels[scif_index]; + hal_virtual_comm_table_t* comm; + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + + // Initialize channel table + chan->base = base; + chan->isr_vector = rcv_vect; + chan->msec_timeout = 1000; + + // Disable interrupts. + HAL_INTERRUPT_MASK(chan->isr_vector); + + // Init channel + cyg_hal_plf_scif_init_channel(chan); + + // Setup procs in the vector table + + // Initialize channel procs + CYGACC_CALL_IF_SET_CONSOLE_COMM()(comm_index); + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CH_DATA_SET(*comm, chan); + CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_scif_write); + CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_scif_read); + CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_scif_putc); + CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_scif_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_scif_control); + CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_scif_isr); + CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_scif_getc_timeout); + + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); +} + +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES + +#endif // CYGNUM_HAL_SH_SH3_SCIF_PORTS + +//----------------------------------------------------------------------------- +// end of sh3_scif.c diff --git a/packages/hal/sh/arch/current/src/vectors.S b/packages/hal/sh/arch/current/src/vectors.S index 039352c75..9174087a2 100644 --- a/packages/hal/sh/arch/current/src/vectors.S +++ b/packages/hal/sh/arch/current/src/vectors.S @@ -32,7 +32,7 @@ #######DESCRIPTIONBEGIN#### ## ## Author(s): jskov -## Contributors: jskov +## Contributors: jskov, gthomas ## Date: 1999-05-01 ## Purpose: SH exception vectors ## Description: This file defines the code placed into the exception @@ -97,167 +97,18 @@ # be expected to provide the proper address space (at that time we # jump to the VMA base of the code). + .org 0x000 .globl __reset; __reset: - - # Initialize CPU - mov.l $nCYG_SR,r1 ! Put CPU in a well-known state - ldc r1,sr - mov #0,r0 - mov #CYGARC_REG_CCR,r1 ! Disable cache - mov.l r0,@r1 - mov #CYGARC_REG_MMUCR,r1 ! Disable MMU - mov.l r0,@r1 - mov #CYGARC_REG_BBRA,r1 ! Disable UBC Channel A - mov.w r0,@r1 - mov #CYGARC_REG_BBRB,r1 ! Disable UBC Channel B - mov.w r0,@r1 - mov #CYGARC_REG_BRCR,r1 ! Reset UBC common register - mov.w r0,@r1 - mov.l $CYGARC_REG_TSTR,r1 ! Disable timers - mov.b r0,@r1 - mov.l $CYGARC_REG_IPRA,r1 ! Disable interrupt request sources - mov.w r0,@r1 - mov.l $CYGARC_REG_IPRB,r1 - mov.w r0,@r1 -#ifdef CYGARC_SH_MOD_INTC_V2 - mov.l $CYGARC_REG_IPRC,r1 - mov.w r0,@r1 - mov.l $CYGARC_REG_IPRD,r1 - mov.w r0,@r1 - mov.l $CYGARC_REG_IPRE,r1 - mov.w r0,@r1 - mov.l $CYGARC_REG_ICR1,r1 ! Set interrupt controller to IRQ mode - mov.w r0,@r1 -#endif - - # 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 - mov #1,r1 - mov #2,r2 - mov #3,r3 - mov #4,r4 - mov #5,r5 - mov #6,r6 - mov #7,r7 - mov #8,r8 - mov #9,r9 - mov #10,r10 - mov #11,r11 - mov #12,r12 - mov #13,r13 - mov #14,r14 -#endif - - # Call platform specific hardware initialization - # This may include memory controller initialization. It is not - # safe to access RAM until after this point. - hal_hardware_init - - # Now copy necessary bits to RAM and jump to the VMA base - -#ifdef CYG_HAL_STARTUP_ROM - - # Copy data from ROM to ram - mov.l $__rom_data_start,r3 ! r3 = rom start - mov.l $__ram_data_start,r4 ! r4 = ram start - mov.l $__ram_data_end,r5 ! r5 = ram end - - cmp/eq r4,r5 ! skip if no data - bt 2f -1: mov.l @r3+,r0 ! get word from ROM - mov.l r0,@r4 ! store in RAM - add #4,r4 - 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 + mov.l $__reset_platform,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 +# Note: this is the unmapped, shadow address of the start of code +# Sadly, it is too far to just branch to. +$__reset_platform: + .long __reset_platform-__reset+0xA0000000 -#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 -#ifdef CYGARC_SH_MOD_INTC_V2 -$CYGARC_REG_IPRC: - .long CYGARC_REG_IPRC -$CYGARC_REG_IPRD: - .long CYGARC_REG_IPRD -$CYGARC_REG_IPRE: - .long CYGARC_REG_IPRE -$CYGARC_REG_ICR1: - .long CYGARC_REG_ICR1 -#endif - -$__reset: - .long __reset - #--------------------------------------------------------------------------- # Exception entry @@ -280,91 +131,7 @@ __exception: .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 - mov #0,r0 ! r0 = 0 -1: cmp/eq r3,r4 ! skip if no bss - bt 2f - mov.l r0,@r3 ! store zero - add #4,r3 - bra 1b ! loop - nop -2: - - # It is now safe to call C functions which may rely on initialized - # data. -# # Initialize MMU. -# .extern hal_MMU_init -# jsr hal_MMU_init -# nop - - # Enable caches - mov.l $_cyg_hal_enable_caches,r1 - jsr @r1 - nop - - # call c++ constructors - mov.l $_cyg_hal_invoke_constructors,r1 - jsr @r1 - nop - -#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - mov.l $_initialize_stub,r1 - jsr @r1 - nop -#endif - - mov.l $_cyg_start,r1 - jsr @r1 - nop -9: - bra 9b ! if we return, loop - nop - - .align 2 -$__startup_stack: - .long __startup_stack - - .extern __bss_start - .extern __bss_end - .extern _cyg_hal_invoke_constructors - .extern _cyg_start - -$__bss_start: - .long __bss_start -$__bss_end: - .long __bss_end -$_cyg_hal_invoke_constructors: - .long _cyg_hal_invoke_constructors -$_cyg_hal_enable_caches: - .long _cyg_hal_enable_caches -$_cyg_start: - .long _cyg_start - -#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - .extern _initialize_stub -$_initialize_stub: - .long _initialize_stub -#endif - - #--------------------------------------------------------------------------- # This code handles the common part of all exception handlers. # It saves the machine state onto the stack and then calls @@ -530,7 +297,6 @@ __interrupt: $_hal_vsr_table_int: .long _hal_vsr_table+CYGNUM_HAL_VECTOR_INTERRUPT*4 - #--------------------------------------------------------------------------- # Common interrupt handling code. @@ -669,24 +435,14 @@ $_cyg_instrument: #endif // CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - mov r4,r10 ! save across call. - mov #CYGARC_SHREG_PC,r4 - add r8,r4 - mov.l @r4,r4 - mov.l $_cyg_hal_gdb_isr,r1 - jsr @r1 ! returns 1 if the proper isr must be - nop ! called (i.e., if it was not a GDB - mov r10,r4 ! interrupt) - cmp/eq #0,r0 - bt skip_isr_proper - bra 2f - nop - .align 2 - .extern _cyg_hal_gdb_isr -$_cyg_hal_gdb_isr: - .long _cyg_hal_gdb_isr -2: +#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ + || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) + # If we are supporting Ctrl-C interrupts from GDB, we must squirrel + # away a pointer to the save interrupt state here so that we can + # plant a breakpoint at some later time. + + mov.l $_hal_saved_interrupt_state,r1 + mov.l r8,@r1 #endif #ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING @@ -731,12 +487,6 @@ $_cyg_hal_gdb_isr: jsr @r1 ! r4=vector, r5=data nop -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - # If interrupt was caused by GDB, the ISR call above - # is skipped by jumping here. -skip_isr_proper: -#endif - #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK # If we are returning from the last nested interrupt, move back @@ -867,6 +617,13 @@ $int_state_marker: .long 0x77777771 #endif +#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ + || defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) + .extern _hal_saved_interrupt_state +$_hal_saved_interrupt_state: + .long _hal_saved_interrupt_state +#endif + #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK $__interrupt_stack: .long __interrupt_stack @@ -909,6 +666,266 @@ $_interrupt_end: .long _interrupt_end #endif +#--------------------------------------------------------------------------- +# Platform initialization (reset) +__reset_platform: + # Initialize CPU + mov.l $nCYG_SR,r1 ! Put CPU in a well-known state + ldc r1,sr + mov #0,r0 + mov #CYGARC_REG_CCR,r1 ! Disable cache + mov.l r0,@r1 + mov #CYGARC_REG_MMUCR,r1 ! Disable MMU + mov.l r0,@r1 + mov #CYGARC_REG_BBRA,r1 ! Disable UBC Channel A + mov.w r0,@r1 + mov #CYGARC_REG_BBRB,r1 ! Disable UBC Channel B + mov.w r0,@r1 + mov #CYGARC_REG_BRCR,r1 ! Reset UBC common register + mov.w r0,@r1 + mov.l $CYGARC_REG_TSTR,r1 ! Disable timers + mov.b r0,@r1 + mov.l $CYGARC_REG_IPRA,r1 ! Disable interrupt request sources + mov.w r0,@r1 + mov.l $CYGARC_REG_IPRB,r1 + mov.w r0,@r1 +#ifdef CYGARC_SH_MOD_INTC_V2 + mov.l $CYGARC_REG_IPRC,r1 + mov.w r0,@r1 + mov.l $CYGARC_REG_IPRD,r1 + mov.w r0,@r1 + mov.l $CYGARC_REG_IPRE,r1 + mov.w r0,@r1 + mov.l $CYGARC_REG_ICR1,r1 ! Set interrupt controller to IRQ mode + mov.w r0,@r1 +#endif + + # 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 + mov #1,r1 + mov #2,r2 + mov #3,r3 + mov #4,r4 + mov #5,r5 + mov #6,r6 + mov #7,r7 + mov #8,r8 + mov #9,r9 + mov #10,r10 + mov #11,r11 + mov #12,r12 + mov #13,r13 + mov #14,r14 +#endif + + # Call platform specific hardware initialization + # This may include memory controller initialization. It is not + # safe to access RAM until after this point. + hal_hardware_init + + # Now copy necessary bits to RAM and jump to the VMA base + +#ifdef CYG_HAL_STARTUP_ROM + + # Copy data from ROM to ram + mov.l $__rom_data_start,r3 ! r3 = rom start + mov.l $__ram_data_start,r4 ! r4 = ram start + mov.l $__ram_data_end,r5 ! r5 = ram end + + cmp/eq r4,r5 ! skip if no data + bt 2f +1: mov.l @r3+,r0 ! get word from ROM + mov.l r0,@r4 ! store in RAM + add #4,r4 + 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 +#ifdef CYGARC_SH_MOD_INTC_V2 +$CYGARC_REG_IPRC: + .long CYGARC_REG_IPRC +$CYGARC_REG_IPRD: + .long CYGARC_REG_IPRD +$CYGARC_REG_IPRE: + .long CYGARC_REG_IPRE +$CYGARC_REG_ICR1: + .long CYGARC_REG_ICR1 +#endif + +$__reset: + .long __reset + +#----------------------------------------------------------------------------- +# Complete target initialization and setup. +# 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 + mov #0,r0 ! r0 = 0 +1: cmp/eq r3,r4 ! skip if no bss + bt 2f + mov.l r0,@r3 ! store zero + add #4,r3 + bra 1b ! loop + nop +2: + + # It is now safe to call C functions which may rely on initialized + # data. + +# # Initialize MMU. +# .extern hal_MMU_init +# jsr hal_MMU_init +# nop + + # Enable caches + mov.l $_cyg_hal_enable_caches,r1 + jsr @r1 + nop + + # Variant HALs may need to do something special before we continue + mov.l $_hal_variant_init,r1 + jsr @r1 + nop + + # Platform initialization + mov.l $_hal_platform_init,r1 + jsr @r1 + nop + + # call c++ constructors + mov.l $_cyg_hal_invoke_constructors,r1 + jsr @r1 + nop + +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + mov.l $_initialize_stub,r1 + jsr @r1 + nop +#endif + + mov.l $_cyg_start,r1 + jsr @r1 + nop +9: + bra 9b ! if we return, loop + nop + + .align 2 +$__startup_stack: + .long __startup_stack + + .extern __bss_start + .extern __bss_end + .extern _cyg_hal_invoke_constructors + .extern _hal_variant_init + .extern _hal_platform_init + .extern _cyg_start + +$__bss_start: + .long __bss_start +$__bss_end: + .long __bss_end +$_cyg_hal_invoke_constructors: + .long _cyg_hal_invoke_constructors +$_cyg_hal_enable_caches: + .long _cyg_hal_enable_caches +$_hal_variant_init: + .long _hal_variant_init +$_hal_platform_init: + .long _hal_platform_init +$_cyg_start: + .long _cyg_start + +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + .extern _initialize_stub +$_initialize_stub: + .long _initialize_stub +#endif + + #--------------------------------------------------------------------------- # Cache operations # These need to be written in assembly to ensure they do not rely on data diff --git a/packages/hal/sh/cq7708/current/ChangeLog b/packages/hal/sh/cq7708/current/ChangeLog index 83f516ab0..5a359e0b4 100644 --- a/packages/hal/sh/cq7708/current/ChangeLog +++ b/packages/hal/sh/cq7708/current/ChangeLog @@ -1,3 +1,23 @@ +2000-06-29 Jesper Skov <jskov@redhat.com> + + * src/hal_diag.c: serial driver API changes. + +2000-06-28 Jesper Skov <jskov@redhat.com> + + * src/plf_stub.c: [deleted] + * src/plf_misc.c: + * src/hal_diag.c: + * include/pkgconf/mlt_sh_sh7708_cq7708_ram.h: + * include/pkgconf/mlt_sh_sh7708_cq7708_ram.ldi: + * include/pkgconf/mlt_sh_sh7708_cq7708_ram.mlt: + * include/pkgconf/mlt_sh_sh7708_cq7708_rom.h: + * include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi: + * include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt: + * include/plf_stub.h: + * include/hal_diag.h: + * cdl/hal_sh_sh7708_cq7708.cdl: + Changed to use virtual vector code. + 2000-06-06 Jesper Skov <jskov@redhat.com> * cdl/hal_sh_sh7708_cq7708.cdl: Added CYGHWR_HAL_SH_BOARD_SPEED diff --git a/packages/hal/sh/cq7708/current/cdl/hal_sh_sh7708_cq7708.cdl b/packages/hal/sh/cq7708/current/cdl/hal_sh_sh7708_cq7708.cdl index 6f764ce7b..c2b94bede 100644 --- a/packages/hal/sh/cq7708/current/cdl/hal_sh_sh7708_cq7708.cdl +++ b/packages/hal/sh/cq7708/current/cdl/hal_sh_sh7708_cq7708.cdl @@ -49,16 +49,19 @@ cdl_package CYGPKG_HAL_SH_SH7708_CQ7708 { The cq HAL package provides the support needed to run eCos on a CqREEK SH7708 board." - compile hal_diag.c plf_stub.c plf_misc.c + compile hal_diag.c plf_misc.c implements CYGINT_HAL_DEBUG_GDB_STUBS implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK + implements CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT define_proc { puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_sh.h>" puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_sh_sh7708_cq7708.h>" + puts $::cdl_header "#define CYGNUM_HAL_SH_SH3_SCI_PORTS 1" puts $::cdl_header "#define CYGHWR_HAL_VSR_TABLE 0x0c000000" + puts $::cdl_header "#define CYGHWR_HAL_VECTOR_TABLE 0x0c000100" } cdl_component CYG_HAL_STARTUP { @@ -79,6 +82,33 @@ cdl_package CYGPKG_HAL_SH_SH7708_CQ7708 { equivalent technology." } + cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS { + display "Number of communication channels on the board" + flavor data + calculated 1 + } + + cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL { + display "Debug serial port" + flavor data + legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1 + default_value 0 + description " + The CQ/7708 board has only one serial port. This option + chooses which port will be used to connect to a host + running GDB." + } + + cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL { + display "Diagnostic serial port" + flavor data + legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1 + default_value 0 + description " + The CQ/7708 board has only one serial port. This option + chooses which port will be used for diagnostic output." + } + cdl_option CYGHWR_HAL_SH_BOARD_SPEED { display "Development board clock speed (MHz)" flavor data @@ -162,8 +192,8 @@ cdl_package CYGPKG_HAL_SH_SH7708_CQ7708 { requires CYGSEM_HAL_ROM_MONITOR requires CYGBLD_BUILD_COMMON_GDB_STUBS requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - requires ! CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - requires ! CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT + requires CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT + requires CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM no_define diff --git a/packages/hal/sh/cq7708/current/include/hal_diag.h b/packages/hal/sh/cq7708/current/include/hal_diag.h index dcf08a9ae..aad6245ef 100644 --- a/packages/hal/sh/cq7708/current/include/hal_diag.h +++ b/packages/hal/sh/cq7708/current/include/hal_diag.h @@ -49,6 +49,16 @@ #include <cyg/infra/cyg_type.h> +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) + +#include <cyg/hal/hal_if.h> + +#define HAL_DIAG_INIT() hal_if_diag_init() +#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_) +#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_) + +#else // everything by steam + //----------------------------------------------------------------------------- // functions implemented in hal_diag.c @@ -66,6 +76,8 @@ externC void hal_diag_read_char(char *c); #define HAL_DIAG_READ_CHAR(_c_) hal_diag_read_char(&_c_) +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG + //----------------------------------------------------------------------------- // Simple LED control. externC void hal_diag_led_on( void ); diff --git a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.h b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.h index 384921661..6be1936b8 100644 --- a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.h +++ b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.h @@ -5,8 +5,8 @@ #include <cyg/infra/cyg_type.h> #include <stddef.h> -#define CYGMEM_REGION_ram (0xc000100) -#define CYGMEM_REGION_ram_SIZE (0x3fff00) +#define CYGMEM_REGION_ram (0xc000200) +#define CYGMEM_REGION_ram_SIZE (0x3ffe00) #define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W) #define CYGMEM_REGION_rom (0xa0000000) #define CYGMEM_REGION_rom_SIZE (0x8000) diff --git a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi index 0f0653f4d..38836b0eb 100644 --- a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi +++ b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.ldi @@ -4,7 +4,7 @@ MEMORY { - ram : ORIGIN = 0xc000100, LENGTH = 0x3fff00 + ram : ORIGIN = 0xc000200, LENGTH = 0x3ffe00 rom : ORIGIN = 0xa0000000, LENGTH = 0x8000 } @@ -18,7 +18,7 @@ SECTIONS 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, 0xc000100, FOLLOWING (.gcc_except_table)) + SECTION_data (ram, 0xc000200, FOLLOWING (.gcc_except_table)) SECTION_bss (ram, ALIGN (0x10), LMA_EQ_VMA) SECTIONS_END } diff --git a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt index f469a6d21..7454fc353 100644 --- a/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt +++ b/packages/hal/sh/cq7708/current/include/pkgconf/mlt_sh_sh7708_cq7708_rom.mlt @@ -1,7 +1,7 @@ version 0 -region ram c000100 3fff00 0 ! +region ram c000200 3ffe00 0 ! region rom a0000000 8000 1 ! -section data 0 1 1 1 1 1 0 0 c000100 bss ! +section data 0 1 1 1 1 1 0 0 c000200 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 ! diff --git a/packages/hal/sh/cq7708/current/include/plf_stub.h b/packages/hal/sh/cq7708/current/include/plf_stub.h index 9fbddf8db..8dfe578f1 100644 --- a/packages/hal/sh/cq7708/current/include/plf_stub.h +++ b/packages/hal/sh/cq7708/current/include/plf_stub.h @@ -47,10 +47,6 @@ #include <pkgconf/system.h> #include <pkgconf/hal.h> -#ifdef CYGPKG_IO_SERIAL -#include <pkgconf/io_serial.h> -#endif - #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS #include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM, externC @@ -60,19 +56,16 @@ #include <cyg/hal/hal_diag.h> // hal_diag_led_on //---------------------------------------------------------------------------- -// Define serial stuff. -externC void hal_sci_stub_init_serial( void ); -externC int hal_sci_stub_get_char( void ); -externC void hal_sci_stub_put_char( int c ); -externC int hal_sci_stub_interruptible( int state ); -externC void hal_sci_stub_init_break_irq( void ); +// Define some platform specific communication details. This is mostly +// handled by hal_if now, but we need to make sure the comms tables are +// properly initialized. + +externC void cyg_hal_plf_comms_init(void); + +#define HAL_STUB_PLATFORM_INIT_SERIAL() cyg_hal_plf_comms_init() -#define HAL_STUB_PLATFORM_INIT_SERIAL() hal_sci_stub_init_serial() -#define HAL_STUB_PLATFORM_GET_CHAR() hal_sci_stub_get_char() -#define HAL_STUB_PLATFORM_PUT_CHAR(c) hal_sci_stub_put_char((c)) #define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud)) -#define HAL_STUB_PLATFORM_INTERRUPTIBLE (&hal_sci_stub_interruptible) -#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ() hal_sci_stub_init_break_irq() +#define HAL_STUB_PLATFORM_INTERRUPTIBLE 0 //---------------------------------------------------------------------------- // Stub initializer. @@ -82,14 +75,15 @@ externC void hal_sci_stub_init_break_irq( void ); # define HAL_STUB_PLATFORM_INIT() CYG_EMPTY_STATEMENT #endif +#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + //---------------------------------------------------------------------------- // Reset. // Block interrupts and cause an exception. This forces a reset. #define HAL_STUB_PLATFORM_RESET() \ asm volatile ("ldc %0,sr;trapa #0x00;" : : "r" (CYGARC_REG_SR_BL)) - -#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +#define HAL_STUB_PLATFORM_RESET_ENTRY 0xa0000000 //----------------------------------------------------------------------------- #endif // CYGONCE_HAL_PLF_STUB_H diff --git a/packages/hal/sh/cq7708/current/src/hal_diag.c b/packages/hal/sh/cq7708/current/src/hal_diag.c index 606081f3a..f5c2d9630 100644 --- a/packages/hal/sh/cq7708/current/src/hal_diag.c +++ b/packages/hal/sh/cq7708/current/src/hal_diag.c @@ -45,18 +45,63 @@ #include <cyg/hal/hal_diag.h> // our header. -#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) -#include <cyg/hal/hal_stub.h> // hal_output_gdb_string -#endif - #include <cyg/infra/cyg_type.h> // base types, externC #include <cyg/hal/hal_io.h> // IO macros #include <cyg/hal/hal_intr.h> // Interrupt macros +#include <cyg/hal/sh3_sci.h> // driver API +#include <cyg/hal/hal_misc.h> // Helper functions -#include <cyg/hal/sh_sci.inl> +#define SCI_BASE ((cyg_uint8*)0xfffffe80) //----------------------------------------------------------------------------- +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ + || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) + +void +cyg_hal_plf_comms_init(void) +{ + static int initialized = 0; + + if (initialized) + return; + + initialized = 1; + + cyg_hal_plf_sci_init(0, 0, CYGNUM_HAL_INTERRUPT_SCI_RXI, SCI_BASE); +} + +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES + +//============================================================================= +// Led control +//============================================================================= +#define LED 0xa8000000 + +void +hal_diag_led_on( void ) +{ + HAL_WRITE_UINT8(LED, 0x18); +} + +void +hal_diag_led_off( void ) +{ + HAL_WRITE_UINT8(LED, 0); +} + +//============================================================================= +// Compatibility with older stubs +//============================================================================= + +#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG + +static channel_data_t channel = { (cyg_uint8*)SCI_BASE, 0, 0}; + +#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) +#include <cyg/hal/hal_stub.h> // hal_output_gdb_string +#endif + #if defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) #define CYG_HAL_DIAG_GDB @@ -71,24 +116,21 @@ void hal_diag_init(void) { - hal_sci_init_serial(); + cyg_hal_plf_sci_init_channel(&channel); } void hal_diag_write_char_serial( char c ) { - hal_sci_put_char(c); + cyg_hal_plf_sci_putc(&channel, c); } void hal_diag_read_char(char *c) { - *c = (char) hal_sci_get_char(); + *c = (char) cyg_hal_plf_sci_getc(&channel); } -externC cyg_bool cyg_hal_is_break(char *buf, int size); -externC void cyg_hal_user_break(CYG_ADDRWORD *regs); - // Packet function void hal_diag_write_char(char c) @@ -124,26 +166,26 @@ hal_diag_write_char(char c) cyg_uint8 csum = 0; int i; - hal_diag_write_char_serial('$'); - hal_diag_write_char_serial('O'); + cyg_hal_plf_sci_putc(&channel, '$'); + cyg_hal_plf_sci_putc(&channel, 'O'); csum += 'O'; for( i = 0; i < pos; i++ ) { char ch = line[i]; char h = hex[(ch>>4)&0xF]; char l = hex[ch&0xF]; - hal_diag_write_char_serial(h); - hal_diag_write_char_serial(l); + cyg_hal_plf_sci_putc(&channel, h); + cyg_hal_plf_sci_putc(&channel, l); csum += h; csum += l; } - hal_diag_write_char_serial('#'); - hal_diag_write_char_serial(hex[(csum>>4)&0xF]); - hal_diag_write_char_serial(hex[csum&0xF]); + cyg_hal_plf_sci_putc(&channel, '#'); + cyg_hal_plf_sci_putc(&channel, hex[(csum>>4)&0xF]); + cyg_hal_plf_sci_putc(&channel, hex[csum&0xF]); // Wait for the ACK character '+' from GDB here and handle // receiving a ^C instead. - hal_diag_read_char(&c1); + c1 = (char) cyg_hal_plf_sci_getc(&channel); if( c1 == '+' ) break; // a good acknowledge @@ -165,25 +207,11 @@ hal_diag_write_char(char c) #endif } #else // CYG_HAL_DIAG_GDB - hal_diag_write_char_serial(c); + cyg_hal_plf_sci_putc(&channel, c); #endif } -//----------------------------------------------------------------------------- -// Led control -#define LED 0xa8000000 - -void -hal_diag_led_on( void ) -{ - HAL_WRITE_UINT8(LED, 0x18); -} - -void -hal_diag_led_off( void ) -{ - HAL_WRITE_UINT8(LED, 0); -} +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG //----------------------------------------------------------------------------- // End of hal_diag.c diff --git a/packages/hal/sh/cq7708/current/src/plf_misc.c b/packages/hal/sh/cq7708/current/src/plf_misc.c index 2ffea80af..861cb7fb6 100644 --- a/packages/hal/sh/cq7708/current/src/plf_misc.c +++ b/packages/hal/sh/cq7708/current/src/plf_misc.c @@ -44,59 +44,14 @@ #include <pkgconf/hal.h> -#include <cyg/infra/cyg_type.h> // Base types - -#include <cyg/hal/hal_arch.h> // architectural definitions - -#include <cyg/hal/hal_intr.h> // Interrupt handling - -#include <cyg/hal/hal_cache.h> // Cache handling - -#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS -#include <cyg/hal/hal_stub.h> // stub functionality -#endif +#include <cyg/hal/hal_if.h> // interfacing API //-------------------------------------------------------------------------- -// Functions to support the detection and execution of a user provoked -// program break. These are usually called from interrupt routines. - -cyg_bool -cyg_hal_is_break(char *buf, int size) -{ - while( size ) - if( buf[--size] == 0x03 ) return true; - - return false; -} - void -cyg_hal_user_break( CYG_ADDRWORD *regs ) +hal_platform_init(void) { -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - HAL_SavedRegisters *__sreg = (HAL_SavedRegisters *)regs; - target_register_t __pc; - - if (__sreg) - __pc = (target_register_t) __sreg->pc; - else - __pc = (target_register_t) &&safe_breakpoint; - - // Note: This would be better for the else case but doesn't work - // at the moment. CR: 101357 - // __pc = (target_register_t) __builtin_return_address(0); - - cyg_hal_gdb_interrupt (__pc); - - safe_breakpoint: -#elif defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) - - // Note: Need to communicate to the ROM stub instead - HAL_BREAKPOINT(breakinst); - -#else - - HAL_BREAKPOINT(breakinst); - -#endif - + hal_if_init(); } + +//-------------------------------------------------------------------------- +// eof plf_misc.c diff --git a/packages/hal/sh/edk/current/ChangeLog b/packages/hal/sh/edk/current/ChangeLog index 46506da3a..2761b3ed8 100644 --- a/packages/hal/sh/edk/current/ChangeLog +++ b/packages/hal/sh/edk/current/ChangeLog @@ -1,3 +1,30 @@ +2000-06-29 Jesper Skov <jskov@redhat.com> + + * src/hal_diag.c: serial driver API changes. + +2000-06-28 Jesper Skov <jskov@redhat.com> + + * src/hal_diag.c: Include hal_if file. + +2000-06-28 Jesper Skov <jskov@redhat.com> + + * src/plf_misc.c: + * src/hal_diag.c: + * src/plf_stub.c: [deleted] + * include/pkgconf/mlt_sh_edk7708_ram.h: + * include/pkgconf/mlt_sh_edk7708_ram.ldi: + * include/pkgconf/mlt_sh_edk7708_ram.mlt: + * include/pkgconf/mlt_sh_edk7708_rom.h: + * include/pkgconf/mlt_sh_edk7708_rom.ldi: + * include/pkgconf/mlt_sh_edk7708_rom.mlt: + * include/pkgconf/mlt_sh_edk7708_romram.h: + * include/pkgconf/mlt_sh_edk7708_romram.ldi: + * include/pkgconf/mlt_sh_edk7708_romram.mlt: + * include/plf_stub.h: + * include/hal_diag.h: + * cdl/hal_sh_edk7708.cdl: + Changed to use virtual vector table. + 1999-06-19 John Dallaway <jld@redhat.com> * cdl/hal_sh_edk7708.cdl: Tidy display strings. diff --git a/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl b/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl index ec6c792ea..86161c19e 100644 --- a/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl +++ b/packages/hal/sh/edk/current/cdl/hal_sh_edk7708.cdl @@ -49,16 +49,19 @@ 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 plf_stub.c plf_misc.c + compile hal_diag.c plf_misc.c implements CYGINT_HAL_DEBUG_GDB_STUBS implements CYGINT_HAL_DEBUG_GDB_STUBS_BREAK + implements CYGINT_HAL_VIRTUAL_VECTOR_SUPPORT define_proc { puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_sh.h>" puts $::cdl_system_header "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_sh_edk7708.h>" + puts $::cdl_header "#define CYGNUM_HAL_SH_SH3_SCI_PORTS 1" puts $::cdl_header "#define CYGHWR_HAL_VSR_TABLE 0x08000000" + puts $::cdl_header "#define CYGHWR_HAL_VECTOR_TABLE 0x08000100" } cdl_component CYG_HAL_STARTUP { @@ -82,6 +85,33 @@ cdl_package CYGPKG_HAL_SH_EDK7708 { increased RAM footprint." } + cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS { + display "Number of communication channels on the board" + flavor data + calculated 1 + } + + cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL { + display "Debug serial port" + flavor data + legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1 + default_value 0 + description " + The EDK/7708 board has only one serial port. This option + chooses which port will be used to connect to a host + running GDB." + } + + cdl_option CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL { + display "Diagnostic serial port" + flavor data + legal_values 0 to CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS-1 + default_value 0 + description " + The EDK/7708 board has only one serial port. This option + chooses which port will be used for diagnostic output." + } + cdl_option CYGHWR_HAL_SH_BOARD_SPEED { display "Development board clock speed (MHz)" flavor data @@ -165,8 +195,8 @@ cdl_package CYGPKG_HAL_SH_EDK7708 { requires CYGSEM_HAL_ROM_MONITOR requires CYGBLD_BUILD_COMMON_GDB_STUBS requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS - requires ! CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - requires ! CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT + requires CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT + requires CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT requires ! CYGDBG_HAL_COMMON_INTERRUPTS_SAVE_MINIMUM_CONTEXT requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM no_define diff --git a/packages/hal/sh/edk/current/include/hal_diag.h b/packages/hal/sh/edk/current/include/hal_diag.h index dcf08a9ae..aad6245ef 100644 --- a/packages/hal/sh/edk/current/include/hal_diag.h +++ b/packages/hal/sh/edk/current/include/hal_diag.h @@ -49,6 +49,16 @@ #include <cyg/infra/cyg_type.h> +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) + +#include <cyg/hal/hal_if.h> + +#define HAL_DIAG_INIT() hal_if_diag_init() +#define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_) +#define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_) + +#else // everything by steam + //----------------------------------------------------------------------------- // functions implemented in hal_diag.c @@ -66,6 +76,8 @@ externC void hal_diag_read_char(char *c); #define HAL_DIAG_READ_CHAR(_c_) hal_diag_read_char(&_c_) +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG + //----------------------------------------------------------------------------- // Simple LED control. externC void hal_diag_led_on( void ); diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.h b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.h index 73f0cf466..ad1d89991 100644 --- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.h +++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.h @@ -5,8 +5,8 @@ #include <cyg/infra/cyg_type.h> #include <stddef.h> -#define CYGMEM_REGION_ram (0x8000100) -#define CYGMEM_REGION_ram_SIZE (0xfff00) +#define CYGMEM_REGION_ram (0x8000200) +#define CYGMEM_REGION_ram_SIZE (0xffe00) #define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W) #define CYGMEM_REGION_rom (0xa0000000) #define CYGMEM_REGION_rom_SIZE (0x20000) diff --git a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.ldi b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.ldi index 668871151..a3bd43e5e 100644 --- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.ldi +++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.ldi @@ -31,7 +31,7 @@ MEMORY { rom : ORIGIN = 0xa0000000, LENGTH = 0x20000 - ram : ORIGIN = 0x08000100, LENGTH = 0xfff00 + ram : ORIGIN = 0x08000200, LENGTH = 0xffe00 } SECTIONS @@ -44,7 +44,7 @@ SECTIONS 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, 0x08000100, FOLLOWING (.gcc_except_table)) + SECTION_data (ram, 0x08000200, 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_rom.mlt b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.mlt index 92f21c2da..3530282c0 100644 --- a/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.mlt +++ b/packages/hal/sh/edk/current/include/pkgconf/mlt_sh_edk7708_rom.mlt @@ -1,7 +1,7 @@ version 0 -region ram 8000100 fff00 0 ! +region ram 8000200 ffe00 0 ! region rom a0000000 20000 1 ! -section data 0 1 1 1 1 1 0 0 8000100 bss ! +section data 0 1 1 1 1 1 0 0 8000200 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 ! 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 index 9179b2f9e..4cb7e1173 100644 --- 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 @@ -5,8 +5,8 @@ #include <cyg/infra/cyg_type.h> #include <stddef.h> -#define CYGMEM_REGION_ram (0x8000100) -#define CYGMEM_REGION_ram_SIZE (0xfff00) +#define CYGMEM_REGION_ram (0x8000200) +#define CYGMEM_REGION_ram_SIZE (0xffe00) #define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W) #define CYGMEM_REGION_rom (0xa0000000) #define CYGMEM_REGION_rom_SIZE (0x20000) 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 index 325bb2876..c76e2482c 100644 --- 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 @@ -4,14 +4,14 @@ MEMORY { - ram : ORIGIN = 0x8000100, LENGTH = 0xfff00 + ram : ORIGIN = 0x8000200, LENGTH = 0xffe00 rom : ORIGIN = 0xa0000000, LENGTH = 0x20000 } SECTIONS { SECTIONS_BEGIN - SECTION_vectors (ram, 0x8000100, AT (0xa0000000)) + SECTION_vectors (ram, 0x8000200, AT (0xa0000000)) SECTION_text (ram, ALIGN (0x10), FOLLOWING (.vectors)) SECTION_fini (ram, ALIGN (0x10), FOLLOWING (.text)) SECTION_rodata1 (ram, ALIGN (0x10), FOLLOWING (.fini)) 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 index e8c6b924d..7bd5562a1 100644 --- 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 @@ -1,7 +1,7 @@ version 0 -region ram 8000100 fff00 0 ! +region ram 8000200 ffe00 0 ! region rom a0000000 20000 1 ! -section vectors 0 10 1 1 1 1 1 1 8000100 a0000000 text text ! +section vectors 0 10 1 1 1 1 1 1 8000200 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 ! diff --git a/packages/hal/sh/edk/current/include/plf_stub.h b/packages/hal/sh/edk/current/include/plf_stub.h index 548027448..219c63413 100644 --- a/packages/hal/sh/edk/current/include/plf_stub.h +++ b/packages/hal/sh/edk/current/include/plf_stub.h @@ -47,10 +47,6 @@ #include <pkgconf/system.h> #include <pkgconf/hal.h> -#ifdef CYGPKG_IO_SERIAL -#include <pkgconf/io_serial.h> -#endif - #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS #include <cyg/infra/cyg_type.h> // CYG_UNUSED_PARAM, externC @@ -60,19 +56,16 @@ #include <cyg/hal/hal_diag.h> // hal_diag_led_on //---------------------------------------------------------------------------- -// Define serial stuff. -externC void hal_sci_stub_init_serial( void ); -externC int hal_sci_stub_get_char( void ); -externC void hal_sci_stub_put_char( int c ); -externC int hal_sci_stub_interruptible( int state ); -externC void hal_sci_stub_init_break_irq( void ); +// Define some platform specific communication details. This is mostly +// handled by hal_if now, but we need to make sure the comms tables are +// properly initialized. + +externC void cyg_hal_plf_comms_init(void); + +#define HAL_STUB_PLATFORM_INIT_SERIAL() cyg_hal_plf_comms_init() -#define HAL_STUB_PLATFORM_INIT_SERIAL() hal_sci_stub_init_serial() -#define HAL_STUB_PLATFORM_GET_CHAR() hal_sci_stub_get_char() -#define HAL_STUB_PLATFORM_PUT_CHAR(c) hal_sci_stub_put_char((c)) #define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud)) -#define HAL_STUB_PLATFORM_INTERRUPTIBLE (&hal_sci_stub_interruptible) -#define HAL_STUB_PLATFORM_INIT_BREAK_IRQ() hal_sci_stub_init_break_irq() +#define HAL_STUB_PLATFORM_INTERRUPTIBLE 0 //---------------------------------------------------------------------------- // Stub initializer. @@ -82,15 +75,16 @@ externC void hal_sci_stub_init_break_irq( void ); # define HAL_STUB_PLATFORM_INIT() CYG_EMPTY_STATEMENT #endif +#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + //---------------------------------------------------------------------------- // Reset. // Block interrupts and cause an exception. This forces a reset. #define HAL_STUB_PLATFORM_RESET() \ asm volatile ("ldc %0,sr;trapa #0x00;" : : "r" (CYGARC_REG_SR_BL)) - - -#endif // ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +#define HAL_STUB_PLATFORM_RESET_ENTRY 0xa0000000 + //----------------------------------------------------------------------------- #endif // CYGONCE_HAL_PLF_STUB_H // End of plf_stub.h diff --git a/packages/hal/sh/edk/current/src/hal_diag.c b/packages/hal/sh/edk/current/src/hal_diag.c index 77009befc..36bc6c586 100644 --- a/packages/hal/sh/edk/current/src/hal_diag.c +++ b/packages/hal/sh/edk/current/src/hal_diag.c @@ -45,18 +45,66 @@ #include <cyg/hal/hal_diag.h> // our header. -#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) -#include <cyg/hal/hal_stub.h> // hal_output_gdb_string -#endif - #include <cyg/infra/cyg_type.h> // base types, externC #include <cyg/hal/hal_io.h> // IO macros +#include <cyg/hal/hal_if.h> // Calling interface #include <cyg/hal/hal_intr.h> // Interrupt macros +#include <cyg/hal/sh3_sci.h> // driver API +#include <cyg/hal/hal_misc.h> // Helper functions -#include <cyg/hal/sh_sci.inl> +#define SCI_BASE ((cyg_uint8*)0xfffffe80) //----------------------------------------------------------------------------- +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ + || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) + +void +cyg_hal_plf_comms_init(void) +{ + static int initialized = 0; + + if (initialized) + return; + + initialized = 1; + + cyg_hal_plf_sci_init(0, 0, CYGNUM_HAL_INTERRUPT_SCI_RXI, SCI_BASE); +} + +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES + +//============================================================================= +// Led control +//============================================================================= +#define LED_ON 0x04000000 +#define LED_OFF 0x18000000 + +void +hal_diag_led_on( void ) +{ + HAL_WRITE_UINT8(LED_ON, 0); +} + +void +hal_diag_led_off( void ) +{ + HAL_WRITE_UINT8(LED_OFF, 0); +} + + +//============================================================================= +// Compatibility with older stubs +//============================================================================= + +#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG + +static channel_data_t channel = { (cyg_uint8*)SCI_BASE, 0, 0}; + +#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) +#include <cyg/hal/hal_stub.h> // hal_output_gdb_string +#endif + #if defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) #define CYG_HAL_DIAG_GDB @@ -71,24 +119,21 @@ void hal_diag_init(void) { - hal_sci_init_serial(); + cyg_hal_plf_sci_init_channel(&channel); } void hal_diag_write_char_serial( char c ) { - hal_sci_put_char(c); + cyg_hal_plf_sci_putc(&channel, c); } void hal_diag_read_char(char *c) { - *c = (char) hal_sci_get_char(); + *c = (char) cyg_hal_plf_sci_getc(&channel); } -externC cyg_bool cyg_hal_is_break(char *buf, int size); -externC void cyg_hal_user_break(CYG_ADDRWORD *regs); - // Packet function void hal_diag_write_char(char c) @@ -124,26 +169,26 @@ hal_diag_write_char(char c) cyg_uint8 csum = 0; int i; - hal_diag_write_char_serial('$'); - hal_diag_write_char_serial('O'); + cyg_hal_plf_sci_putc(&channel, '$'); + cyg_hal_plf_sci_putc(&channel, 'O'); csum += 'O'; for( i = 0; i < pos; i++ ) { char ch = line[i]; char h = hex[(ch>>4)&0xF]; char l = hex[ch&0xF]; - hal_diag_write_char_serial(h); - hal_diag_write_char_serial(l); + cyg_hal_plf_sci_putc(&channel, h); + cyg_hal_plf_sci_putc(&channel, l); csum += h; csum += l; } - hal_diag_write_char_serial('#'); - hal_diag_write_char_serial(hex[(csum>>4)&0xF]); - hal_diag_write_char_serial(hex[csum&0xF]); + cyg_hal_plf_sci_putc(&channel, '#'); + cyg_hal_plf_sci_putc(&channel, hex[(csum>>4)&0xF]); + cyg_hal_plf_sci_putc(&channel, hex[csum&0xF]); // Wait for the ACK character '+' from GDB here and handle // receiving a ^C instead. - hal_diag_read_char(&c1); + c1 = (char) cyg_hal_plf_sci_getc(&channel); if( c1 == '+' ) break; // a good acknowledge @@ -165,26 +210,10 @@ hal_diag_write_char(char c) #endif } #else // CYG_HAL_DIAG_GDB - hal_diag_write_char_serial(c); + cyg_hal_plf_sci_putc(&channel, c); #endif } - -//----------------------------------------------------------------------------- -// Led control -#define LED_ON 0x04000000 -#define LED_OFF 0x18000000 - -void -hal_diag_led_on( void ) -{ - HAL_WRITE_UINT8(LED_ON, 0); -} - -void -hal_diag_led_off( void ) -{ - HAL_WRITE_UINT8(LED_OFF, 0); -} +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG //----------------------------------------------------------------------------- // End of hal_diag.c diff --git a/packages/hal/sh/edk/current/src/plf_misc.c b/packages/hal/sh/edk/current/src/plf_misc.c index 2ffea80af..861cb7fb6 100644 --- a/packages/hal/sh/edk/current/src/plf_misc.c +++ b/packages/hal/sh/edk/current/src/plf_misc.c @@ -44,59 +44,14 @@ #include <pkgconf/hal.h> -#include <cyg/infra/cyg_type.h> // Base types - -#include <cyg/hal/hal_arch.h> // architectural definitions - -#include <cyg/hal/hal_intr.h> // Interrupt handling - -#include <cyg/hal/hal_cache.h> // Cache handling - -#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS -#include <cyg/hal/hal_stub.h> // stub functionality -#endif +#include <cyg/hal/hal_if.h> // interfacing API //-------------------------------------------------------------------------- -// Functions to support the detection and execution of a user provoked -// program break. These are usually called from interrupt routines. - -cyg_bool -cyg_hal_is_break(char *buf, int size) -{ - while( size ) - if( buf[--size] == 0x03 ) return true; - - return false; -} - void -cyg_hal_user_break( CYG_ADDRWORD *regs ) +hal_platform_init(void) { -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - HAL_SavedRegisters *__sreg = (HAL_SavedRegisters *)regs; - target_register_t __pc; - - if (__sreg) - __pc = (target_register_t) __sreg->pc; - else - __pc = (target_register_t) &&safe_breakpoint; - - // Note: This would be better for the else case but doesn't work - // at the moment. CR: 101357 - // __pc = (target_register_t) __builtin_return_address(0); - - cyg_hal_gdb_interrupt (__pc); - - safe_breakpoint: -#elif defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) - - // Note: Need to communicate to the ROM stub instead - HAL_BREAKPOINT(breakinst); - -#else - - HAL_BREAKPOINT(breakinst); - -#endif - + hal_if_init(); } + +//-------------------------------------------------------------------------- +// eof plf_misc.c diff --git a/packages/hal/v85x/arch/current/ChangeLog b/packages/hal/v85x/arch/current/ChangeLog index bb1f19257..3f455c166 100644 --- a/packages/hal/v85x/arch/current/ChangeLog +++ b/packages/hal/v85x/arch/current/ChangeLog @@ -1,3 +1,12 @@ +2000-06-27 Jesper Skov <jskov@redhat.com> + + * src/vectors.S: + * src/hal_mk_defs.c: + Fix compiler warnings. + + * src/hal_misc.c (hal_default_isr): Let common version do the + checks. + 2000-06-15 Gary Thomas <gthomas@redhat.com> * src/hal_mk_defs.c: diff --git a/packages/hal/v85x/arch/current/src/hal_misc.c b/packages/hal/v85x/arch/current/src/hal_misc.c index e3c4077b7..dc59ac348 100644 --- a/packages/hal/v85x/arch/current/src/hal_misc.c +++ b/packages/hal/v85x/arch/current/src/hal_misc.c @@ -141,11 +141,6 @@ cyg_hal_invoke_constructors (void) externC cyg_uint32 hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) { - CYG_TRACE1(true, "Interrupt: %d", vector); - - diag_printf("Spurious Interrupt!!! - vector: %d, data: %x\n", vector, - data); - CYG_FAIL("Spurious Interrupt!!!"); return 0; } #else diff --git a/packages/hal/v85x/arch/current/src/hal_mk_defs.c b/packages/hal/v85x/arch/current/src/hal_mk_defs.c index 45571cfc1..8e0014d5a 100644 --- a/packages/hal/v85x/arch/current/src/hal_mk_defs.c +++ b/packages/hal/v85x/arch/current/src/hal_mk_defs.c @@ -160,6 +160,8 @@ main(void) #endif // Variant definitions - want these to be included instead. + + return 0; } //-------------------------------------------------------------------------- diff --git a/packages/hal/v85x/arch/current/src/vectors.S b/packages/hal/v85x/arch/current/src/vectors.S index c11877734..d93ef35de 100644 --- a/packages/hal/v85x/arch/current/src/vectors.S +++ b/packages/hal/v85x/arch/current/src/vectors.S @@ -83,7 +83,7 @@ reset_vector: #ifdef CYG_HAL_STARTUP_ROM // // These are the hardware exception vectors. -// +// __ROM_vsr: // 0x000 jr start @@ -92,12 +92,12 @@ __ROM_vsr: .rept CYGNUM_HAL_EXCEPTION_COUNT-1 EXCEPTION .endr - .set VECTOR, 8 + .set VECTOR, 8 .rept CYGNUM_HAL_ISR_COUNT INTERRUPT - .endr + .endr #endif // CYG_HAL_STARTUP_ROM - + .globl start start: // Perform hardware initialization @@ -113,7 +113,7 @@ start: addi 4,r6,r6 addi 4,r7,r7 cmp r7,r8 - bne 1b + bne 1b #endif // Initialize stack lea __startup_stack,r1 @@ -125,7 +125,7 @@ start: 1: st.w r0,0[r6] addi 4,r6,r6 cmp r6,r7 - bne 1b + bne 1b #ifdef CYG_HAL_STARTUP_ROM // Built initial trap VSR tables @@ -135,13 +135,13 @@ start: lea __ROM_vsr,r7 mov r6,r8 sub r7,r8 - lea 0x003FFFFF,r7 + lea 0x003FFFFF,r7 and r7,r8 lea 0x07800000,r7 or r7,r8 #else lea 0x00000794,r8 // jr 0x0100xx0 -#endif +#endif 10: st.w r8,0[r6] addi 16,r6,r6 cmp r6,r9 @@ -169,8 +169,8 @@ start: 10: st.w r8,0[r6] addi 4,r6,r6 addi -1,r7,r7 - bne 10b -#endif + bne 10b +#endif jarl _initialize_stub,r31 #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // this _check_ should go away #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) \ @@ -550,4 +550,3 @@ _hal_interrupt_objects: .rept CYGNUM_HAL_ISR_COUNT .long 0 .endr - \ No newline at end of file diff --git a/packages/hal/v85x/ceb_v850/current/ChangeLog b/packages/hal/v85x/ceb_v850/current/ChangeLog index b54a7c866..b909e07c5 100644 --- a/packages/hal/v85x/ceb_v850/current/ChangeLog +++ b/packages/hal/v85x/ceb_v850/current/ChangeLog @@ -1,3 +1,15 @@ +2000-06-27 Jesper Skov <jskov@redhat.com> + + * src/plf_misc.c: Fix compiler warnings. + + * src/plf_stub.c: + * src/hal_diag.c: + * include/plf_stub.h: + * include/plf_intr.h: + * include/hal_diag.h: + Moved Ctrl-c handling to driver code. Use new comms procs + semantics. + 2000-06-17 Gary Thomas <gthomas@redhat.com> * include/plf_intr.h: diff --git a/packages/hal/v85x/ceb_v850/current/include/hal_diag.h b/packages/hal/v85x/ceb_v850/current/include/hal_diag.h index d8ede1322..3e84642d0 100644 --- a/packages/hal/v85x/ceb_v850/current/include/hal_diag.h +++ b/packages/hal/v85x/ceb_v850/current/include/hal_diag.h @@ -49,14 +49,6 @@ #include <cyg/infra/cyg_type.h> -/*---------------------------------------------------------------------------*/ -/* functions implemented in hal_diag.c */ - - -externC void hal_diag_init(void); -externC void hal_diag_write_char(char c); -externC void hal_diag_read_char(char *c); - /*---------------------------------------------------------------------------*/ #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) @@ -67,18 +59,12 @@ externC void hal_diag_read_char(char *c); #define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_) #define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_) -#ifndef CYGPRI_CONSOLE_PROCS_HANDLED -externC void hal_plf_init_serial(void); -externC void hal_plf_write_char(int); -externC int hal_plf_get_char(void); - -# define HAL_PLF_DIAG_RAW_INIT() hal_plf_init_serial() -# define HAL_PLF_DIAG_RAW_WRITE_CHAR(_c_) hal_plf_write_char(_c_) -# define HAL_PLF_DIAG_RAW_READ_CHAR(_c_) (_c_) = hal_plf_get_char() -#endif - #else +externC void hal_diag_init(void); +externC void hal_diag_write_char(char c); +externC void hal_diag_read_char(char *c); + #define HAL_DIAG_INIT() hal_diag_init() #define HAL_DIAG_WRITE_CHAR(_c_) hal_diag_write_char(_c_) #define HAL_DIAG_READ_CHAR(_c_) hal_diag_read_char(&_c_) diff --git a/packages/hal/v85x/ceb_v850/current/include/plf_intr.h b/packages/hal/v85x/ceb_v850/current/include/plf_intr.h index 5f2fda0db..8f608fe0d 100644 --- a/packages/hal/v85x/ceb_v850/current/include/plf_intr.h +++ b/packages/hal/v85x/ceb_v850/current/include/plf_intr.h @@ -115,9 +115,6 @@ // The vector used by the Real time clock. #define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_VECTOR_INTTM10 -// Vector used to detect ^C -#define CYGHWR_HAL_GDB_PORT_VECTOR CYGNUM_HAL_VECTOR_INTCSI1 - // Mapping from interrupt numbers to hardware registers #define CYG_HAL_V85X_INTERRUPT_CONTROL_REGISTERS \ (volatile unsigned char *)V850_REG_WDTIC, \ @@ -151,15 +148,6 @@ (volatile unsigned char *)V850_REG_DMAIC2, \ (volatile unsigned char *)V850_REG_WTIC -#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) - -extern struct Hal_SavedRegisters *hal_saved_interrupt_state; -extern void hal_ctrlc_isr_init(void); -extern cyg_uint32 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data); -#define HAL_CTRLC_ISR(_v_,_d_) hal_ctrlc_isr(_v_, _d_) -#endif - //-------------------------------------------------------------------------- #endif // ifndef CYGONCE_HAL_PLF_INTR_H // End of plf_intr.h diff --git a/packages/hal/v85x/ceb_v850/current/include/plf_stub.h b/packages/hal/v85x/ceb_v850/current/include/plf_stub.h index c46c56b03..b8678d64f 100644 --- a/packages/hal/v85x/ceb_v850/current/include/plf_stub.h +++ b/packages/hal/v85x/ceb_v850/current/include/plf_stub.h @@ -54,16 +54,11 @@ //---------------------------------------------------------------------------- // Define serial stuff. -extern void hal_plf_init_serial( void ); -extern int hal_plf_get_char( void ); -extern void hal_plf_put_char( int c ); -extern int hal_plf_interruptible( int ); +externC void cyg_hal_plf_comms_init(void); -#define HAL_STUB_PLATFORM_INIT_SERIAL() hal_plf_init_serial() -#define HAL_STUB_PLATFORM_GET_CHAR() hal_plf_get_char() -#define HAL_STUB_PLATFORM_PUT_CHAR(c) hal_plf_put_char((c)) +#define HAL_STUB_PLATFORM_INIT_SERIAL() cyg_hal_plf_comms_init() #define HAL_STUB_PLATFORM_SET_BAUD_RATE(baud) CYG_UNUSED_PARAM(int, (baud)) -#define HAL_STUB_PLATFORM_INTERRUPTIBLE hal_plf_interruptible +#define HAL_STUB_PLATFORM_INTERRUPTIBLE 0 #define HAL_STUB_PLATFORM_INIT_BREAK_IRQ() CYG_EMPTY_STATEMENT //---------------------------------------------------------------------------- diff --git a/packages/hal/v85x/ceb_v850/current/src/hal_diag.c b/packages/hal/v85x/ceb_v850/current/src/hal_diag.c index 95b90d6f9..4fc18b2cd 100644 --- a/packages/hal/v85x/ceb_v850/current/src/hal_diag.c +++ b/packages/hal/v85x/ceb_v850/current/src/hal_diag.c @@ -33,7 +33,7 @@ // // Author(s): nickg, gthomas // Contributors:nickg, gthomas -// Date: 1998-03-02 +// Date: 2000-05-22 // Purpose: HAL diagnostic output // Description: Implementations of HAL diagnostic output support. // @@ -54,27 +54,13 @@ #include <cyg/hal/hal_io.h> // IO macros #include <cyg/hal/hal_diag.h> -#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) #include <cyg/hal/hal_stub.h> // target_register_t -#include <cyg/hal/hal_intr.h> // HAL_INTERRUPT_UNMASK(...) #include <cyg/hal/hal_if.h> // Calling interface definitions #include <cyg/hal/hal_misc.h> // Helper functions #include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED -#endif #include <cyg/hal/v850_common.h> // hardware registers, etc. -// Assumption: all diagnostic output must be GDB packetized unless this is a ROM (i.e. -// totally stand-alone) system. - -#if defined(CYG_HAL_STARTUP_ROM) && !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) -#define HAL_DIAG_USES_HARDWARE -#else -#if defined(CYGDBG_HAL_DIAG_DISABLE_GDB_PROTOCOL) -#define HAL_DIAG_USES_HARDWARE -#endif -#endif #if (CYGHWR_HAL_V85X_V850_CEB_DIAG_BAUD == 9600) #define BAUD_COUNT 0xDD @@ -95,51 +81,243 @@ /*---------------------------------------------------------------------------*/ // CEB-v850 +void +init_serial_channel(void* base) +{ + volatile unsigned char *mode = (volatile unsigned char *)V850_REG_ASIM0; + volatile unsigned char *brgc = (volatile unsigned char *)V850_REG_BRGC0; + volatile unsigned char *brgm = (volatile unsigned char *)V850_REG_BRGM0; + volatile unsigned char *rxstat = (volatile unsigned char *)V850_REG_SRIC0; + volatile unsigned char *rxerr = (volatile unsigned char *)V850_REG_SERIC0; + volatile unsigned char *txstat = (volatile unsigned char *)V850_REG_STIC0; + + *mode = 0xC8; + *brgc = BAUD_COUNT; + *brgm = BAUD_DIVISOR; + *rxstat = 0x47; + *rxerr = 0; + *txstat = 0x47; +} + // Actually send character down the wire void -hal_diag_write_char_serial(char c) +cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 c) { volatile unsigned char *TxDATA = (volatile unsigned char *)V850_REG_TXS0; volatile unsigned char *TxSTAT = (volatile unsigned char *)V850_REG_STIC0; + CYGARC_HAL_SAVE_GP(); + // Send character *TxDATA = (unsigned char)c; // Wait for Tx not busy - while ((*TxSTAT & 0x80) == 0x00) ; + while ((*TxSTAT & 0x80) == 0x00); *TxSTAT &= ~0x80; + + CYGARC_HAL_RESTORE_GP(); } -bool -hal_diag_read_serial(char *c) +static cyg_bool +cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch) { volatile unsigned char *RxDATA = (volatile unsigned char *)V850_REG_RXS0; volatile unsigned char *RxSTAT = (volatile unsigned char *)V850_REG_SRIC0; - volatile unsigned char *RxERR = (volatile unsigned char *)V850_REG_SERIC0; - int timeout = 0; - while ((*RxSTAT & 0x80) == 0x00) { - if (++timeout == 50000) return false; - } - *c = (char)*RxDATA; + + if ((*RxSTAT & 0x80) == 0x00) + return false; + + *ch = (char)*RxDATA; *RxSTAT &= ~0x80; return true; } +cyg_uint8 +cyg_hal_plf_serial_getc(void* __ch_data) +{ + cyg_uint8 ch; + CYGARC_HAL_SAVE_GP(); + + while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch)); + + CYGARC_HAL_RESTORE_GP(); + return ch; +} + +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ + || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) + +static void +cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, + cyg_uint32 __len) +{ + CYGARC_HAL_SAVE_GP(); + + while(__len-- > 0) + cyg_hal_plf_serial_putc(__ch_data, *__buf++); + + CYGARC_HAL_RESTORE_GP(); +} + +static void +cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len) +{ + CYGARC_HAL_SAVE_GP(); + + while(__len-- > 0) + *__buf++ = cyg_hal_plf_serial_getc(__ch_data); + + CYGARC_HAL_RESTORE_GP(); +} + +cyg_int32 msec_timeout = 1000; + +cyg_bool +cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch) +{ + int delay_count = msec_timeout * 10; // delay in .1 ms steps + cyg_bool res; + CYGARC_HAL_SAVE_GP(); + + for(;;) { + res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch); + if (res || 0 == delay_count--) + break; + + CYGACC_CALL_IF_DELAY_US()(100); + } + + CYGARC_HAL_RESTORE_GP(); + return res; +} + +static int +cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...) +{ + static int irq_state = 0; + int ret = 0; + CYGARC_HAL_SAVE_GP(); + + switch (__func) { + case __COMMCTL_IRQ_ENABLE: + HAL_INTERRUPT_UNMASK(CYGNUM_HAL_VECTOR_INTCSI1); + irq_state = 1; + break; + case __COMMCTL_IRQ_DISABLE: + ret = irq_state; + irq_state = 0; + HAL_INTERRUPT_MASK(CYGNUM_HAL_VECTOR_INTCSI1); + break; + case __COMMCTL_DBG_ISR_VECTOR: + ret = CYGNUM_HAL_VECTOR_INTCSI1; + break; + case __COMMCTL_SET_TIMEOUT: + { + va_list ap; + + va_start(ap, __func); + + ret = msec_timeout; + msec_timeout = va_arg(ap, cyg_uint32); + + va_end(ap); + } + default: + break; + } + CYGARC_HAL_RESTORE_GP(); + return ret; +} + +static int +cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, + CYG_ADDRWORD __vector, CYG_ADDRWORD __data) +{ + volatile unsigned char *RxDATA = (volatile unsigned char *)V850_REG_RXS0; + cyg_uint8 c; + int res = 0; + CYGARC_HAL_SAVE_GP(); + + c = (char)*RxDATA; + *__ctrlc = 0; + if( cyg_hal_is_break( &c , 1 ) ) + *__ctrlc = 1; + + cyg_drv_interrupt_acknowledge(CYGNUM_HAL_VECTOR_INTCSI1); + + res = CYG_ISR_HANDLED; + + CYGARC_HAL_RESTORE_GP(); + return res; +} + +static void +cyg_hal_plf_serial_init(void) +{ + hal_virtual_comm_table_t* comm; + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + + // Disable interrupts. + HAL_INTERRUPT_MASK(CYGNUM_HAL_VECTOR_INTCSI1); + + // Init channels + init_serial_channel((cyg_uint8*)0); + + // Setup procs in the vector table + + // Set channel 0 + CYGACC_CALL_IF_SET_CONSOLE_COMM()(0); + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CH_DATA_SET(*comm, 0); + CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); + CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); + CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); + CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); + CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr); + CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout); + + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); +} + +void +cyg_hal_plf_comms_init(void) +{ + static int initialized = 0; + + if (initialized) + return; + + initialized = 1; + + cyg_hal_plf_serial_init(); +} +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES + +//============================================================================= +// Compatibility with older stubs +//============================================================================= + +#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG + +// Assumption: all diagnostic output must be GDB packetized unless this is a ROM (i.e. +// totally stand-alone) system. + +//#ifdef CYGSEM_HAL_ROM_MONITOR +//#define CYG_HAL_STARTUP_ROM +//#undef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS +//#endif + +#if defined(CYG_HAL_STARTUP_ROM) && !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) +#define HAL_DIAG_USES_HARDWARE +#else +#if defined(CYGDBG_HAL_DIAG_DISABLE_GDB_PROTOCOL) +#define HAL_DIAG_USES_HARDWARE +#endif +#endif + void hal_diag_init(void) { - static int init = 0; - volatile unsigned char *mode = (volatile unsigned char *)V850_REG_ASIM0; - volatile unsigned char *brgc = (volatile unsigned char *)V850_REG_BRGC0; - volatile unsigned char *brgm = (volatile unsigned char *)V850_REG_BRGM0; - volatile unsigned char *rxstat = (volatile unsigned char *)V850_REG_SRIC0; - volatile unsigned char *rxerr = (volatile unsigned char *)V850_REG_SERIC0; - volatile unsigned char *txstat = (volatile unsigned char *)V850_REG_STIC0; - if (init) return; - init++; - *mode = 0xC8; - *brgc = BAUD_COUNT; - *brgm = BAUD_DIVISOR; - *rxstat = 0x47; - *rxerr = 0; - *txstat = 0x47; + init_serial_channel(0); } #ifdef HAL_DIAG_USES_HARDWARE @@ -148,14 +326,13 @@ void hal_diag_write_char(char c) { CYG_INTERRUPT_STATE old; HAL_DISABLE_INTERRUPTS(old); - hal_diag_init(); - hal_diag_write_char_serial(c); + cyg_hal_plf_serial_putc(0, c); HAL_RESTORE_INTERRUPTS(old); } void hal_diag_read_char(char *c) { - while (!hal_diag_read_serial(c)) ; + *c = cyg_hal_plf_serial_getc(0); } #else // HAL_DIAG relies on GDB @@ -163,7 +340,7 @@ void hal_diag_read_char(char *c) void hal_diag_read_char(char *c) { - while (!hal_diag_read_serial(c)) ; + *c = cyg_hal_plf_serial_getc(0); } #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS @@ -205,41 +382,40 @@ hal_diag_write_char(char c) int i; char c1; - hal_diag_write_char_serial('$'); - hal_diag_write_char_serial('O'); + cyg_hal_plf_serial_putc(0, '$'); + cyg_hal_plf_serial_putc(0, 'O'); csum += 'O'; for( i = 0; i < pos; i++ ) { char ch = line[i]; char h = hex[(ch>>4)&0xF]; char l = hex[ch&0xF]; - hal_diag_write_char_serial(h); - hal_diag_write_char_serial(l); + cyg_hal_plf_serial_putc(0, h); + cyg_hal_plf_serial_putc(0, l); csum += h; csum += l; } - hal_diag_write_char_serial('#'); - hal_diag_write_char_serial(hex[(csum>>4)&0xF]); - hal_diag_write_char_serial(hex[csum&0xF]); + cyg_hal_plf_serial_putc(0, '#'); + cyg_hal_plf_serial_putc(0, hex[(csum>>4)&0xF]); + cyg_hal_plf_serial_putc(0, hex[csum&0xF]); // Wait for the ACK character '+' from GDB here and handle // receiving a ^C instead. This is the reason for this clause // being a loop. - if (!hal_diag_read_serial(&c1)) - continue; // No response - try sending packet again + c1 = cyg_hal_plf_serial_getc(0); if( c1 == '+' ) break; // a good acknowledge #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) && \ defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) - cyg_drv_interrupt_acknowledge(CYGHWR_HAL_GDB_PORT_VECTOR); + cyg_drv_interrupt_acknowledge(CYGNUM_HAL_VECTOR_INTCSI1); if( c1 == 3 ) { // Ctrl-C: breakpoint. #if 0 // FIXME - __builtin_return_address() doesn't work cyg_hal_gdb_interrupt (__builtin_return_address(0)); #else - cyg_hal_gdb_interrupt (hal_diag_write_char_break); + cyg_hal_gdb_interrupt((CYG_ADDRWORD)hal_diag_write_char_break); #endif break; } @@ -262,28 +438,7 @@ hal_diag_write_char(char c) } #endif // USE HARDWARE -#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) - -struct Hal_SavedRegisters *hal_saved_interrupt_state; - -void -hal_ctrlc_isr_init(void) -{ - HAL_INTERRUPT_UNMASK(CYGHWR_HAL_GDB_PORT_VECTOR); -} - -cyg_uint32 -hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) -{ - volatile unsigned char *RxDATA = (volatile unsigned char *)V850_REG_RXS0; - unsigned char ch; - ch = (char)*RxDATA; - if( cyg_hal_is_break( &ch , 1 ) ) - cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state ); - return CYG_ISR_HANDLED; -} -#endif +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG /*---------------------------------------------------------------------------*/ /* End of hal_diag.c */ diff --git a/packages/hal/v85x/ceb_v850/current/src/plf_misc.c b/packages/hal/v85x/ceb_v850/current/src/plf_misc.c index 2c1ca7864..246429116 100644 --- a/packages/hal/v85x/ceb_v850/current/src/plf_misc.c +++ b/packages/hal/v85x/ceb_v850/current/src/plf_misc.c @@ -55,6 +55,8 @@ #include <cyg/hal/hal_if.h> // ROM monitor interfaces +#include <cyg/infra/diag.h> // diag_printf + extern void show_hex4(unsigned long val); extern void show_hex1(unsigned long val); extern void show_8bit_reg(void *addr); @@ -63,7 +65,6 @@ extern void show_led(int p); void cyg_hal_platform_hardware_init(void) { - int i; hal_if_init(); // Initialize GDB[ROM]/eCos interfaces show_led(' '); show_led(' '); @@ -92,9 +93,9 @@ show_8bit_reg(void *addr) unsigned char *reg = (unsigned char *)addr; unsigned char val = *reg; show_led(' '); - show_hex4(reg); + show_hex4((unsigned long)reg); show_led('='); - show_hex1(val); + show_hex1((unsigned long)val); show_led('/'); } @@ -302,7 +303,7 @@ extern void _hal_thread_switch_context(HAL_SavedRegisters **to, HAL_SavedRegiste void hal_thread_load_context(CYG_ADDRESS to) { - HAL_SavedRegisters **new_context = to; + HAL_SavedRegisters **new_context = (HAL_SavedRegisters **)to; #if 0 diag_printf("Load context: %x\n", *new_context); show_regs(*new_context); @@ -312,8 +313,8 @@ void hal_thread_load_context(CYG_ADDRESS to) void hal_thread_switch_context(CYG_ADDRESS to, CYG_ADDRESS from) { - HAL_SavedRegisters **old_context = from; - HAL_SavedRegisters **new_context = to; + HAL_SavedRegisters **old_context = (HAL_SavedRegisters **)from; + HAL_SavedRegisters **new_context = (HAL_SavedRegisters **)to; #if 0 diag_printf("Switch context - old: %x, new: %x\n", *old_context, *new_context); show_regs(*new_context); diff --git a/packages/hal/v85x/ceb_v850/current/src/plf_stub.c b/packages/hal/v85x/ceb_v850/current/src/plf_stub.c index f802deffb..3771d081c 100644 --- a/packages/hal/v85x/ceb_v850/current/src/plf_stub.c +++ b/packages/hal/v85x/ceb_v850/current/src/plf_stub.c @@ -54,84 +54,6 @@ #include <cyg/hal/v850_common.h> -/*---------------------------------------------------------------------------*/ -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT -static cyg_interrupt gdb_interrupt; -static cyg_handle_t gdb_interrupt_handle; -#define CYG_DEVICE_SERIAL_INT CYGNUM_HAL_VECTOR_INTCSI1 - -// This ISR is called only for serial receive interrupts. -int -cyg_hal_gdb_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs) -{ - volatile unsigned char *RxDATA = (volatile unsigned char *)V850_REG_RXS0; - cyg_uint8 c; - - c = *RxDATA; // Fetch the character - if( 3 == c ) { // ^C - // Ctrl-C: set a breakpoint at PC so GDB will display the - // correct program context when stopping rather than the - // interrupt handler. - cyg_hal_gdb_interrupt (regs->pc); - cyg_drv_interrupt_acknowledge(CYG_DEVICE_SERIAL_INT); - } - return 0; // No need to run DSR -} - -int -hal_plf_interruptible(int state) -{ - if (state) { - cyg_drv_interrupt_unmask(CYG_DEVICE_SERIAL_INT); - } else { - cyg_drv_interrupt_mask(CYG_DEVICE_SERIAL_INT); - } - - return 0; -} -#endif - -void hal_plf_init_serial() -{ -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - cyg_drv_interrupt_create(CYG_DEVICE_SERIAL_INT, - 99, // Priority - what goes here? - 0, // Data item passed to interrupt handler - cyg_hal_gdb_isr, - 0, - &gdb_interrupt_handle, - &gdb_interrupt); - cyg_drv_interrupt_attach(gdb_interrupt_handle); - cyg_drv_interrupt_unmask(CYG_DEVICE_SERIAL_INT); -#endif -} - -/*---------------------------------------------------------------------------*/ - -void hal_plf_put_char( int c) -{ - hal_diag_write_char_serial(c); -} - -/*---------------------------------------------------------------------------*/ - -int hal_plf_get_char( void ) -{ - volatile unsigned char *LED = (volatile unsigned char *)V850_REG_P10; - char c; - unsigned char led = *LED & 0x7F; - if (led == 0) { - led = 0x01; - } else { - led <<= 1; - } - *LED = 0x80 | led; - hal_diag_read_char(&c); - *LED &= 0x7F; - return c; -} - - //----------------------------------------------------------------------------- // Stub init diff --git a/packages/io/serial/current/ChangeLog b/packages/io/serial/current/ChangeLog index 63bc7471c..635a7db71 100644 --- a/packages/io/serial/current/ChangeLog +++ b/packages/io/serial/current/ChangeLog @@ -1,3 +1,7 @@ +2000-06-23 Jesper Skov <jskov@redhat.com> + + * tests/ser_test_protocol.inl: Added cq7708 definitions. + 2000-05-28 Gary Thomas <gthomas@redhat.com> * tests/ser_test_protocol.inl: Rename NEC V85x drivers. diff --git a/packages/io/serial/current/tests/ser_test_protocol.inl b/packages/io/serial/current/tests/ser_test_protocol.inl index f1c779b28..702ee774f 100644 --- a/packages/io/serial/current/tests/ser_test_protocol.inl +++ b/packages/io/serial/current/tests/ser_test_protocol.inl @@ -196,6 +196,15 @@ # define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV # endif #endif +#if defined(CYGPKG_HAL_SH) \ + && defined(CYGPKG_IO_SERIAL_SH_CQ7708) \ + && defined(CYGPKG_IO_SERIAL_SH_CQ7708_SCI) +# define TEST_CRASH_ID "cq7708" +# define TEST_SER_DEV CYGDAT_IO_SERIAL_SH_CQ7708_SCI_NAME +# if defined(CYGPKG_IO_SERIAL_TTY_TTY2) +# define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV +# endif +#endif #if defined(CYGPKG_HAL_I386_PC) \ && defined(CYGPKG_IO_SERIAL_I386_PC) \ && defined(CYGPKG_IO_SERIAL_I386_PC_SERIAL0) diff --git a/packages/kernel/current/ChangeLog b/packages/kernel/current/ChangeLog index 9042873a7..24dcabc67 100644 --- a/packages/kernel/current/ChangeLog +++ b/packages/kernel/current/ChangeLog @@ -1,3 +1,11 @@ +2000-06-23 Hugo Tyson <hmt@cygnus.co.uk> + + * include/kapi.h (cyg_scheduler_read_lock): New function, to + return the value of the scheduler lock; this for implementing SPLX + in the network stack. + + * src/common/kapi.cxx (cyg_scheduler_read_lock): New function. + 2000-06-16 Gary Thomas <gthomas@redhat.com> * cdl/kernel.cdl: Remove exception tests for CMA230 - not supported diff --git a/packages/kernel/current/include/kapi.h b/packages/kernel/current/include/kapi.h index 38118c426..ef9bdcbe3 100644 --- a/packages/kernel/current/include/kapi.h +++ b/packages/kernel/current/include/kapi.h @@ -133,6 +133,9 @@ void cyg_scheduler_unlock(void); /* subsequent call to 'cyg_scheduler_unlock()' will completely unlock. */ void cyg_scheduler_safe_lock(void); +/* Read the scheduler lock value. */ +cyg_ucount32 cyg_scheduler_read_lock(void); + /*---------------------------------------------------------------------------*/ /* Thread operations */ diff --git a/packages/kernel/current/src/common/kapi.cxx b/packages/kernel/current/src/common/kapi.cxx index 6ee11846e..5f89c3b0a 100644 --- a/packages/kernel/current/src/common/kapi.cxx +++ b/packages/kernel/current/src/common/kapi.cxx @@ -137,6 +137,13 @@ externC void cyg_scheduler_unlock(void) Cyg_Scheduler::unlock(); } +/* Read the scheduler lock value. */ +externC cyg_ucount32 cyg_scheduler_read_lock(void) +{ + cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock(); + return slock; +} + /*---------------------------------------------------------------------------*/ /* Thread operations */ diff --git a/packages/net/snmp/agent/current/ChangeLog b/packages/net/snmp/agent/current/ChangeLog index bc335b048..3abf31f87 100644 --- a/packages/net/snmp/agent/current/ChangeLog +++ b/packages/net/snmp/agent/current/ChangeLog @@ -1,3 +1,14 @@ +2000-06-27 Hugo Tyson <hmt@cygnus.co.uk> + + * src/mibgroup/mibII/dot3.c (var_dot3StatsTable): Forgot the + DOT3STATSINDEX for loopback, so it claimed index 0. Fixed. + +2000-06-26 Hugo Tyson <hmt@cygnus.co.uk> + + * src/snmptask.c (cyg_net_snmp_init): Change the priority of the + SNMP thread; make it one less important than the network thread of + which it is a client. + 2000-06-19 Hugo Tyson <hmt@cygnus.co.uk> * src/mibgroup/mibII/dot3.c (var_dot3StatsTable): Don't trip over diff --git a/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c b/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c index 715c4ef56..3e9446049 100644 --- a/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c +++ b/packages/net/snmp/agent/current/src/mibgroup/mibII/dot3.c @@ -242,6 +242,10 @@ var_dot3StatsTable(struct variable *vp, if ( IFT_LOOP == ifp->if_type ) { switch(vp->magic) { + case DOT3STATSINDEX: + long_ret = name[(*length)-1]; + return (unsigned char *) &long_ret; + case DOT3STATSETHERCHIPSET: *var_len = sizeof(nullobjid); return (unsigned char *) nullobjid; diff --git a/packages/net/snmp/agent/current/src/snmptask.c b/packages/net/snmp/agent/current/src/snmptask.c index 30446776d..2e980db5e 100644 --- a/packages/net/snmp/agent/current/src/snmptask.c +++ b/packages/net/snmp/agent/current/src/snmptask.c @@ -176,7 +176,7 @@ cyg_net_snmp_init(void) { // Create network background thread - cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY-2, // Priority + cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY+1, // Priority, just lower than the net snmpd, // entry 0, // entry parameter "snmpd", // Name diff --git a/packages/net/tcpip/current/ChangeLog b/packages/net/tcpip/current/ChangeLog index 2db54304f..a9fba6bb0 100644 --- a/packages/net/tcpip/current/ChangeLog +++ b/packages/net/tcpip/current/ChangeLog @@ -1,3 +1,23 @@ +2000-06-26 Hugo Tyson <hmt@cygnus.co.uk> + + * tests/ping_test.c (net_test): Added use of the + CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS stuff now that the test + passes (consequent on the change below); also use larger ping + packets now that that is working also. + + * tests/tcp_echo.c (echo_test): Added use of the + CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS stuff now that the test + passes (consequent on the change below). + +2000-06-26 Hugo Tyson <hmt@cygnus.co.uk> + + * src/ecos/support.c (cyg_splnet): Use the scheduler lock and a + mutex instead of disable-interrupts for SPLX type processing. A + mutex is used at splsoftnet because that is client threads - we do + not want them to pre-empt the rest of the app. This enables the + real-time response testing for the EBSA285 to succeed (interrupts + every 1mS, DSRs delayed by at most 2mS). + 2000-06-23 Hugo Tyson <hmt@cygnus.co.uk> * src/ecos/support.c (cyg_net_mbuf_alloc, cyg_kmem_init): Align diff --git a/packages/net/tcpip/current/src/ecos/support.c b/packages/net/tcpip/current/src/ecos/support.c index 2889a9aa5..51e604c0a 100644 --- a/packages/net/tcpip/current/src/ecos/support.c +++ b/packages/net/tcpip/current/src/ecos/support.c @@ -102,11 +102,111 @@ cyg_panic(const char *msg, ...) cyg_test_exit(); // FIXME } + +// ------------------------------------------------------------------------ +#define SPLSOFTNET_IS_A_MUTEX 1 +// ------------------------------------------------------------------------ +#ifdef SPLSOFTNET_IS_A_MUTEX + +#define MUTEX 0x50F750F7 +#define HOLD MUTEX+1 + +static cyg_mutex_t mutex; +static volatile cyg_handle_t owner; + +#define SPLINIT() CYG_MACRO_START \ + cyg_mutex_init( &mutex ); \ + owner = 0; \ +CYG_MACRO_END + +// use the scheduler lock for SPLX() and a mutex for softnet + +static inline cyg_uint32 +cyg_splin_softnet(void) +{ + if ( 0 == cyg_scheduler_read_lock() ) { + cyg_handle_t self = cyg_thread_self(); + if ( self != owner ) { + cyg_mutex_lock( &mutex ); // Perfectly OK for this to wait + owner = self; + return MUTEX; // release when restoring here + } + return HOLD; // do not release when restoring to this value + } + cyg_scheduler_lock(); + return cyg_scheduler_read_lock() - 1; +} + +static inline cyg_uint32 +cyg_splin(void) +{ + cyg_scheduler_lock(); + return cyg_scheduler_read_lock() - 1; +} + +static inline void +cyg_splout(cyg_uint32 orig) +{ + if ( MUTEX == orig ) { + CYG_ASSERT( cyg_thread_self() == owner, "Not owner release!" ); + cyg_scheduler_lock(); + owner = 0; + cyg_mutex_unlock( &mutex ); + cyg_scheduler_unlock(); + return; + } + if ( HOLD == orig ) { + CYG_ASSERT( cyg_thread_self() == owner, "Not owner hold!" ); + return; + } + CYG_ASSERT( 0 == (0xffff0000 & orig), "Scary splx value" ); + while ( cyg_scheduler_read_lock() > orig ) + cyg_scheduler_unlock(); +} + +#define SPL_ENTER(x) (x) = cyg_splin() +#define SPL_SOFTNET(x) (x) = cyg_splin_softnet() +#define SPL_EXIT(x) cyg_splout((x)) + +#else +#if 1 + +// use the scheduler lock for SPLX() +static inline cyg_uint32 +cyg_splin(void) +{ + cyg_scheduler_lock(); + return cyg_scheduler_read_lock() - 1; +} + +static inline void +cyg_splout(cyg_uint32 orig) +{ + CYG_ASSERT( 0 == (0xffff0000 & orig), "Scary splx value" ); + while ( cyg_scheduler_read_lock() > orig ) + cyg_scheduler_unlock(); +} + +#define SPL_ENTER(x) (x) = cyg_splin() +#define SPL_SOFTNET(x) (x) = cyg_splin() +#define SPL_EXIT(x) cyg_splout((x)) + +#else + +// Old interrupt based version +#define SPL_ENTER(x) HAL_DISABLE_INTERRUPTS((x)) +#define SPL_SOFTNET(x) HAL_DISABLE_INTERRUPTS((x)) +#define SPL_EXIT(x) HAL_RESTORE_INTERRUPTS((x)) + +#endif +#endif +// ------------------------------------------------------------------------ + cyg_uint32 cyg_splimp(void) { cyg_uint32 old_ints; - HAL_DISABLE_INTERRUPTS(old_ints); + SPL_ENTER(old_ints); return old_ints; } @@ -114,7 +214,7 @@ cyg_uint32 cyg_splnet(void) { cyg_uint32 old_ints; - HAL_DISABLE_INTERRUPTS(old_ints); + SPL_ENTER(old_ints); return old_ints; } @@ -122,7 +222,7 @@ cyg_uint32 cyg_splclock(void) { cyg_uint32 old_ints; - HAL_DISABLE_INTERRUPTS(old_ints); + SPL_ENTER(old_ints); return old_ints; } @@ -130,14 +230,14 @@ cyg_uint32 cyg_splsoftnet(void) { cyg_uint32 old_ints; - HAL_DISABLE_INTERRUPTS(old_ints); + SPL_SOFTNET(old_ints); return old_ints; } void cyg_splx(cyg_uint32 old_lev) { - HAL_RESTORE_INTERRUPTS(old_lev); + SPL_EXIT(old_lev); } void @@ -497,11 +597,19 @@ cyg_wakeup(void *chan) int cyg_tsleep(void *chan, int pri, char *wmesg, int timo) { - int i, res; + int i, res = 0; struct wakeup_event *ev; cyg_tick_count_t sleep_time; - res = 0; +#ifdef SPLSOFTNET_IS_A_MUTEX + int olock; // this does the same as safe_lock() but keeping the old state + cyg_scheduler_lock(); // ...around. + olock = cyg_scheduler_read_lock(); + if ( olock > 1 ) + cyg_scheduler_unlock(); +#else cyg_scheduler_safe_lock(); // Ensure safe scan +#endif + for (i = 0, ev = wakeup_list; i < CYGPKG_NET_NUM_WAKEUP_EVENTS; i++, ev++) { if (ev->chan == 0) { ev->chan = chan; @@ -511,16 +619,41 @@ cyg_tsleep(void *chan, int pri, char *wmesg, int timo) if (i == CYGPKG_NET_NUM_WAKEUP_EVENTS) { panic("no sleep slots"); } - cyg_scheduler_unlock(); - if (timo) { - sleep_time = cyg_current_time() + timo; - if (!cyg_semaphore_timed_wait(&ev->sem, sleep_time)) { - res = ETIMEDOUT; - ev->chan = 0; // Free slot + CYG_ASSERT( 1 == cyg_scheduler_read_lock(), "Sleep won't!" ); + +#ifdef SPLSOFTNET_IS_A_MUTEX + { // Then we must release the mutex when we wait - if we have it + cyg_handle_t self = cyg_thread_self(); + if ( self == owner ) { + owner = 0; + cyg_mutex_unlock( &mutex ); + } else { + self = 0; // Flag no need to reclaim } - } else { - cyg_semaphore_wait(&ev->sem); +#endif + + // This part actually does the wait: + cyg_scheduler_unlock(); + if (timo) { + sleep_time = cyg_current_time() + timo; + if (!cyg_semaphore_timed_wait(&ev->sem, sleep_time)) { + res = ETIMEDOUT; + ev->chan = 0; // Free slot + } + } else { + cyg_semaphore_wait(&ev->sem); + } + +#ifdef SPLSOFTNET_IS_A_MUTEX + if ( self ) { // return to previous state + cyg_mutex_lock( &mutex ); // this might wait + owner = self; // got it now... + } + if ( olock > 1 ) + cyg_scheduler_lock(); } +#endif + return res; } @@ -590,6 +723,10 @@ cyg_net_init(void) cyg_do_net_init(); // Just forces the linking in of the initializer/constructor // Initialize interrupt "flags" cyg_flag_init(&netint_flags); + // Anthing else needed? +#ifdef SPLINIT + SPLINIT(); +#endif // Create network background thread cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY, // Priority cyg_netint, // entry diff --git a/packages/net/tcpip/current/tests/ping_test.c b/packages/net/tcpip/current/tests/ping_test.c index 2d4091671..06575bf12 100644 --- a/packages/net/tcpip/current/tests/ping_test.c +++ b/packages/net/tcpip/current/tests/ping_test.c @@ -56,6 +56,37 @@ #include <network.h> +#include <pkgconf/system.h> +#include <pkgconf/net.h> + +#include <cyg/infra/testcase.h> + +#ifdef CYGBLD_DEVS_ETH_DEVICE_H // Get the device config if it exists +#include CYGBLD_DEVS_ETH_DEVICE_H // May provide CYGTST_DEVS_ETH_TEST_NET_REALTIME +#endif + +#ifdef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS // do we use the rt test? +# ifdef CYGTST_DEVS_ETH_TEST_NET_REALTIME // Get the test ancilla if it exists +# include CYGTST_DEVS_ETH_TEST_NET_REALTIME +# endif +#endif + +// Fill in the blanks if necessary +#ifndef TNR_OFF +# define TNR_OFF() +#endif +#ifndef TNR_ON +# define TNR_ON() +#endif +#ifndef TNR_INIT +# define TNR_INIT() +#endif +#ifndef TNR_PRINT_ACTIVITY +# define TNR_PRINT_ACTIVITY() +#endif + + + #define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL static char stack[STACK_SIZE]; static cyg_thread thread_data; @@ -63,18 +94,20 @@ static cyg_handle_t thread_handle; #define NUM_PINGS 16 #define MAX_PACKET 4096 +#define MIN_PACKET 64 +#define MAX_SEND 4000 + +#define PACKET_ADD ((MAX_SEND - MIN_PACKET)/NUM_PINGS) +#define nPACKET_ADD 1 + static unsigned char pkt1[MAX_PACKET], pkt2[MAX_PACKET]; #define UNIQUEID 0x1234 -extern void -cyg_test_exit(void); - void pexit(char *s) { - perror(s); - cyg_test_exit(); + CYG_TEST_FAIL_FINISH(s); } // Compute INET checksum @@ -149,7 +182,7 @@ static void ping_host(int s, struct sockaddr_in *host) { struct icmp *icmp = (struct icmp *)pkt1; - int icmp_len = 64; + int icmp_len = MIN_PACKET; int seq, ok_recv, bogus_recv; cyg_tick_count_t *tp; long *dp; @@ -159,7 +192,8 @@ ping_host(int s, struct sockaddr_in *host) ok_recv = 0; bogus_recv = 0; diag_printf("PING server %s\n", inet_ntoa(host->sin_addr)); - for (seq = 0; seq < NUM_PINGS; seq++) { + for (seq = 0; seq < NUM_PINGS; seq++, icmp_len += PACKET_ADD ) { + TNR_ON(); // Build ICMP packet icmp->icmp_type = ICMP_ECHO; icmp->icmp_code = 0; @@ -177,12 +211,14 @@ ping_host(int s, struct sockaddr_in *host) icmp->icmp_cksum = inet_cksum( (u_short *)icmp, icmp_len+8); // Send it off if (sendto(s, icmp, icmp_len+8, 0, (struct sockaddr *)host, sizeof(*host)) < 0) { + TNR_OFF(); perror("sendto"); continue; } // Wait for a response fromlen = sizeof(from); len = recvfrom(s, pkt2, sizeof(pkt2), 0, (struct sockaddr *)&from, &fromlen); + TNR_OFF(); if (len < 0) { perror("recvfrom"); } else { @@ -193,6 +229,7 @@ ping_host(int s, struct sockaddr_in *host) } } } + TNR_OFF(); diag_printf("Sent %d packets, received %d OK, %d bad\n", NUM_PINGS, ok_recv, bogus_recv); } @@ -205,12 +242,12 @@ ping_test(struct bootp *bp) int s; if ((p = getprotobyname("icmp")) == (struct protoent *)0) { - perror("getprotobyname"); + pexit("getprotobyname"); return; } s = socket(AF_INET, SOCK_RAW, p->p_proto); if (s < 0) { - perror("socket"); + pexit("socket"); return; } tv.tv_sec = 1; @@ -230,6 +267,7 @@ void net_test(cyg_addrword_t p) { diag_printf("Start PING test\n"); + TNR_INIT(); init_all_network_interfaces(); #ifdef CYGHWR_NET_DRIVER_ETH0 if (eth0_up) { @@ -241,7 +279,8 @@ net_test(cyg_addrword_t p) ping_test(ð1_bootp_data); } #endif - cyg_test_exit(); + TNR_PRINT_ACTIVITY(); + CYG_TEST_PASS_FINISH("Ping test OK"); } void diff --git a/packages/net/tcpip/current/tests/tcp_echo.c b/packages/net/tcpip/current/tests/tcp_echo.c index b5e425be2..63d7c298d 100644 --- a/packages/net/tcpip/current/tests/tcp_echo.c +++ b/packages/net/tcpip/current/tests/tcp_echo.c @@ -57,6 +57,35 @@ // //========================================================================== +#include <pkgconf/system.h> +#include <pkgconf/net.h> + +#ifdef CYGBLD_DEVS_ETH_DEVICE_H // Get the device config if it exists +#include CYGBLD_DEVS_ETH_DEVICE_H // May provide CYGTST_DEVS_ETH_TEST_NET_REALTIME +#endif + +#ifdef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS // do we use the rt test? +# ifdef CYGTST_DEVS_ETH_TEST_NET_REALTIME // Get the test ancilla if it exists +# include CYGTST_DEVS_ETH_TEST_NET_REALTIME +# endif +#endif + + +// Fill in the blanks if necessary +#ifndef TNR_OFF +# define TNR_OFF() +#endif +#ifndef TNR_ON +# define TNR_ON() +#endif +#ifndef TNR_INIT +# define TNR_INIT() +#endif +#ifndef TNR_PRINT_ACTIVITY +# define TNR_PRINT_ACTIVITY() +#endif + + // Network throughput test code #include <lib/libkern/libkern.h> @@ -118,6 +147,7 @@ cyg_test_exit(void); void pexit(char *s) { + TNR_OFF(); perror(s); cyg_test_exit(); } @@ -449,26 +479,34 @@ echo_test(cyg_addrword_t p) starttime = cyg_current_time(); start_load(params.load); + TNR_ON(); + // Echo the data from the source to the sink hosts for (i = 0; i < params.nbufs; i++) { if ((len = do_read(e_source, data_buf, params.bufsize)) != params.bufsize) { + TNR_OFF(); diag_printf("Can't read buf #%d: ", i+1); if (len < 0) { perror("I/O error"); } else { diag_printf("short read - only %d bytes\n", len); } + TNR_ON(); } if ((len = do_write(e_sink, data_buf, params.bufsize)) != params.bufsize) { + TNR_OFF(); diag_printf("Can't write buf #%d: ", i+1); if (len < 0) { perror("I/O error"); } else { diag_printf("short write - only %d bytes\n", len); } + TNR_ON(); } } + TNR_OFF(); + // Wait for the data to drain and the "sink" to tell us all is OK. if (do_read(e_sink, &status, sizeof(status)) != sizeof(status)) { pexit("Can't receive ACK from 'sink' host"); @@ -511,7 +549,15 @@ net_test(cyg_addrword_t param) diag_printf("Start TCP test - ECHO mode\n"); init_all_network_interfaces(); calibrate_load(DESIRED_BACKGROUND_LOAD); + TNR_INIT(); +#ifdef CYGPKG_SNMPAGENT + { + extern void cyg_net_snmp_init(void); + cyg_net_snmp_init(); + } +#endif echo_test(param); + TNR_PRINT_ACTIVITY(); cyg_test_exit(); } @@ -558,3 +604,5 @@ cyg_start(void) } cyg_scheduler_start(); } + +// EOF tcp_echo.c -- GitLab