Mercurial > ecos
changeset 182:f62680ef1804
Merge from eCos master repository on 2001-09-07-06:43:02-BST
line wrap: on
line diff
--- a/host/tools/configtool/common/common/build.cxx +++ b/host/tools/configtool/common/common/build.cxx @@ -39,7 +39,7 @@ //####DESCRIPTIONEND#### //========================================================================== -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) #include <windows.h> /* for GetShortPathNameA() */ #endif #ifdef __CYGWIN__ @@ -120,7 +120,7 @@ static void path_to_vector (std::string // eliminate spaces from a DOS filepath by substituting the // short form of path components containing spaces -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) std::string nospace_path (const std::string input) { // split the path into a vector of path components std::vector <std::string> long_path_vector; @@ -151,7 +151,7 @@ std::string nospace_path (const std::str // convert a DOS filepath to a Cygwin filepath std::string cygpath (const std::string input) { -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) // remove spaces from the DOS filepath const std::string path = nospace_path (input); std::string output; @@ -323,7 +323,7 @@ bool generate_makefile (const CdlConfigu fprintf (stream, "export COMMAND_PREFIX := %s\n", command_prefix.c_str ()); fprintf (stream, "export CC := $(COMMAND_PREFIX)gcc\n"); fprintf (stream, "export OBJCOPY := $(COMMAND_PREFIX)objcopy\n"); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) fprintf (stream, "export HOST := CYGWIN\n"); #else fprintf (stream, "export HOST := UNIX\n"); @@ -415,7 +415,7 @@ bool generate_makefile (const CdlConfigu fprintf (stream, "\n\n"); for (count = 0; count < info.headers.size (); count++) { // for each header fprintf (stream, "$(PREFIX)/include/%s: $(REPOSITORY)/$(PACKAGE)/%s\n", info.headers [count].destination.c_str (), info.headers [count].source.c_str ()); -#if defined(_WIN32) && (ECOS_USE_CYGDRIVE == 1) +#if (defined(_WIN32) || defined(__CYGWIN__)) && (ECOS_USE_CYGDRIVE == 1) fprintf (stream, "ifeq ($(HOST),CYGWIN)\n"); fprintf (stream, "\t@mkdir -p `cygpath -w \"$(dir $@)\" | sed \"s/\\\\\\\\\\/\\\\//g\"`\n"); fprintf (stream, "else\n"); @@ -482,7 +482,7 @@ bool generate_toplevel_makefile (const C // generate the variables fprintf (stream, "export REPOSITORY := %s\n", cygpath (config->get_database ()->get_component_repository ()).c_str ()); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) fprintf (stream, "export HOST := CYGWIN\n"); #else fprintf (stream, "export HOST := UNIX\n"); @@ -545,7 +545,7 @@ bool generate_toplevel_makefile (const C // generates the directory structure for the build and install trees bool generate_build_tree (const CdlConfiguration config, const std::string build_tree, const std::string install_tree /* = "" */ ) { -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) // convert backslash directory separators to forward slashes under Win32 const std::string build_dir = replace_char (build_tree, '\\', '/'); const std::string install_dir = install_tree.empty () ? build_dir + "/install" : replace_char (install_tree, '\\', '/');
--- a/host/tools/configtool/standalone/wxwin/CHANGES.txt +++ b/host/tools/configtool/standalone/wxwin/CHANGES.txt @@ -1,6 +1,28 @@ Release History for eCos Configuration Tool 2 ============================================= +*** Version 2.07, September 5th 2001 + +- Image (png) files and about.htm now incorporated into configtool.bin, + which is an ordinary zip file. + + +*** Version 2.06, August 30th 2001 + +- Now saves the width of the configuration tree pane. + +- New -r (--edit-only) command-line switch which suppresses creation + of build trees when saving .ecc files. + +- Added -v (--version), -h (--help) switches, and under Unix the + resulting output goes on the terminal, not a dialog box. + +- The build tree will now only get generated when the file is saved instead + of when a new document is created or template selected. + +- Added recursive process killing for implementing Stop command. + + *** Version 2.05, August 10th 2001 - Fixed a bug in the administration dialog that only looked at the filename of the
--- a/host/tools/configtool/standalone/wxwin/README.txt +++ b/host/tools/configtool/standalone/wxwin/README.txt @@ -116,9 +116,7 @@ Installing the Configuration Tool The following files will be extracted to the installation directory: configtool - ecoslogo.png - rhlogo.png - about.htm + configtool.bin README.txt license.txt ecosplatforms.tar.gz
--- a/host/tools/configtool/standalone/wxwin/TODO.txt +++ b/host/tools/configtool/standalone/wxwin/TODO.txt @@ -31,3 +31,6 @@ To-Do List for Configuration Tool 2.x Bart says: "The whole makefile generation system needs a major overhaul." +- Make as many UI elements as possible copyable to the clipboard, such as the + name and description for a configuration option. Can do this via the right-click + menus.
--- a/host/tools/configtool/standalone/wxwin/about.htm +++ b/host/tools/configtool/standalone/wxwin/about.htm @@ -10,7 +10,7 @@ <table> <tr> <td> - <IMG src="rhlogo.png" align=left vspace=2> + <IMG src="memory:rhlogo.png" align=left vspace=2> </td> <td bgcolor="#101010"> @@ -60,7 +60,7 @@ Drew Moseley<BR> </td> <td valign=center align=center> -<IMG src="ecoslogosmall.png" align=center> +<IMG src="memory:ecoslogosmall.png" align=center> </td> <td valign=top align=left>
--- a/host/tools/configtool/standalone/wxwin/aboutdlg.cpp +++ b/host/tools/configtool/standalone/wxwin/aboutdlg.cpp @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/09/11 -// Version: $Id: aboutdlg.cpp,v 1.11 2001/06/27 14:07:05 julians Exp $ +// Version: $Id: aboutdlg.cpp,v 1.12 2001/09/05 14:35:53 julians Exp $ // Purpose: // Description: Implementation file for ecAboutDialog // Requires: @@ -52,6 +52,7 @@ #include "wx/wxhtml.h" #include "wx/datetime.h" #include "wx/file.h" +#include "wx/fs_mem.h" #ifdef __BORLANDC__ #pragma hdrstop @@ -81,23 +82,28 @@ ecAboutDialog::ecAboutDialog( wxWindow * bool ecAboutDialog::AddControls(wxWindow* parent) { - wxSetWorkingDirectory(wxGetApp().GetAppDir()); - wxString htmlFile(wxGetApp().GetFullAppPath(wxT("about.htm"))); + wxString htmlText; - wxString htmlText; - if (wxFileExists(htmlFile)) + if (!wxGetApp().GetMemoryTextResource(wxT("about.htm"), htmlText)) { - wxFile file; - file.Open(htmlFile, wxFile::read); - long len = file.Length(); - char* buf = htmlText.GetWriteBuf(len + 1); - file.Read(buf, len); - buf[len] = 0; - htmlText.UngetWriteBuf(); + wxSetWorkingDirectory(wxGetApp().GetAppDir()); + wxString htmlFile(wxGetApp().GetFullAppPath(wxT("about.htm"))); + + if (wxFileExists(htmlFile)) + { + wxFile file; + file.Open(htmlFile, wxFile::read); + long len = file.Length(); + char* buf = htmlText.GetWriteBuf(len + 1); + file.Read(buf, len); + buf[len] = 0; + htmlText.UngetWriteBuf(); + } } - else + + if (htmlText.IsEmpty()) { - htmlText.Printf(wxT("<html><head><title>Warning</title></head><body><P>Sorry, could not find file for About dialog, %s<P></body></html>"), (const wxChar*) htmlFile); + htmlText.Printf(wxT("<html><head><title>Warning</title></head><body><P>Sorry, could not find resource for About dialog<P></body></html>")); } // Customize the HTML
--- a/host/tools/configtool/standalone/wxwin/admindlg.cpp +++ b/host/tools/configtool/standalone/wxwin/admindlg.cpp @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/09/28 -// Version: $Id: admindlg.cpp,v 1.5 2001/08/10 14:58:21 julians Exp $ +// Version: $Id: admindlg.cpp,v 1.6 2001/08/22 16:50:32 julians Exp $ // Purpose: // Description: Implementation file for ecAdminDialog // Requires: @@ -245,7 +245,7 @@ void ecAdminDialog::OnAdd(wxCommandEvent wxString strCommand; strCommand.Printf(wxT("add %s --extract_license"), (const wxChar*) strPathName); strCommand.Replace(wxT("\\"), wxT("/")); // backslashes -> forward slashes for Tcl_EvalFile - EvalTclFile (3, strCommand); + EvalTclFile (3, strCommand, _("Adding package")); wxString strLicenseFile = m_strRepository + wxString(wxFILE_SEP_PATH) + wxT("pkgadd.txt"); #ifdef __WXMSW__ @@ -280,7 +280,7 @@ void ecAdminDialog::OnAdd(wxCommandEvent strCommand.Printf (wxT("add %s --accept_license"), (const wxChar*) strPathName); strCommand.Replace (wxT("\\"), wxT("/")); // backslashes -> forward slashes for Tcl_EvalFile - if (! EvalTclFile (3, strCommand)) // if not successful + if (! EvalTclFile (3, strCommand, _("Adding package"))) // if not successful { // try the next file } @@ -398,7 +398,7 @@ bool ecAdminDialog::RemovePackageVersion wxString strCommand; wxString itemText(treeCtrl->GetItemText (hTreeItem)); strCommand.Printf (wxT("remove %s --version %s"), (const wxChar*) pstrPackage, (const wxChar*) itemText); - if (! EvalTclFile (3, strCommand)) // if not successful + if (! EvalTclFile (3, strCommand, wxT("Removing package"))) // if not successful return false; treeCtrl->Delete (hTreeItem); // remove the selected item from the tree @@ -505,9 +505,9 @@ bool ecAdminDialog::PopulatePackageTree } -bool ecAdminDialog::EvalTclFile(int nargc, const wxString& Argv) +bool ecAdminDialog::EvalTclFile(int nargc, const wxString& Argv, const wxString& msg) { - wxProgressDialog dlgWait(_("Adding Package"), _("Please wait..."), 100, this); + wxProgressDialog dlgWait(msg, _("Please wait..."), 100, this); dlgWait.Update(50);
--- a/host/tools/configtool/standalone/wxwin/admindlg.h +++ b/host/tools/configtool/standalone/wxwin/admindlg.h @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/09/28 -// Version: $Id: admindlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $ +// Version: $Id: admindlg.h,v 1.3 2001/08/22 16:50:32 julians Exp $ // Purpose: // Description: Header file for ecAdminDialog // Requires: @@ -70,7 +70,7 @@ public: void CreateControls(wxWindow* parent); bool FindUserToolsPath(); bool RemovePackageVersion (wxTreeItemId hTreeItem); - bool EvalTclFile (int nargc, const wxString& argv); + bool EvalTclFile (int nargc, const wxString& argv, const wxString& msg); void ClearPackageTree (); bool PopulatePackageTree (const wxString& packageDatabase);
--- a/host/tools/configtool/standalone/wxwin/appsettings.cpp +++ b/host/tools/configtool/standalone/wxwin/appsettings.cpp @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/08/29 -// Version: $Id: appsettings.cpp,v 1.22 2001/06/26 17:26:35 julians Exp $ +// Version: $Id: appsettings.cpp,v 1.24 2001/09/05 14:35:53 julians Exp $ // Purpose: // Description: Implementation file for the ecSettings // Requires: @@ -90,7 +90,7 @@ ecSettings::ecSettings() m_showToolBar = TRUE; m_frameSize = wxRect(0, 0, 600, 500); m_appName = _("eCos Configuration Tool"); - m_showSplashScreen = FALSE; + m_showSplashScreen = TRUE; m_userName = wxEmptyString; m_serialNumber = 0; m_frameStatus = ecSHOW_STATUS_NORMAL; @@ -101,6 +101,7 @@ ecSettings::ecSettings() m_shortDescrSashSize = wxSize(1000, 80); m_memorySashSize = wxSize(1000, 50); m_outputSashSize = wxSize(1000, 50); + m_configPaneWidth = 200; m_showConflictsWindow = FALSE; m_showPropertiesWindow = TRUE; @@ -127,6 +128,8 @@ ecSettings::ecSettings() m_findDirection = TRUE; // Down is TRUE, Up is FALSE m_findSearchWhat = _("Macro names"); // Macro names, item names etc. m_findDialogPos = wxPoint(-1, -1); + + m_editSaveFileOnly = FALSE; } // Copy constructor @@ -148,7 +151,7 @@ void ecSettings::Copy(const ecSettings& m_propertiesSashSize = settings.m_propertiesSashSize; m_memorySashSize = settings.m_memorySashSize; m_outputSashSize = settings.m_outputSashSize; - + m_configPaneWidth = settings.m_configPaneWidth; m_showMacroNames = settings.m_showMacroNames; m_bUseCustomViewer = settings.m_bUseCustomViewer; @@ -170,6 +173,8 @@ void ecSettings::Copy(const ecSettings& m_userToolsDir = settings.m_userToolsDir; m_buildToolsDir = settings.m_buildToolsDir; + + m_editSaveFileOnly = settings.m_editSaveFileOnly; } ecSettings::~ecSettings() @@ -245,6 +250,7 @@ bool ecSettings::LoadConfig() config.Read(_("/Window Size/TreeSashWidth"), & m_treeSashSize.x); config.Read(_("/Window Size/TreeSashHeight"), & m_treeSashSize.y); + config.Read(_("/Window Size/ConfigPaneWidth"), & m_configPaneWidth); config.Read(_("/Window Size/ConflictsWidth"), & m_conflictsSashSize.x); config.Read(_("/Window Size/ConflictsHeight"), & m_conflictsSashSize.y); config.Read(_("/Window Size/PropertiesWidth"), & m_propertiesSashSize.x); @@ -554,6 +560,7 @@ bool ecSettings::SaveConfig() config.Write(_("/Window Size/WindowHeight"), (long) m_frameSize.height); config.Write(_("/Window Size/TreeSashWidth"), (long) m_treeSashSize.x); config.Write(_("/Window Size/TreeSashHeight"), (long) m_treeSashSize.y); + config.Write(_("/Window Size/ConfigPaneWidth"), (long) m_configPaneWidth); config.Write(_("/Window Size/ConflictsWidth"), (long) m_conflictsSashSize.x); config.Write(_("/Window Size/ConflictsHeight"), (long) m_conflictsSashSize.y); config.Write(_("/Window Size/PropertiesWidth"), (long) m_propertiesSashSize.x);
--- a/host/tools/configtool/standalone/wxwin/appsettings.h +++ b/host/tools/configtool/standalone/wxwin/appsettings.h @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/08/29 -// Version: $Id: appsettings.h,v 1.9 2001/06/26 17:26:35 julians Exp $ +// Version: $Id: appsettings.h,v 1.10 2001/08/22 16:50:32 julians Exp $ // Purpose: // Description: Header file for the ConfigTool application settings // Requires: @@ -192,6 +192,7 @@ public: wxSize m_shortDescrSashSize; wxSize m_memorySashSize; wxSize m_outputSashSize; + int m_configPaneWidth; // The sash to the right of the tree bool m_showConflictsWindow; bool m_showPropertiesWindow; bool m_showShortDescrWindow; @@ -201,6 +202,10 @@ public: // Are we showing macro names, or ordinary names? bool m_showMacroNames ; + // Are we merely editing the .ecc file and not saving build trees? + // This option is specified on the command line and not saved. + bool m_editSaveFileOnly; + // Viewers & browsers bool m_bUseCustomViewer; bool m_bUseExternalBrowser;
index 901e793fd4b3f8adb2c33577ab75b0bc57129d15..7351f93a5be6debeb0c3cac487e32ffe300cdca1 GIT binary patch literal 4550 zc$}qFcQhLgyADYuF=N&!5~TK4vn65^rA154(pFJhZA!$Z)K*$sjoPD1idbJ&6|E5= zrL{-xJ#T;K`|I9w?;qc}&pGdT&hxzQfA90YvBtM`=%_iV0RRA<p04Iy0Duw#08prc zfPWoMj{T6o1oqK0)B=w{uh7X-%knI<{I#GSx)$C50KLyYMd2dQF#gw+GRBx{{bgEO z_G~22rWPNw^n=?LuH{j$z7I|w20c2=PdWeEb-A{-xp}#JczStwczJnA&gI4f0F1(V zn(C(hq(5&4-MRk7+8JFd#7(kqih0cayYLcA$MXz$r2-(j0^>>n=(h@F(CN+>_#z1@ z#C(1KtpW%vAIzIVNp&V!jC#$JqAkTVA&<I$>u4^S*ebVDpx1<YCKIJ)ID<c)Mhf?* z&5zyPB(P=5HpuRV?k*1ISj5>U;QkwmL;5jkN;QLf*U3o&C6!h=P%QeRe6o*G%A?vC z`Q+@IcovxkniH><*FKIZDZju6Cx4EMgHjWGZgJX)W$t=^Ox-G#tF=B(*gVxc3>aFt zMtkw<8brklTX*4VSWqK3C)?4$mVzn2&rbOnN`WvTZA7g<IJbYtp)nLv3WqoVx?5@o z=|WtBze)BWil=0>sX(CdAWikps^rC}b<Vt@n>_K(f8GU!<{vMaYkz~hsg2A>PIJX0 zOO;7I;X}(SaCpAc)9uK;I97Gx?Cn$B-=>KhBH}po#f?Fm!X-+$VmTt0Mc7-KD%4%O zFj+*@VCxm-;t|K?zNrQ~2f)!|CuWYL?b^Fx1=Yo?SJk)q-p8W|c|xpd$ZO&;EHimR zfTW_D`$<$QZ(y0y+IBi(phZyf`DGAssAKo^=K@}pq2V`CWX1|)0Dxp3F~q|pS@NE# za_(k!l)VU5aWW%iGOf-G$VD+T4iUR6ABSzRfy<9;e_$t0l=B=9udkIH+9d2hnJ_3B z15<W6CZ*gf2`QKPB+qFnM4Aq@nLBGMayjd;quI?4{iZMx4m9t&x+~TuGjzgcQF^Jh zITD&huUGlK83N81>&)tk8Qh>q?6`1ItFZ;~AC2cN1UuQA&6+b#4eri-;XYc`8aFYl z(Lq7<PbV6M6<q{qL&PupSiV9o6~9Ka+Bk4zad}_FnWIl!Xs;&kTsyUReK^~~GSBxL z4KN6!Gs_-2y^y{rOxo?(t9NU}#V1c$cSE}J-hd&(A8<mE%y$fk*B)oHwwnsE1e~)I z!(OuMAP$K%Qn(`KE48?{qn20;I2U|x>xApQOJdRJLoX}SATVuCo9*6{lZ-rw+{y=B zwN8yv1L1kXEEBkAm<v)QZLlRdVG!AP3Ob;@@ar~KZi^m}zi-(!k*5}VcEpHckAHxj zu?0^7@{(7_!o>-f)lH<38^|7d5hlSfq}1@q^3jn$PjFXc8S-d}HztDAXo;??G`^-7 z-MT8<pp_G!0jTUYBx>x}i)9Yr9H0vUbcn$WDVd(*bBS-fR2n~+BPb)=!c#J&Xb_Zc z*C!O8vCVYF+_9iUeU4EqP#c43Vm=#K#p<rS_4bZLUW-O~2IKu1G4>|f378uC$5M$! zF7~mQ-I2Q=#`DyyMB*XIi3ubtCn&kr*8hwhzhpsFdB6SK1)4nxZl7ULy456?C-`Vw z4tM3A_U7V|)<Y;D+`5nQl8FY`GXg`^3w~j;naRrbzk8AOSi$joaHsrZOhHdxeQZ}k z&@idv_)}PN<Sl_qis0FK<r>K|w~&|T*5>E~wc6C_d4?C;bsle<if>Ft?s<q7@hSRP zQ4X+CE4EMCm&*ZbvhAIqsKk1#-H$7J8YLwoZZWJc(=$@WA6@<acoA3=tC1QQSJfKA zAr0HOynCkGsurs|jxwh#Lh1NJ7INoU>B|vP0l^jIu7W)Xy1q|gT*uGW^1(t@eI$vv zv8G?+!#W~OFF;NzmIe_X>Y&j7z$<2cc!N^+ACNM?7hDbNWcUOFVNoy$r8*n}3Wxv4 zf}8eX1DR_gHPR#K2|gWzKG>c1-3iqiGkqf_vC$!M3V7%c7;i-I-Grbe{H)F7Z>W+t zVy-(uxhya0_iiJeQk$g8p4JTf)M)v9076$MG^J-6sBGNDFg4;VpC!R_EyypB2hgs* zP8)S8w*qUuZ%pm>K~%rKUWnEi!J1F0V>83@@#v|PETp2XAo0c>p?SY6za~y=dfQPg zPK|FgJDOR}$G#BI(v-iHSx7Bw%OQaQO*^*(tsJ}|PvkKbpu^KEZ4&)*z=sy?9o&|T z^3`P@R&cci`?sE?tfyoP?+StDF6ge5G?jYrJ0YjA#))eK+iSWd_!1KqoQZFKM}ktg zi?AoPA!4~^MrEydrDnXrc3>Y*ICj@G8J(IgFHV0(gC;(O^s$uM!}vH0g>!8ZS;BC| z>C<$$x4OS&S6E%UcKgCSy3Jpd)K@s_NMtsqw1rC{t1qQ1#$)KL;4dA*zvz5qxSwY! z=zmIDS@ZWaR4*eO-LHNQz$F+PgkIrN2In#~d<HHNtYx{jR)L;Ks!N5{eM~hFKC3YC z&0^ETBw{jI<E;H2c{|#U;-i|Un<JWpILn>7p`L{{i}0LVs2@8@`|Vkj3XhRo9c}A( zy8;R+sVsnG)hJ7UH~YJ+31tvA>*B+{WJdfW4~CB4zQ+@lwuT)aDcq}d^Ewq&S7{*& z{ySw>QdW@PwX=eLZAT?gn7i#CUC7nq=PeTILT3)NSo%DX`zipmh8GRQw)M$&QG*M9 ziU13prtbouM2Wtk`StD(d>Kd;DtHe2;?cCM8pK6>qMZ93<|Pv)FCpiI^n()4mHj@w zA-X;9Eb;!R0gt)U!4V<#9fXZ#=G&IJtE+|+=27yMFKFEMQ??(Sc<e@>Iyx7%r-6zb zdsXQH4fy2O!W@}jkZX}>uIGqCMY>PUrN2ADXt}a^R0c=n9D7*Xw*OFv%_CC$mEVZR zS1K`U+q3wbRQpDKXPgZewK1zMTN$Q!d50%|t7IEGn#(|JxIcV}S@`%C7(93QahliD z438Bp@$Z;Mz+UPwRn~PsVU<iH%N!((2)}ZJSijQI@vaUqXXR&L-O#LC&PV(csQf$? zjFQvI<}D)s@{(_eF<;W%dqwU)PNvm$z!o}$<9kN=*GyU*@SwP#TBW<tv;a0IUiHbc z{xc=mt+~uWSLfONBHfU;|4ygfTYbkyu!q_}hV@IdVwGyu({HRprhM)uC#EDfj!}oB z2Yaca%)Kc<^*<Tw4H;G&L#(IUxY1Bm!lVo)?VdqAuufd_ELFr&6~D&wUVEXl4aXAv zL|6$DbiC38RO7n4rPMbM9~OLY=is1W5Nt`TJWe|$upKyu&it~Y2|{)pdv!*RNMafP zUq9vFBDwK@I>S6Tosz??efN^|Dz_J=frpPDv{{R|r@L|m^#>k;yX;}0Or@Icwfy`# z7;R;q5dv(pLtqgQBkUJ{tEQr;QSZt>nqx>7(6?K$V^0~VA14fCDfDQ)Ei;*>l9`vg zzIHCo#-UG-Hgk>>!xCgF8cC2}h=WTnTFTNbr}uEmUu^BKn$o!tS$(FT8lW0k8L#!z zHEj!~mbl=fb>>nnY|-#2v-TF4&HNkEH+fWTVtHV6N+kS5_7(499?FPX-(Z9r`mokm zh!3=UVTX{6`WgwpJ3ebK#GZimhsPBOqg*5CV9y+ye+nR`8L$R;c_@{1<Mjmdr@|^~ z@7pBc`DPPXdmrVP37IqYZ$-RE`j5uu$#!cDzyN+{MX{VpYJrhH%};jXdT8@bn-HpV zf35^s-rR_^n^ymVW9Alk{b?zkgVhv2z@Icl)^dQ{3#+>eLoHLWvvTrP_$}i?*dxi7 zofR75ALw#9PRbO!V1h~(1-VmGK!UN8RA_Ny<0xFH-2olU)FG#(ddo5SwE!+yicbZc zYKfsA`J+&f+9&;%6|jn~G@^mufiU#A{!l;W5LrPBiIUlRtg;i)wTYjS8#U4Ouu>M# z_6`doAuK=>@l1#pTw(>8>*@yPr;9klqK(sGv$jCcSe6JxvJyPVq-_VuF-P;`P_0es zo}YexXUgBYFD_Q#D<$@j(>lv%mn4|b*~yi+CBYfLy#D*B#fy!tE1*Cmt!rvdRh^If z=U1?-C#0h8gs=sbd4FDdJt#Fg91Lke_uPy2F6)8?s;oaZOks*|r#_*@DYw38QjTGN zB(=f*+yU(HyhW1FHimh}ekD|>Dil=o+B{dPn08@CCLawMDz?>BTIz%TC^R-?|ALLv z=J&)-WhF5G#IRtEKO|q}XTyl8FE?Xhc63STF#Fzpqh5$A^A)r8_$PS^(zTI*%D&_> zLn>=$?}rFtUj?6UZpOALyrTn20m(5upyz)&#|U{|vKlAh&zAYwi8eJ;G~LqvnmEWz zH*yB62f{Y^CGTS&mL=-*!RF;}Z}{xByMx*|!t<LW?TbqXD_}AGd%~?JuaBG%pIr;z zyPA(J{>|hh*{Kj#+mYGhCtjW?jYcIcpovy#Kq}4!Wa8_WtWhm@$>DH%+O4e4x3^nh z7>D`*g1iL;FOcNBiVW!5Gt>%>Bps%|*h&0yE4%i3eEL@Ugg$b6ENx$3>rAgPPRukM zZ64ZC81GP3$W!gYq|i@8X20r)*%_kDs$dHDD8u~+FQAqermI^l;F{1+^M6er(4mR9 zfj<Z4qa;0D#4I};#6?{2<V76>?i&}IQ;)ZE`Uih=&1r-INufX-*L(Aw+U=_0#-$bC zTjb5*)wy2M3=~&u_Lz|js>p!dTzadWQh(3Pd-)-wkttin&MKXEWjzdkw1vAp(QV$L z@$(B4hE5zIS0(nK9SJIpGN!-!b3N8T=ug0JYI7NUPQQdU+~f56C=6qkyx31c%{>Jz zA^X?Q6f_E~e{j|{>#SA2-mh_+{Wa|}^*Df=wr=yQ%bn~BG$~@$nIC6-z49t<Hgc7> zAv1Y(#nYbF)#yT_NgVVl`a_vK+7(*hq&g~YC%(wEMonJ4CF|yue@lTOHEWr5rb0#{ zXlc6&Aw{QNkhE7Q461JB<ec*rBc$GNHn6LL!wX>L0VJ#iKWIJensp=m72?I0)@+W> z#dIyWRQgO0(=(-^y>X4LJCH!-EH9D|9}KPZj2bK8guqc@-|0l<ghm^Rg-=m7yG(N+ zU7&^{@xn_=8jQQpFP|y{_}^95c|-HoVoT$`Si}WNmA+HiZ8X|?Zxm)VG}p>DgdQ&9 zl5ym8&|u7iIUCH1jaIc}<OidPc$r+z(sef2>o`Ypo#W;&S3OJ5KHrfp8`FAk2vjSh zrqF^q2Z}a<_>uw*O)Qa{nqBuc(Mg*lqejx8p?lNRy%&6OD9BVqZ8!PnJs4hGbkbck zcAXn8mKlz<ibe2z*lv!c#Jsfe*AVPXeuZzRa0vc9-dm?UhJM-%Y$*+r5!=@M(W+>Y z9?R(iujEr88#W6D+XsPJ!~4VHCu0)41^wgKkv_pITKqThgjoOXW$uFEans5or7^h% zx?Zo3q`{T?KUzF0;dVg38$=oQ_`M<ykQr8bWrh89tju!@Mw3-(j)Y3%;j(gIpwU=C z3N45&Jd8Y@Q&N?U^Z*jbWv*btjfi2>e+_PYkAGlLcEGz~zD6$kX+$)h`N0(u;8>g! z1f>8z=OW6ggn7jU1+ooXGwNOPs!+**3pU`@2Ls=|ZvuVdPCgYe>fK*0#+H-A-8yp( zW17)FtUi+xdM(k!a(q4OdHM}a7%5^n0R6w;8lDBj#Dus6H`AB5@2~bU1O7r!>$YY! H+7A0)^8+%5
--- a/host/tools/configtool/standalone/wxwin/configtool.cpp +++ b/host/tools/configtool/standalone/wxwin/configtool.cpp @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/08/24 -// Version: $Id: configtool.cpp,v 1.40 2001/07/16 14:02:56 julians Exp $ +// Version: $Id: configtool.cpp,v 1.46 2001/09/05 14:35:53 julians Exp $ // Purpose: // Description: Implementation file for the ConfigTool application class // Requires: @@ -74,6 +74,8 @@ #include "wx/process.h" #include "wx/mimetype.h" #include "wx/txtstrm.h" +#include "wx/wfstream.h" +#include "wx/fs_mem.h" #include "configtool.h" #include "configtoolview.h" @@ -85,6 +87,7 @@ #include "shortdescrwin.h" #include "conflictwin.h" #include "propertywin.h" +#include "symbols.h" // ---------------------------------------------------------------------------- // resources @@ -115,6 +118,9 @@ static const wxCmdLineEntryDesc sg_cmdLi { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER }, { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE }, */ + { wxCMD_LINE_SWITCH, "h", "help", "displays help on the command line parameters" }, + { wxCMD_LINE_SWITCH, "e", "edit-only", "edit save file only" }, + { wxCMD_LINE_SWITCH, "v", "version", "print version" }, { wxCMD_LINE_PARAM, NULL, NULL, "input file 1", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_PARAM, NULL, NULL, "input file 2", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, @@ -134,11 +140,16 @@ ecApp::ecApp() m_pipedProcess = NULL; m_valuesLocked = 0; m_helpController = NULL; + m_fileSystem = new wxFileSystem; +#if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB + m_zipHandler = new wxZipFSHandler; +#endif } ecApp::~ecApp() { delete m_whatsThisMenu; + delete m_fileSystem; } // 'Main program' equivalent: the program execution "starts" here @@ -157,7 +168,7 @@ bool ecApp::OnInit() // Required for advanced HTML help #if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB - wxFileSystem::AddHandler(new wxZipFSHandler); + wxFileSystem::AddHandler(m_zipHandler); #endif wxString currentDir = wxGetCwd(); @@ -175,6 +186,10 @@ bool ecApp::OnInit() m_appDir = wxPathOnly(m_appDir); #endif + // Load resources from binary resources archive, or failing that, from + // Windows resources or plain files + LoadResources(); + wxGetEnv(wxT("PATH"), & m_strOriginalPath); // Create a document manager @@ -203,6 +218,33 @@ bool ecApp::OnInit() if (!m_settings.m_lastFilename.IsEmpty()) templ->SetDirectory(wxPathOnly(m_settings.m_lastFilename)); + // Parse the command-line parameters and options + wxCmdLineParser parser(sg_cmdLineDesc, argc, argv); + int res; + { + wxLogNull log; + res = parser.Parse(); + } + if (res == -1 || res > 0 || parser.Found(wxT("h"))) + { +#ifdef __WXGTK__ + wxLog::SetActiveTarget(new wxLogStderr); +#endif + parser.Usage(); + return FALSE; + } + if (parser.Found(wxT("v"))) + { +#ifdef __WXGTK__ + wxLog::SetActiveTarget(new wxLogStderr); +#endif + wxString msg; + msg.Printf(wxT("eCos Configuration Tool (c) Red Hat, 2001 Version %.2f, %s"), ecCONFIGURATION_TOOL_VERSION, __DATE__); + wxLogMessage(msg); + return FALSE; + } + +/* #ifdef __WXMSW__ wxBitmap bitmap(wxBITMAP(splash)); #else @@ -210,9 +252,11 @@ bool ecApp::OnInit() if (wxFileExists("splash16.png")) bitmap.LoadFile("splash16.png", wxBITMAP_TYPE_PNG); #endif - if (bitmap.Ok() && GetSettings().m_showSplashScreen) +*/ + + if (m_splashScreenBitmap.Ok() && GetSettings().m_showSplashScreen) { - m_splashScreen = new ecSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT, + m_splashScreen = new ecSplashScreen(m_splashScreenBitmap, wxSPLASH_CENTRE_ON_SCREEN|wxSPLASH_TIMEOUT, 6000, NULL, -1, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxFRAME_FLOAT_ON_PARENT|wxSTAY_ON_TOP); } @@ -227,6 +271,9 @@ bool ecApp::OnInit() SetTopWindow(frame); frame->Show(TRUE); SendIdleEvents(); // Otherwise UI updates aren't done, because it's busy loading the repository +#ifdef __WXMSW__ + ::UpdateWindow((HWND) frame->GetHWND()); +#endif InitializeWindowSettings(FALSE /* beforeWindowConstruction */) ; @@ -235,14 +282,9 @@ bool ecApp::OnInit() wxYieldIfNeeded(); - // Parse the command-line parameters and options - wxCmdLineParser parser(sg_cmdLineDesc, argc, argv); - int res = parser.Parse(); - if (res == -1 || res > 0) - { - parser.Usage(); - return FALSE; - } + if (parser.Found(wxT("e"))) + GetSettings().m_editSaveFileOnly = TRUE; + wxString filenameToOpen1, filenameToOpen2; if (parser.GetParamCount() > 0) { @@ -427,6 +469,153 @@ bool ecApp::OnInit() return TRUE; } +// Load resources from disk +bool ecApp::LoadResources() +{ + wxFileSystem::AddHandler(new wxMemoryFSHandler); + + LoadBitmapResource(m_splashScreenBitmap, wxT("splash16.png"), wxBITMAP_TYPE_PNG, FALSE); + + wxBitmap bitmap1, bitmap2, bitmap3; + LoadBitmapResource(bitmap1, wxT("ecoslogo.png"), wxBITMAP_TYPE_PNG, TRUE); + LoadBitmapResource(bitmap2, wxT("ecoslogosmall.png"), wxBITMAP_TYPE_PNG, TRUE); + LoadBitmapResource(bitmap3, wxT("rhlogo.png"), wxBITMAP_TYPE_PNG, TRUE); + + wxString aboutText; + LoadTextResource(aboutText, wxT("about.htm"), TRUE); + + VersionStampSplashScreen(); + + return TRUE; +} + +// Load resources from zip resource file or disk +bool ecApp::LoadBitmapResource(wxBitmap& bitmap, const wxString& filename, int bitmapType, bool addToMemoryFS) +{ + wxString archive(GetFullAppPath(wxT("configtool.bin"))); + +#if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB + wxFSFile* file = m_fileSystem->OpenFile(archive + wxString(wxT("#zip:")) + filename); + if (file) + { + wxInputStream* stream = file->GetStream(); + + wxImage image(* stream, bitmapType); + bitmap = image.ConvertToBitmap(); + + delete file; + } +#endif + +#ifdef __WXMSW__ + if (!bitmap.Ok()) + bitmap.LoadFile(filename, wxBITMAP_TYPE_BMP_RESOURCE); +#endif + + if (!bitmap.Ok() && wxFileExists(GetFullAppPath(filename))) + bitmap.LoadFile(GetFullAppPath(filename), bitmapType); + + + if (bitmap.Ok() && addToMemoryFS) + wxMemoryFSHandler::AddFile(filename, bitmap, bitmapType); + + return bitmap.Ok(); +} + +// Load resources from zip resource file or disk +bool ecApp::LoadTextResource(wxString& text, const wxString& filename, bool addToMemoryFS) +{ + wxString archive(GetFullAppPath(wxT("configtool.bin"))); + + bool success = FALSE; + +#if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB + wxFSFile* file = m_fileSystem->OpenFile(archive + wxString(wxT("#zip:")) + filename); + if (file) + { + wxInputStream* stream = file->GetStream(); + + char* buf = text.GetWriteBuf(stream->GetSize() + 1); + stream->Read((void*) buf, stream->GetSize()); + buf[stream->GetSize()] = 0; + text.UngetWriteBuf(); + + success = TRUE; + + delete file; + } +#endif + + if (!success && wxFileExists(GetFullAppPath(filename))) + { + wxFileInputStream str(GetFullAppPath(filename)); + + char* buf = text.GetWriteBuf(str.GetSize() + 1); + str.Read((void*) buf, str.GetSize()); + buf[str.GetSize()] = 0; + text.UngetWriteBuf(); + + success = TRUE; + } + + if (success && addToMemoryFS) + wxMemoryFSHandler::AddFile(filename, text); + + return success; +} + +// Get a text resource from the memory filesystem +bool ecApp::GetMemoryTextResource(const wxString& filename, wxString& text) +{ + wxString s(wxString(wxT("memory:")) + filename); + wxFSFile* file = wxGetApp().GetFileSystem()->OpenFile(s); + if (file) + { + wxInputStream* stream = file->GetStream(); + + char* buf = text.GetWriteBuf(stream->GetSize() + 1); + stream->Read((void*) buf, stream->GetSize()); + buf[stream->GetSize()] = 0; + text.UngetWriteBuf(); + + delete file; + return TRUE; + } + else + return FALSE; +} + +// Version-stamp the splash screen +bool ecApp::VersionStampSplashScreen() +{ + if (m_splashScreenBitmap.Ok()) + { + wxMemoryDC dc; + dc.SelectObject(m_splashScreenBitmap); + + wxColour textColour(19, 49, 4); + dc.SetTextForeground(textColour); + dc.SetBackgroundMode(wxTRANSPARENT); + dc.SetFont(wxFont(11, wxSWISS, wxNORMAL, wxBOLD, FALSE)); + + // Bottom left of area to start drawing at + + wxString verString; + verString.Printf("%.2f", ecCONFIGURATION_TOOL_VERSION); + + int x = 339; int y = 236; + int w, h; + dc.GetTextExtent(verString, & w, & h); + dc.DrawText(verString, x, y - h); + + dc.SelectObject(wxNullBitmap); + + return TRUE; + } + else + return FALSE; +} + // Initialize window settings object bool ecApp::InitializeWindowSettings(bool beforeWindowConstruction) { @@ -628,7 +817,8 @@ void ecApp::SetStatusText(const wxString if (clearFailingRulesPane) mainFrame->GetStatusBar()->SetStatusText(wxT(""), ecFailRulePane); #ifdef __WXMSW__ - wxYield(); + ::UpdateWindow((HWND) mainFrame->GetHWND()); + //wxYield(); #endif } }
--- a/host/tools/configtool/standalone/wxwin/configtool.h +++ b/host/tools/configtool/standalone/wxwin/configtool.h @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/08/24 -// Version: $Id: configtool.h,v 1.25 2001/08/10 14:58:21 julians Exp $ +// Version: $Id: configtool.h,v 1.26 2001/09/05 14:35:53 julians Exp $ // Purpose: // Description: main header file for the ConfigTool application // Requires: @@ -99,6 +99,9 @@ class ecPipedProcess; #define ecUSE_EXPERIMENTAL_CODE 1 #endif +class WXDLLEXPORT wxZipFSHandler; +class WXDLLEXPORT wxFileSystem; + // Define a new application type, each program should derive a class from wxApp class ecApp : public wxApp { @@ -138,6 +141,21 @@ public: // Initialize window settings object bool InitializeWindowSettings(bool beforeWindowConstruction); + // Load resources from disk + bool LoadResources(); + + // Load a bitmap resource from resource.bin + bool LoadBitmapResource(wxBitmap& bitmap, const wxString& filename, int bitmapType, bool addToMemoryFS); + + // Load a text resource from resource.bin + bool LoadTextResource(wxString& text, const wxString& filename, bool addToMemoryFS); + + // Get a text resource from the memory filesystem + bool GetMemoryTextResource(const wxString& filename, wxString& text); + + // Version-stamp the splash screen + bool VersionStampSplashScreen(); + //// Accessors // Get settings @@ -182,6 +200,8 @@ public: wxString GetHelpFile() const { return m_helpFile; } void SetHelpFile(const wxString& file) { m_helpFile = file; } + wxFileSystem* GetFileSystem() const { return m_fileSystem; } + // Lock out value changes while conflicts are being resolved, for example bool GetValuesLocked() { return (m_valuesLocked > 0); } void LockValues() { m_valuesLocked ++; } @@ -210,6 +230,9 @@ public: ecConfigToolDoc* m_currentDoc; wxString m_helpFile; ecPipedProcess* m_pipedProcess; + wxBitmap m_splashScreenBitmap; + wxZipFSHandler* m_zipHandler; + wxFileSystem* m_fileSystem; DECLARE_EVENT_TABLE() };
--- a/host/tools/configtool/standalone/wxwin/configtooldoc.cpp +++ b/host/tools/configtool/standalone/wxwin/configtooldoc.cpp @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/10/05 -// Version: $Id: configtooldoc.cpp,v 1.36 2001/08/10 14:58:21 julians Exp $ +// Version: $Id: configtooldoc.cpp,v 1.41 2001/09/03 17:18:18 julians Exp $ // Purpose: // Description: Implementation file for the ecConfigToolDoc class // Requires: @@ -294,22 +294,28 @@ bool ecConfigToolDoc::OnSaveDocument(con ecFileName buildFilename(m_strBuildTree); ecFileName installFilename(m_strInstallTree); - if (!buildFilename.CreateDirectory() || !installFilename.CreateDirectory()) + if (!wxGetApp().GetSettings().m_editSaveFileOnly) { - wxString msg; - msg.Printf(_("Failed to save %s"), (const wxChar*) filename); - - wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION); - rc = FALSE; + if (!buildFilename.CreateDirectory() || !installFilename.CreateDirectory()) + { + wxString msg; + msg.Printf(_("Failed to save %s"), (const wxChar*) filename); + + wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION); + rc = FALSE; + } + else if (GenerateHeaders() && CopyMLTFiles()) + { + // in each case errors already emitted + // copy new MLT files to the build tree as necessary + rc=generate_build_tree (GetCdlConfig(), ecUtils::UnicodeToStdStr(m_strBuildTree), ecUtils::UnicodeToStdStr(m_strInstallTree)); + rc = TRUE; + } } - else if (GenerateHeaders() && CopyMLTFiles()) + else { - // in each case errors already emitted - // copy new MLT files to the build tree as necessary - rc=generate_build_tree (GetCdlConfig(), ecUtils::UnicodeToStdStr(m_strBuildTree), ecUtils::UnicodeToStdStr(m_strInstallTree)); rc = TRUE; } - } } if(rc) @@ -440,11 +446,12 @@ bool ecConfigToolDoc::OnOpenDocument(con UpdateFailingRuleCount(); - UpdateBuildInfo(); + SetFilename(filename); + + // UpdateBuildInfo(); // Don't create directories on opening file rc = TRUE; - SetFilename(filename); ecConfigToolHint hint(NULL, ecFilenameChanged); UpdateAllViews (NULL, & hint); @@ -722,7 +729,8 @@ bool ecConfigToolDoc::OpenRepository(con } #ifdef __WXMSW__ // Ensure display gets updated - wxYield(); + ::UpdateWindow((HWND) mainFrame->GetHWND()); + //wxYield(); #endif strNewRepository=dlg.GetFolder(); } else @@ -1010,7 +1018,9 @@ void ecConfigToolDoc::RegenerateData() SwitchMemoryLayout (TRUE); // the hardware template may have changed #endif - UpdateBuildInfo(); + if (GetDocumentSaved() && !wxGetApp().GetSettings().m_editSaveFileOnly) + UpdateBuildInfo(); + // TODO // CConfigTool::GetControlView()->SelectItem(Item(0)); } @@ -1379,7 +1389,12 @@ bool ecConfigToolDoc::ShowExternalHtmlHe if (strURL.Left(7) == wxT("http://") || strURL.Left(7) == wxT("file://")) url = strURL; else - url = docDir + sep + strURL; + { + if (wxIsAbsolutePath(strURL)) + url = strURL; + else + url = docDir + sep + strURL; + } wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(wxT("html")); if ( !ft )
--- a/host/tools/configtool/standalone/wxwin/ecutils.cpp +++ b/host/tools/configtool/standalone/wxwin/ecutils.cpp @@ -524,11 +524,9 @@ bool ecUtils::CopyFile(LPCTSTR pszSource if(rc){ // Files are identical - TRACE(wxT("Copy not necessary: '%s' to '%s'\n"),pszSource,pszDest); } else { rc=TRUE==::CopyFile(pszSource,pszDest,FALSE); if(rc){ - TRACE(wxT("Copied '%s' to '%s'\n"),pszSource,pszDest); } else { MessageBoxF(wxT("Failed to copy '%s' to '%s' - %s"),pszSource,pszDest,GetLastErrorMessageString()); } @@ -1010,205 +1008,6 @@ bool wxWindowSettings::ApplyFontsToWindo return TRUE; } -#if TODO - -#ifdef _WIN32 -class wxProcessInfo: public wxObject -{ -public: - wxProcessInfo() {} - - wxProcessInfo *pParent; -#ifdef _WIN32 - __int64 tCreation; -#endif - Time tCpu; - int PID; - int PPID; - bool IsChildOf(int pid) const; -}; - -void wxSetProcessInfoParents(CSubprocess::PInfoArray &arPinfo) -{ - int i; - for(i=0;i<(signed)arPinfo.size();i++){ - PInfo &p=arPinfo[i]; - p.pParent=0; - for(int j=0;j<(signed)arPinfo.size();j++){ - if(arPinfo[j].PID==p.PPID -#ifdef _WIN32 - && arPinfo[j].tCreation<p.tCreation -#endif - ) - { - arPinfo[i].pParent=&arPinfo[j]; - break; - } - } - } - - // Check for circularity - bool bCircularity=false; - for(i=0;i<(signed)arPinfo.size();i++){ - PInfo *p=&arPinfo[i]; - for(int j=0;j<(signed)arPinfo.size() && p;j++){ - p=p->pParent; - } - // If all is well, p should be NULL here. Otherwise we have a loop. - if(p){ - // Make sure it can't foul things up: - arPinfo[i].pParent=0; - bCircularity=true; - } - } - - if(bCircularity){ - ERROR(_T("!!! Circularly linked process list at index %d\n"),i); - for(int k=0;k<(signed)arPinfo.size();k++){ - const PInfo &p=arPinfo[k]; - ERROR(_T("%d: %s ppid=%4d\n"),k,(LPCTSTR)Name(p.PID),p.PPID); - } - } -} - -bool CSubprocess::PInfo::IsChildOf(int pid) const -{ - for(PInfo *p=pParent;p && p!=this;p=p->pParent) { // guard against circular linkage - if(p->PID==pid){ - return true; - } - } - return false; -} - - -bool wxGetChildProcesses(wxList& children) -{ - int osVersion = wxGetOsVersion() ; - HINSTANCE hInstLib1 = wxWINDOWS_NT==osVersion ? LoadLibrary(_T("PSAPI.DLL")):LoadLibrary(_T("Kernel32.DLL")) ; - HINSTANCE hInstLib2 = wxWINDOWS_NT==osVersion ? LoadLibrary(_T("NTDLL.DLL")):NULL; - - bool rc=false; - children.Clear(); - // If Windows NT: - switch (osVersion) - { - case wxWINDOWS_NT: - if(hInstLib1) - { - - // Get procedure addresses. - static BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ) = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))GetProcAddress( hInstLib1, "EnumProcesses" ) ; - if (lpfEnumProcesses) - { - - if (hInstLib2) - { - - static DWORD (WINAPI *lpfNtQueryInformationProcess)( HANDLE, int, void *, DWORD, LPDWORD ) = - (DWORD(WINAPI *)(HANDLE, int, void *, DWORD, LPDWORD)) GetProcAddress( hInstLib2,"NtQueryInformationProcess" ) ; - - if(lpfNtQueryInformationProcess) - { - DWORD dwMaxPids=256; - DWORD dwPidSize; - DWORD *arPids = NULL ; - do { - delete [] arPids; - arPids=new DWORD[dwMaxPids]; - } while(lpfEnumProcesses(arPids, dwMaxPids, &dwPidSize) && dwPidSize/sizeof(DWORD)==dwMaxPids) ; - - if(dwPidSize/sizeof(DWORD)<dwMaxPids) - { - rc=true; - for ( DWORD dwIndex = 0 ; (signed)dwIndex < dwPidSize/sizeof(DWORD); dwIndex++ ) { - // Regardless of OpenProcess success or failure, we - // still call the enum func with the ProcID. - DWORD pid=arPids[dwIndex]; - HANDLE hProcess=::OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pid ); - if (hProcess ) { - struct { - DWORD ExitStatus; // receives process termination status - DWORD PebBaseAddress; // receives process environment block address - DWORD AffinityMask; // receives process affinity mask - DWORD BasePriority; // receives process priority class - ULONG UniqueProcessId; // receives process identifier - ULONG InheritedFromUniqueProcessId; // receives parent process identifier - } pbi; - memset( &pbi, 0, sizeof(pbi)); - DWORD retLen; - __int64 ftCreation,ftExit,ftKernel,ftUser; - if(lpfNtQueryInformationProcess(hProcess, 0 /*ProcessBasicInformation*/, &pbi, sizeof(pbi), &retLen)>=0 && - TRUE==::GetProcessTimes (hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){ - // The second test is important. It excludes orphaned processes who appear to have been adopted by virtue of a new - // process having been created with the same ID as their original parent. - wxProcessInfo* p = new wxProcessInfo; - p->PID=pid; - p->PPID=pbi.InheritedFromUniqueProcessId; - p->tCreation=ftCreation; - p->tCpu=Time((ftKernel+ftUser)/10000); - children.Append(p); - } - - CloseHandle(hProcess); - - } - } - } - delete [] arPids; - } - } - } - } - break; - case wxWIN95: - - if( hInstLib1) { - - static HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD)= - (HANDLE(WINAPI *)(DWORD,DWORD))GetProcAddress( hInstLib1,"CreateToolhelp32Snapshot" ) ; - static BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32)= - (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( hInstLib1, "Process32First" ) ; - static BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32)= - (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( hInstLib1, "Process32Next" ) ; - if( lpfProcess32Next && lpfProcess32First && lpfCreateToolhelp32Snapshot) { - - // Get a handle to a Toolhelp snapshot of the systems - // processes. - HANDLE hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ; - if(INVALID_HANDLE_VALUE != hSnapShot) { - // Get the first process' information. - PROCESSENTRY32 procentry; - procentry.dwSize = sizeof(PROCESSENTRY32) ; - if(lpfProcess32First( hSnapShot, &procentry )){ - rc=true; - do { - PInfo p; - p.PID=procentry.th32ProcessID; - p.PPID=procentry.th32ParentProcessID; - arPinfo.push_back(p); - } while(lpfProcess32Next( hSnapShot, &procentry )); - } - CloseHandle(hSnapShot); - } - } - } - break; - default: - break; - } - - SetParents(children); - - if(!rc){ - wxMessageBox(_T("Couldn't get process information!\n")); - } - return rc; -} -#endif - -#endif - #ifdef __WIN32__ // This will be obsolete when we switch to using the version included // in wxWindows (from wxWin 2.3.1 onwards) @@ -1438,3 +1237,363 @@ int ecKill(long pid, wxSignal sig) #endif } +#ifdef _WIN32 + #include <tlhelp32.h> + + WXHINSTANCE wxProcessKiller::hInstLib1 = VER_PLATFORM_WIN32_NT==wxProcessKiller::GetPlatform()? (WXHINSTANCE) LoadLibrary(_T("PSAPI.DLL")) : (WXHINSTANCE) LoadLibrary(_T("Kernel32.DLL")) ; + WXHINSTANCE wxProcessKiller::hInstLib2 = VER_PLATFORM_WIN32_NT==wxProcessKiller::GetPlatform()? (WXHINSTANCE) LoadLibrary(_T("NTDLL.DLL")): (WXHINSTANCE) NULL; + +#endif + +const unsigned int wxProcessKiller::PROCESS_KILL_EXIT_CODE=0xCCFFCCFF; + +wxProcessKiller::wxProcessKiller(int pid): + m_bVerbose(false), + m_nExitCode(-1), + m_idProcess(pid) +{ +#ifdef _WIN32 + m_hProcess = (WXHANDLE) ::OpenProcess(SYNCHRONIZE | + PROCESS_TERMINATE | + PROCESS_QUERY_INFORMATION, + FALSE, // not inheritable + (DWORD) m_idProcess); +#endif +} + +wxProcessKiller::~wxProcessKiller() +{ +#ifdef _WIN32 + if (m_hProcess) + { + ::CloseHandle((HANDLE) m_hProcess); + } +#endif +} + +bool wxProcessKiller::Kill(bool bRecurse) +{ + wxPInfoArray arPinfo; + bool rc=false; + if(m_idProcess && -1!=m_idProcess){ + // Start of with the easy one: + if(bRecurse) { + // Need to gather this information before we orphan our grandchildren: + PSExtract(arPinfo); + } + +#ifdef _WIN32 + + if(m_hProcess){ + rc=(TRUE==::TerminateProcess((HANDLE) m_hProcess,PROCESS_KILL_EXIT_CODE)); + // dtor's (or subsequent Run's) responsibility to close the handle + } + +#else + rc=(0==kill(m_idProcess,SIGTERM)); + int status; + waitpid(m_idProcess,&status,WNOHANG); +#endif + + if(bRecurse) { + // kill process *and* its children + // FIXME: needs to be top-down + for(int i=0;i<(signed)arPinfo.size();i++){ + if(arPinfo[i].IsChildOf(m_idProcess)){ + +#ifdef _WIN32 + // begin hack + // WHY NECESSARY?? + const wxString strName(Name(arPinfo[i].PID)); + if(_tcsstr(strName,_T("eCosTest")) || _tcsstr(strName,_T("cmd.EXE")) || _tcsstr(strName,_T("CMD.EXE")) || arPinfo[i].PID==(signed)GetCurrentProcessId()){ + continue; + } + // end hack + HANDLE hProcess=::OpenProcess(PROCESS_TERMINATE,false,arPinfo[i].PID); + if(hProcess){ + rc&=(TRUE==::TerminateProcess(hProcess,PROCESS_KILL_EXIT_CODE)); + CloseHandle(hProcess); + } else { + rc=false; + } +#else + rc&=(0==kill(arPinfo[i].PID,SIGTERM)); + int status; + waitpid(arPinfo[i].PID,&status,WNOHANG); +#endif + } + } + } + } + return rc; +} + +#ifdef _WIN32 +bool wxProcessKiller::PSExtract(wxProcessKiller::wxPInfoArray &arPinfo) +{ + bool rc=false; + arPinfo.clear(); + // If Windows NT: + switch(GetPlatform()) { + case VER_PLATFORM_WIN32_NT: + if(hInstLib1) { + + // Get procedure addresses. + static BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ) = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))GetProcAddress( (HINSTANCE) hInstLib1, "EnumProcesses" ) ; + if( lpfEnumProcesses) { + + if(hInstLib2) { + + static DWORD (WINAPI *lpfNtQueryInformationProcess)( HANDLE, int, void *, DWORD, LPDWORD ) = + (DWORD(WINAPI *)(HANDLE, int, void *, DWORD, LPDWORD)) GetProcAddress( (HINSTANCE) hInstLib2,"NtQueryInformationProcess" ) ; + + if(lpfNtQueryInformationProcess){ + DWORD dwMaxPids=256; + DWORD dwPidSize; + DWORD *arPids = NULL ; + do { + delete [] arPids; + arPids=new DWORD[dwMaxPids]; + } while(lpfEnumProcesses(arPids, dwMaxPids, &dwPidSize) && dwPidSize/sizeof(DWORD)==dwMaxPids) ; + + if(dwPidSize/sizeof(DWORD)<dwMaxPids){ + rc=true; + for( DWORD dwIndex = 0 ; (signed)dwIndex < dwPidSize/sizeof(DWORD); dwIndex++ ) { + // Regardless of OpenProcess success or failure, we + // still call the enum func with the ProcID. + DWORD pid=arPids[dwIndex]; + HANDLE hProcess=::OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, pid ); + if (hProcess ) { + struct { + DWORD ExitStatus; // receives process termination status + DWORD PebBaseAddress; // receives process environment block address + DWORD AffinityMask; // receives process affinity mask + DWORD BasePriority; // receives process priority class + ULONG UniqueProcessId; // receives process identifier + ULONG InheritedFromUniqueProcessId; // receives parent process identifier + } pbi; + memset( &pbi, 0, sizeof(pbi)); + DWORD retLen; + __int64 ftCreation,ftExit,ftKernel,ftUser; + if(lpfNtQueryInformationProcess(hProcess, 0 /*ProcessBasicInformation*/, &pbi, sizeof(pbi), &retLen)>=0 && + TRUE==::GetProcessTimes (hProcess,(FILETIME *)&ftCreation,(FILETIME *)&ftExit,(FILETIME *)&ftKernel,(FILETIME *)&ftUser)){ + // The second test is important. It excludes orphaned processes who appear to have been adopted by virtue of a new + // process having been created with the same ID as their original parent. + wxPInfo p; + p.PID=pid; + p.PPID=pbi.InheritedFromUniqueProcessId; + p.tCreation=ftCreation; + p.tCpu=Time((ftKernel+ftUser)/10000); + arPinfo.push_back(p); + } + + CloseHandle(hProcess); + + } + } + } + delete [] arPids; + } + } + } + } + break; + case VER_PLATFORM_WIN32_WINDOWS: + + if( hInstLib1) { + + static HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD)= + (HANDLE(WINAPI *)(DWORD,DWORD))GetProcAddress( (HINSTANCE) hInstLib1,"CreateToolhelp32Snapshot" ) ; + static BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32)= + (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( (HINSTANCE) hInstLib1, "Process32First" ) ; + static BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32)= + (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))GetProcAddress( (HINSTANCE) hInstLib1, "Process32Next" ) ; + if( lpfProcess32Next && lpfProcess32First && lpfCreateToolhelp32Snapshot) { + + // Get a handle to a Toolhelp snapshot of the systems + // processes. + HANDLE hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ; + if(INVALID_HANDLE_VALUE != hSnapShot) { + // Get the first process' information. + PROCESSENTRY32 procentry; + procentry.dwSize = sizeof(PROCESSENTRY32) ; + if(lpfProcess32First( hSnapShot, &procentry )){ + rc=true; + do { + wxPInfo p; + p.PID=procentry.th32ProcessID; + p.PPID=procentry.th32ParentProcessID; + arPinfo.push_back(p); + } while(lpfProcess32Next( hSnapShot, &procentry )); + } + CloseHandle(hSnapShot); + } + } + } + break; + default: + break; + } + + SetParents(arPinfo); + + if(!rc){ + wxLogError(_T("Couldn't get process information!\n")); + } + return rc; +} + +#else // UNIX + +bool wxProcessKiller::PSExtract(wxProcessKiller::wxPInfoArray &arPinfo) +{ + arPinfo.clear(); + int i; + FILE *f=popen("ps -l",_T("r") MODE_TEXT); + if(f){ + char buf[100]; + while(fgets(buf,sizeof(buf)-1,f)){ + TCHAR discard[100]; + wxPInfo p; + // Output is in the form + // F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD + //100 S 490 877 876 0 70 0 - 368 wait4 pts/0 00:00:00 bash + int F,UID,C,PRI,NI,SZ,HH,MM,SS; + bool rc=(15==_stscanf(buf,_T("%d %s %d %d %d %d %d %d %s %d %s %s %d:%d:%d"),&F,discard,&UID,&p.PID,&p.PPID,&C,&PRI,&NI,discard,&SZ,discard,discard,&HH,&MM,&SS)); + if(rc){ + p.tCpu=1000*(SS+60*(60*HH+MM)); + arPinfo.push_back(p); + } + } + pclose(f); + for(i=0;i<(signed)arPinfo.size();i++){ + int pid=arPinfo[i].PPID; + arPinfo[i].pParent=0; + for(int j=0;j<(signed)arPinfo.size();j++){ + if(i!=j && arPinfo[j].PID==pid){ + arPinfo[i].pParent=&arPinfo[j]; + break; + } + } + } + } else { + wxLogError(_T("Failed to run ps -l\n")); + } + return true; //FIXME +} + +#endif + +void wxProcessKiller::SetParents(wxProcessKiller::wxPInfoArray &arPinfo) +{ + int i; + for(i=0;i<(signed)arPinfo.size();i++){ + wxPInfo &p=arPinfo[i]; + p.pParent=0; + for(int j=0;j<(signed)arPinfo.size();j++){ + if(arPinfo[j].PID==p.PPID +#ifdef _WIN32 + && arPinfo[j].tCreation<p.tCreation +#endif + ) + { + arPinfo[i].pParent=&arPinfo[j]; + break; + } + } + } + + // Check for circularity + bool bCircularity=false; + for(i=0;i<(signed)arPinfo.size();i++){ + wxPInfo *p=&arPinfo[i]; + for(int j=0;j<(signed)arPinfo.size() && p;j++){ + p=p->pParent; + } + // If all is well, p should be NULL here. Otherwise we have a loop. + if(p){ + // Make sure it can't foul things up: + arPinfo[i].pParent=0; + bCircularity=true; + } + } + + if(bCircularity){ + wxLogError(_T("!!! Circularly linked process list at index %d\n"),i); + for(int k=0;k<(signed)arPinfo.size();k++){ + const wxPInfo &p=arPinfo[k]; + wxLogError(_T("%d: %s ppid=%4d\n"),k,(LPCTSTR)Name(p.PID),p.PPID); + } + } +} + +bool wxProcessKiller::wxPInfo::IsChildOf(int pid) const +{ + for(wxPInfo *p=pParent;p && p!=this;p=p->pParent) { // guard against circular linkage + if(p->PID==pid){ + return true; + } + } + return false; +} + +const wxString wxProcessKiller::Name(int pid) +{ + wxString str; + str.Printf(_T("id=%d"),pid); +#ifdef _DEBUG +#ifdef _WIN32 + if(VER_PLATFORM_WIN32_NT==GetPlatform() && hInstLib1){ + static BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, DWORD, LPDWORD ) = + (BOOL(WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( (HINSTANCE) hInstLib1,"EnumProcessModules" ) ; + static DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE, LPTSTR, DWORD )= + (DWORD (WINAPI *)(HANDLE, HMODULE,LPTSTR, DWORD )) GetProcAddress( (HINSTANCE) hInstLib1,"GetModuleFileNameExA" ) ; + if( lpfEnumProcessModules && lpfGetModuleFileNameEx ) { + HANDLE hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,pid); + if(hProcess) { + HMODULE hMod; + DWORD dwSize; + if(lpfEnumProcessModules( hProcess, &hMod, sizeof(HMODULE), &dwSize ) ){ + // Get Full pathname: + TCHAR buf[1+MAX_PATH]; + lpfGetModuleFileNameEx( hProcess, hMod, buf, MAX_PATH); + str+=_TCHAR(' '); + str+=buf; + } + CloseHandle(hProcess); + } + } + } +#endif +#endif + return str; +} + +#ifdef _WIN32 +long wxProcessKiller::GetPlatform() +{ + OSVERSIONINFO osver; + osver.dwOSVersionInfoSize = sizeof( osver ) ; + return GetVersionEx( &osver ) ? (long) osver.dwPlatformId : (long)-1; +} +#endif + +const wxString wxProcessKiller::ErrorString() const +{ +#ifdef _WIN32 + TCHAR *pszMsg; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + m_nErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&pszMsg, + 0, + NULL + ); + return pszMsg; +#else + return strerror(errno); +#endif +} +
--- a/host/tools/configtool/standalone/wxwin/ecutils.h +++ b/host/tools/configtool/standalone/wxwin/ecutils.h @@ -213,6 +213,77 @@ wxOutputStream& operator <<(wxOutputStre wxOutputStream& operator <<(wxOutputStream&, long l); /* + * Class for recursively killing a process and its children. + * This has been taken from CSubprocess, but we can't use CSubprocess + * directly for killing a process because it assumes it's been used to create + * the process. + */ + +class wxProcessKiller +{ + +public: + const wxString ErrorString() const; + + wxProcessKiller(int pid); + ~wxProcessKiller(); + + void SetVerbose (bool b) { m_bVerbose=b; } + + int Pid() const { return m_idProcess; } // returns process id (even when process is terminated) + + // Get the process exit code. This can be: + // exit code of process (if terminated) + // 0xffffffff (if process not yet run) + // GetLastError result (if process could not be run) + int GetExitCode() { return m_nExitCode; } + + // Kill the process: + bool Kill(bool bRecurse = true); + + // Is the process running? + bool ProcessAlive(); + +protected: + static const wxString Name (int pid); // for debugging - only works under NT + + struct wxPInfo; + struct wxPInfo { + wxPInfo *pParent; +#ifdef _WIN32 + __int64 tCreation; +#endif + long tCpu; + int PID; + int PPID; + bool IsChildOf(int pid) const; + }; + + typedef std::vector<wxPInfo> wxPInfoArray; + + static bool PSExtract(wxPInfoArray &arPinfo); + static void SetParents(wxPInfoArray &arPinfo); + +#ifdef _WIN32 + static long GetPlatform(); + WXHANDLE m_hrPipe; + WXHANDLE m_hwPipe; + WXHANDLE m_hProcess; // This handle is "owned" by the ThreadFunc + static WXHINSTANCE hInstLib1, hInstLib2; + int m_nErr; +#else + int m_tty; + wxString m_strCmd; +#endif + + bool m_bVerbose; + int m_nExitCode; + int m_idProcess; + + static const unsigned int PROCESS_KILL_EXIT_CODE; +}; + +/* * ecDialog * Supports features we want to have for all dialogs in the application. * So far, this just allows dialogs to be resizeable under MSW by
--- a/host/tools/configtool/standalone/wxwin/mainwin.cpp +++ b/host/tools/configtool/standalone/wxwin/mainwin.cpp @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/08/24 -// Version: $Id: mainwin.cpp,v 1.48 2001/08/10 14:58:21 julians Exp $ +// Version: $Id: mainwin.cpp,v 1.53 2001/09/03 17:18:18 julians Exp $ // Purpose: // Description: Implementation file for the ConfigTool main window // Requires: @@ -478,7 +478,7 @@ void ecMainFrame::CreateWindows() wxDefaultSize, wxNO_BORDER); m_splitter->SplitVertically(m_tree, m_valueWindow); //m_splitter->AdjustScrollbars(); - m_splitter->SetSashPosition(200); + m_splitter->SetSashPosition(wxGetApp().GetSettings().m_configPaneWidth); m_scrolledWindow->SetTargetWindow(m_tree); m_scrolledWindow->EnableScrolling(FALSE, FALSE); m_tree->SetHelpText(_("The configuration window is the principal window used to configure eCos.\nIt takes the form of a tree-based representation of the configuration items within the currently loaded eCos packages.")); @@ -928,6 +928,7 @@ void ecMainFrame::OnCloseWindow(wxCloseE wxGetApp().GetSettings().m_shortDescrSashSize = m_shortDescrSashWindow->GetSize(); wxGetApp().GetSettings().m_memorySashSize = m_memorySashWindow->GetSize(); wxGetApp().GetSettings().m_outputSashSize = m_outputSashWindow->GetSize(); + wxGetApp().GetSettings().m_configPaneWidth = m_splitter->GetSashPosition(); event.Skip(); } @@ -1047,6 +1048,8 @@ void ecMainFrame::OnHelpConfigtool(wxCom { //wxString strURL(wxT("redirect/the-ecos-configuration-tool.html")); wxString strURL(wxGetApp().GetFullAppPath(wxT("manual/user-guides.2.html"))); + if (!wxFileExists(strURL)) + strURL = wxT("guides/user-guides.2.html"); if (wxGetApp().GetConfigToolDoc()) { @@ -1118,7 +1121,8 @@ void ecMainFrame::OnTemplates(wxCommandE { #ifdef __WXMSW__ // Ensure display gets updated - wxYield(); + ::UpdateWindow((HWND) GetHWND()); + //wxYield(); #endif ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc(); @@ -1520,11 +1524,60 @@ void ecMainFrame::OnBuildLibrary(wxComma // TODO: possibly add wxT("clean build") to ensure library is // cleanly built. No, can't do that because it would clean // out any user code too :-( + + bool regenerateBuildTree = FALSE; + + if (wxGetApp().GetSettings().m_editSaveFileOnly) + { + int ans = wxMessageBox(wxT("Running in --edit-only mode so there may not be an up-to-date build tree.\nBuild the tree now?"), wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO|wxCANCEL); + + if (ans == wxYES) + { + regenerateBuildTree = TRUE; + } + else if (ans == wxCANCEL) + return; + } + + if (regenerateBuildTree) + { + ecConfigToolDoc* pDoc = wxGetApp().GetConfigToolDoc(); + if (!pDoc) + return; + + if (!pDoc->GenerateBuildTree()) + return ; + } + wxGetApp().Build(); } void ecMainFrame::OnBuildTests(wxCommandEvent& event) { + bool regenerateBuildTree = FALSE; + + if (wxGetApp().GetSettings().m_editSaveFileOnly) + { + int ans = wxMessageBox(wxT("Running in --edit-only mode so there may not be an up-to-date build tree.\nBuild the tree now?"), wxGetApp().GetSettings().GetAppName(), wxICON_QUESTION|wxYES_NO|wxCANCEL); + + if (ans == wxYES) + { + regenerateBuildTree = TRUE; + } + else if (ans == wxCANCEL) + return; + } + + if (regenerateBuildTree) + { + ecConfigToolDoc* pDoc = wxGetApp().GetConfigToolDoc(); + if (!pDoc) + return; + + if (!pDoc->GenerateBuildTree()) + return ; + } + wxGetApp().Build(wxT("tests")); } @@ -1534,7 +1587,9 @@ void ecMainFrame::OnStopBuild(wxCommandE { long pid = wxGetApp().m_pipedProcess->GetPid(); wxGetApp().m_pipedProcess->Detach(); - ecKill(pid, wxSIGKILL); + + wxProcessKiller pKiller(pid); + pKiller.Kill(TRUE); } }
--- a/host/tools/configtool/standalone/wxwin/settingsdlg.cpp +++ b/host/tools/configtool/standalone/wxwin/settingsdlg.cpp @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2000/09/11 -// Version: $Id: settingsdlg.cpp,v 1.13 2001/07/05 10:42:16 julians Exp $ +// Version: $Id: settingsdlg.cpp,v 1.14 2001/09/03 16:51:51 julians Exp $ // Purpose: // Description: Implementation file for ecSettingsDialog // Requires: @@ -568,7 +568,7 @@ void ecViewerOptionsDialog::CreateContro item0->Add( item8, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); // Disable this option because we don't yet have a built-in browser -#if !ecUSE_EXPERIMENTAL_CODE +#if 0 // !ecUSE_EXPERIMENTAL_CODE FindWindow(ecID_VIEWER_DIALOG_DOC_BUILTIN)->Enable(FALSE); #endif
--- a/host/tools/configtool/standalone/wxwin/setup/configtool.iss +++ b/host/tools/configtool/standalone/wxwin/setup/configtool.iss @@ -4,13 +4,13 @@ [Setup] MinVersion=4.0,4.0 - AppName=eCos Configuration Tool 2.04 + AppName=eCos Configuration Tool 2.07 AppId=eCos Configuration Tool CreateUninstallRegKey=1 UsePreviousAppDir=1 UsePreviousGroup=1 - AppVersion=2.04 - AppVerName=eCos Configuration Tool 2.04 + AppVersion=2.07 + AppVerName=eCos Configuration Tool 2.07 AppCopyright=Copyright © Red Hat Inc., 2001 BackColor=$FF0000 BackColor2=$000000 @@ -42,12 +42,9 @@ Name: {app}\manual\pix [Files] - Source: v:\deliver\configtool\about.htm; DestDir: {app}\ - Source: v:\deliver\configtool\aboutlo.htm; DestDir: {app}\ Source: v:\deliver\configtool\CHANGES.txt; DestDir: {app}\ + Source: v:\deliver\configtool\configtool.bin; DestDir: {app}\ Source: v:\deliver\configtool\configtool.exe; DestDir: {app}\ - Source: v:\deliver\configtool\ecoslogo.png; DestDir: {app}\ - Source: v:\deliver\configtool\ecoslogosmall.png; DestDir: {app}\ Source: v:\deliver\configtool\license.txt; DestDir: {app}\ Source: v:\deliver\configtool\manual\botclear.gif; DestDir: {app}\manual Source: v:\deliver\configtool\manual\cygnus.css; DestDir: {app}\manual @@ -182,7 +179,6 @@ Source: v:\deliver\configtool\manual\user-guides.f.html; DestDir: {app}\manual Source: v:\deliver\configtool\manual\user-guides.html; DestDir: {app}\manual Source: v:\deliver\configtool\README.txt; DestDir: {app}\ - Source: v:\deliver\configtool\rhlogo.png; DestDir: {app}\ Source: v:\deliver\configtool\TODO.txt; DestDir: {app}\ Source: c:\winnt\system32\tcl82.dll; DestDir: {sys}\; DestName: tcl82.dll; CopyMode: onlyifdoesntexist; Flags: uninsneveruninstall @@ -217,7 +213,7 @@ ; DO NOT DELETE THEM or you may be unable to reload the script ;[ScriptSetup] -;VerNum=2.04 +;VerNum=2.07 ;InnoVer=1.3 ;AddVerTo=AppVerName ;SetupFilename=setup.exe
--- a/host/tools/configtool/standalone/wxwin/setup/makesetup.sh +++ b/host/tools/configtool/standalone/wxwin/setup/makesetup.sh @@ -35,6 +35,7 @@ findversion() doinno() { + rm -f -r $DEST/configtool mkdir -p $DEST/configtool mkdir -p $DEST/configtool/manual mkdir -p $DEST/configtool/manual/pix @@ -45,6 +46,9 @@ doinno() cp $SRC/CHANGES.txt . cp $SRC/TODO.txt . cp $SRC/*.png . + cp $SRC/bitmaps/splash16.png . + zip configtool.bin about.htm *.png + rm -f about.htm *.png cp "$ECOSDIR/ecc/release/eCos Install/Setup Files/Uncompressed Files/Disk1/license.txt" . cp $BINARYSRC/configtool.exe . cp $CONFIGTOOLDIR/manual/*.html $CONFIGTOOLDIR/manual/*.css $CONFIGTOOLDIR/manual/*.gif $DEST/configtool/manual
--- a/host/tools/configtool/standalone/wxwin/setup/maketarball.sh +++ b/host/tools/configtool/standalone/wxwin/setup/maketarball.sh @@ -29,6 +29,9 @@ dotar() cp $SRC/*.htm . cp $SRC/*.png . + cp $SRC/bitmaps/splash16.png . + zip configtool.bin *.htm *.png + rm -f *.htm *.png cp $SRC/setup/ecosplatforms.tar.gz . cp $SRC/README.txt . cp $SRC/CHANGES.txt .
--- a/host/tools/configtool/standalone/wxwin/symbols.h +++ b/host/tools/configtool/standalone/wxwin/symbols.h @@ -30,7 +30,7 @@ // Author(s): julians // Contact(s): julians // Date: 2001/05/14 -// Version: $Id: symbols.h,v 1.8 2001/08/10 14:58:21 julians Exp $ +// Version: $Id: symbols.h,v 1.10 2001/09/05 14:35:53 julians Exp $ // Purpose: // Description: Some important symbols, such as the version // Requires: @@ -43,5 +43,5 @@ // //=========================================================================== -#define ecCONFIGURATION_TOOL_VERSION 2.05 +#define ecCONFIGURATION_TOOL_VERSION 2.07
--- a/packages/ChangeLog +++ b/packages/ChangeLog @@ -105,6 +105,10 @@ 2001-04-03 Jonathan Larmour <jlarmour@ * ecos.db: Include flash driver in sa1100mm target. +2001-04-03 Jesper Skov <jskov@redhat.com> + + * ecos.db: Added PCNet ethernet driver package. + 2001-03-29 Jonathan Larmour <jlarmour@redhat.com> * ecos.db: Add Atlas flash and ethernet drivers to target description.
--- a/packages/NEWS +++ b/packages/NEWS @@ -1,3 +1,4 @@ +* AMD PCNet ethernet driver added. * Generic SMP support added. * RedBoot support added to AM33-STB port. * Add Atmel AT91/EB40 port, including flash and serial drivers.
--- a/packages/compat/posix/current/ChangeLog +++ b/packages/compat/posix/current/ChangeLog @@ -1,3 +1,8 @@ +2001-09-06 Jesper Skov <jskov@redhat.com> + + * cdl/posix.cdl: Moved signal implements statements to the + CYGPKG_POSIX_SIGNALS component. + 2001-08-06 Jonathan Larmour <jlarmour@redhat.com> * cdl/posix.cdl: Reorganize dependencies so that signals, timers
--- a/packages/compat/posix/current/cdl/posix.cdl +++ b/packages/compat/posix/current/cdl/posix.cdl @@ -53,18 +53,9 @@ cdl_package CYGPKG_POSIX { requires CYGIMP_KERNEL_SCHED_SORTED_QUEUES implements CYGINT_ISO_SCHED_IMPL - implements CYGINT_ISO_SIGNAL_NUMBERS - implements CYGINT_ISO_SIGNAL_IMPL implements CYGINT_ISO_POSIX_LIMITS - implements CYGINT_ISO_PMUTEXTYPES - requires { CYGBLD_ISO_SIGNAL_NUMBERS_HEADER == \ - "<cyg/posix/signal.h>" } - requires { CYGBLD_ISO_SIGNAL_IMPL_HEADER == \ - "<cyg/posix/signal.h>" } requires { CYGBLD_ISO_POSIX_LIMITS_HEADER == \ "<cyg/posix/limits.h>" } - requires { CYGBLD_ISO_PMUTEXTYPES_HEADER == \ - "<cyg/posix/muttypes.h>" } compile mqueue.cxx mutex.cxx sem.cxx misc.cxx compile -library=libextras.a startup.cxx @@ -205,6 +196,12 @@ cdl_package CYGPKG_POSIX { implements CYGINT_ISO_SIGSETJMP requires { CYGBLD_ISO_SIGSETJMP_HEADER == \ "<cyg/posix/sigsetjmp.h>" } + implements CYGINT_ISO_SIGNAL_NUMBERS + implements CYGINT_ISO_SIGNAL_IMPL + requires { CYGBLD_ISO_SIGNAL_NUMBERS_HEADER == \ + "<cyg/posix/signal.h>" } + requires { CYGBLD_ISO_SIGNAL_IMPL_HEADER == \ + "<cyg/posix/signal.h>" } description "This component provides configuration controls for the POSIX signals." compile signal.cxx except.cxx
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/amd/pcnet/current/ChangeLog @@ -0,0 +1,123 @@ +2001-07-26 Jesper Skov <jskov@redhat.com> + + * src/if_pcnet.c (amd_pcnet_init): Wait for init table loadup + completion. Removed ESA hack. + +2001-07-25 Jesper Skov <jskov@redhat.com> + + * src/if_pcnet.c: Be more careful with the use of STOP since it + clears interrupt request flags. Moved some code from _start to + _init. Don't double check RX int flag in RxEvent function. + (amd_pcnet_init): Move ID output below initialization. + Get rid of the last use of STOP, replace with SUSPEND. Minor + cleanups. + (amd_pcnet_init): Fix silly compile error. + (amd_pcnet_init): Check that the controller actually + starts. Appears that it needs to be kicked a couple of times under + certain conditions. + + * src/amd_pcnet.h: Added TFC bits. + +2001-07-24 Jesper Skov <jskov@redhat.com> + + * src/if_pcnet.c: Mask off RDRA/TDRA pointers. Additional debug + info. Hack for broken ESA init. Don't clear TX interrupt flag in + send function (leave it to the event handler). + (pcnet_stop): Don't reset the controller, just stop it. + (pcnet_TxEvent): Only ack interrupt once. + + * src/amd_pcnet.h: Added more registers. + +2001-07-18 Jesper Skov <jskov@redhat.com> + + * src/if_pcnet.c: Make controller recover after FIFO + underflow. Removed unnecessary stall checking. Signal stack on TX + errors. + +2001-07-16 Jesper Skov <jskov@redhat.com> + + * src/if_pcnet.c: Minor cleanups, avoid use of diag_printf unless + when debugging. + +2001-07-12 Jesper Skov <jskov@redhat.com> + + * src/if_pcnet.c: Use PCI_IO accessor macros instead of HAL IO + macros. Added a few more CPU->PCI address conversions. Print + controller data. + + * src/amd_pcnet.h: Added default PCI_IO accessor macros. Use + PCI_IO accessor macros instead of HAL IO macros. + + * src/if_pcnet.c: Removed macros. Added new interrupt handling + code. Added code to find resources via PCI library. Change from + enaddr to esa. Use HAL_PCI_CPU_TO_BUS macros instead of phys + address macro. Fix esa setup code. Debug output tidied up. + + * src/amd_pcnet.h: Moved macros here. Added definitions for 32 bit + RD/TD (unused). Changes for PCI configury. + + * cdl/amd_pcnet_eth_drivers.cdl: Removed static esa option (now + per-device option). Added dev count option. + + * src/if_pcnet.c: Get rid of within_send. + * src/amd_pcnet.h: Same. + + * src/if_pcnet.c: Fix compile error. + +2001-04-09 Jesper Skov <jskov@redhat.com> + + * src/if_pcnet.c: More updates. + + * src/amd_pcnet.h: A few more defs. + + * cdl/amd_pcnet_eth_drivers.cdl: Removed write EEPROM option. + + * src/if_pcnet.c: Fix link status check code. Change some C types + to cyg types. + * src/amd_pcnet.h (get_reg, put_reg): Also access ANR registers. + + * src/amd_pcnet.h: Macros for accessing structure elements. + * src/if_pcnet.c: Use those macros. + +2001-04-04 Jesper Skov <jskov@redhat.com> + + * src/if_pcnet.c: Keep local counter of where to expect RX + packets. Appears that the receive ring counter always points at + the first buffer. + (pcnet_poll): Handle RX events before TX events. + Make sure to not accidently clear IENA flag. + + * src/if_pcnet.c: Added RX code. + * src/amd_pcnet.h: A few more defs. + +2001-04-03 Jesper Skov <jskov@redhat.com> + + * src/if_pcnet.c (amd_pcnet_init): Feed controller physical address. + + * Cloned from LAN91Cxx driver. + +//=========================================================================== +//####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, 2001 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//===========================================================================
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/amd/pcnet/current/cdl/amd_pcnet_eth_drivers.cdl @@ -0,0 +1,86 @@ +# ==================================================================== +# +# amd_pcnet_eth_drivers.cdl +# +# Ethernet drivers - support for AMD PCNET ethernet controllers +# +# ==================================================================== +#####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, 2001 Red Hat, Inc. +# All Rights Reserved. +# ------------------------------------------- +# +#####COPYRIGHTEND#### +# ==================================================================== +######DESCRIPTIONBEGIN#### +# +# Author(s): gthomas +# Contributors: gthomas, jskov +# Date: 2001-04-02 +# +#####DESCRIPTIONEND#### +# +# ==================================================================== + +cdl_package CYGPKG_DEVS_ETH_AMD_PCNET { + display "AMD PCNET compatible ethernet driver" + description "Ethernet driver for AMD PCNET compatible controllers." + + parent CYGPKG_IO_ETH_DRIVERS + active_if CYGPKG_IO_ETH_DRIVERS + + active_if CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED + + include_dir . + include_files ; # none _exported_ whatsoever + compile -library=libextras.a if_pcnet.c + + define_proc { + puts $::cdl_header "#include <pkgconf/system.h>"; + puts $::cdl_header "#include CYGDAT_DEVS_ETH_AMD_PCNET_CFG"; + } + + cdl_option CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT { + display "Number of supported interfaces." + calculated { CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED } + flavor data + description " + This option selects the number of PCI ethernet interfaces to + be supported by the driver." + } + + cdl_component CYGPKG_DEVS_ETH_AMD_PCNET_OPTIONS { + display "PCNET ethernet driver build options" + flavor none + no_define + + cdl_option CYGPKG_DEVS_ETH_AMD_PCNET_CFLAGS_ADD { + display "Additional compiler flags" + flavor data + no_define + default_value { "-D_KERNEL -D__ECOS" } + description " + This option modifies the set of compiler flags for + building the PCNET ethernet driver package. + These flags are used in addition + to the set of global flags." + } + } +}
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/amd/pcnet/current/src/amd_pcnet.h @@ -0,0 +1,528 @@ +#ifndef CYGONCE_DEVS_ETH_AMD_PCNET_H +#define CYGONCE_DEVS_ETH_AMD_PCNET_H +//========================================================================== +// +// amd_pcnet.h +// +// AMD PCNet Ethernet chip +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov +// Contributors: jskov, hmt +// Date: 2001-04-02 +// Purpose: Hardware description of AMD PCnet series. +// Description: +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include <cyg/hal/hal_io.h> + +//------------------------------------------------------------------------ +// Get macros from platform header +#define __WANT_CONFIG +#include CYGDAT_DEVS_ETH_AMD_PCNET_INL +#undef __WANT_CONFIG + +//------------------------------------------------------------------------ +// Set to perms of: +// 0 disables all debug output +// 1 for process debug output +// 2 for added data IO output: get_reg, put_reg +// 4 for packet allocation/free output +// 8 for only startup status, so we can tell we're installed OK +#define DEBUG 0x0 + +#if DEBUG & 1 +#define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0) +#else +#define DEBUG_FUNCTION() do {} while(0) +#endif + +// ------------------------------------------------------------------------ +// Macros for keeping track of statistics +#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD) +# define KEEP_STATISTICS +#endif + +#ifdef KEEP_STATISTICS +# define INCR_STAT( _x_ ) (cpd->stats. _x_ ++) +#else +# define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT +#endif + +//------------------------------------------------------------------------ +// Cache translation +#ifndef CYGARC_UNCACHED_ADDRESS +# define CYGARC_UNCACHED_ADDRESS(x) (x) +#endif + +//------------------------------------------------------------------------ +// Address translation +#ifndef HAL_PCI_CPU_TO_BUS +# error "HAL PCI support must define translation macros" +#endif + +// ------------------------------------------------------------------------ +// Macros for accessing structure elements + +#define _SU8( _base_, _offset_) \ + *((cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_))) +#define _SU16( _base_, _offset_) \ + *((cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_))) +#define _SU32( _base_, _offset_) \ + *((cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_))) + +#define _SI8( _base_, _offset_) \ + *((cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_))) +#define _SI16( _base_, _offset_) \ + *((cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_))) +#define _SI32( _base_, _offset_) \ + *((cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_))) + +// ------------------------------------------------------------------------ +// Macros for accessing controller registers +#ifndef HAL_PCI_IO_READ_UINT8 +# define HAL_PCI_IO_READ_UINT8(addr, datum) HAL_READ_UINT8(addr, datum) +# define HAL_PCI_IO_WRITE_UINT8(addr, datum) HAL_WRITE_UINT8(addr, datum) +# define HAL_PCI_IO_READ_UINT16(addr, datum) HAL_READ_UINT16(addr, datum) +# define HAL_PCI_IO_WRITE_UINT16(addr, datum) HAL_WRITE_UINT16(addr, datum) +# define HAL_PCI_IO_READ_UINT32(addr, datum) HAL_READ_UINT32(addr, datum) +# define HAL_PCI_IO_WRITE_UINT32(addr, datum) HAL_WRITE_UINT32(addr, datum) +#endif + +// ------------------------------------------------------------------------ +// IO map registers +#define PCNET_IO_EEPROM 0x00 +#define PCNET_IO_ID 0x0e +#define PCNET_IO_RDP 0x10 +#define PCNET_IO_RAP 0x12 +#define PCNET_IO_RESET 0x14 +#define PCNET_IO_BDP 0x16 + +// The ID of the 79C790 is 0x5757 - that may be different in other +// (older) cards. +#define PCNET_IO_ID_KEY 0x5757 + +// ------------------------------------------------------------------------ +// Controller registers come in three sets: CSR, BCR and ANR. Use +// high-bits do differentiate, make the put/get functions do the right +// thing depending the state of these bits. +#define PCNET_RAP_MASK 0x007f +//#define PCNET_CSR_FLAG 0x0000 // implied +#define PCNET_BCR_FLAG 0x0080 +#define PCNET_ANR_FLAG 0x0100 + + +// CSR registers +#define PCNET_CSR_CSCR 0 +#define PCNET_CSR_IBA0 1 +#define PCNET_CSR_IBA1 2 +#define PCNET_CSR_IM 3 +#define PCNET_CSR_TFC 4 +#define PCNET_CSR_ECI 5 +#define PCNET_CSR_LAR0 8 +#define PCNET_CSR_LAR1 9 +#define PCNET_CSR_LAR2 10 +#define PCNET_CSR_LAR3 11 +#define PCNET_CSR_PAR0 12 +#define PCNET_CSR_PAR1 13 +#define PCNET_CSR_PAR2 14 +#define PCNET_CSR_MODE 15 +#define PCNET_CSR_BARRL 24 +#define PCNET_CSR_BARRU 25 +#define PCNET_CSR_BATRL 30 +#define PCNET_CSR_BATRU 31 +#define PCNET_CSR_RRC 72 +#define PCNET_CSR_TRC 74 +#define PCNET_CSR_RRLEN 76 +#define PCNET_CSR_TRLEN 78 +#define PCNET_CSR_ID_LO 88 +#define PCNET_CSR_ID_HI 89 + + +#define PCNET_CSR_CSCR_ERR 0x8000 +#define PCNET_CSR_CSCR_RES 0x4000 +#define PCNET_CSR_CSCR_CERR 0x2000 +#define PCNET_CSR_CSCR_MISS 0x1000 +#define PCNET_CSR_CSCR_MERR 0x0800 +#define PCNET_CSR_CSCR_RINT 0x0400 +#define PCNET_CSR_CSCR_TINT 0x0200 +#define PCNET_CSR_CSCR_IDON 0x0100 +#define PCNET_CSR_CSCR_INTR 0x0080 +#define PCNET_CSR_CSCR_IENA 0x0040 +#define PCNET_CSR_CSCR_RXON 0x0020 +#define PCNET_CSR_CSCR_TXON 0x0010 +#define PCNET_CSR_CSCR_TDMD 0x0008 +#define PCNET_CSR_CSCR_STOP 0x0004 +#define PCNET_CSR_CSCR_STRT 0x0002 +#define PCNET_CSR_CSCR_INIT 0x0001 + +#define PCNET_CSR_CSCR_EV_MASK 0x007f + +#define PCNET_CSR_IM_MISSM 0x1000 +#define PCNET_CSR_IM_MERRM 0x0800 +#define PCNET_CSR_IM_RINTM 0x0400 +#define PCNET_CSR_IM_TINTM 0x0200 +#define PCNET_CSR_IM_IDONM 0x0100 +#define PCNET_CSR_IM_DXSUFLO 0x0040 +#define PCNET_CSR_IM_LAPPEN 0x0020 +#define PCNET_CSR_IM_DXMT2PD 0x0010 +#define PCNET_CSR_IM_EMBA 0x0008 +#define PCNET_CSR_IM_BSWP 0x0004 + +#define PCNET_CSR_TFC_TXDPOLL 0x1000 +#define PCNET_CSR_TFC_APAD_XMT 0x0800 +#define PCNET_CSR_TFC_ASTRP_RCV 0x0400 +#define PCNET_CSR_TFC_MFCO 0x0200 +#define PCNET_CSR_TFC_MFCOM 0x0100 +#define PCNET_CSR_TFC_UINTCMD 0x0080 +#define PCNET_CSR_TFC_UINT 0x0040 +#define PCNET_CSR_TFC_RCVCCO 0x0020 +#define PCNET_CSR_TFC_RCVCCOM 0x0010 +#define PCNET_CSR_TFC_TXSTRT 0x0008 +#define PCNET_CSR_TFC_TXSTRTM 0x0004 + +#define PCNET_CSR_ECI_TOKINTD 0x8000 +#define PCNET_CSR_ECI_LTINTEN 0x4000 +#define PCNET_CSR_ECI_SINT 0x0800 +#define PCNET_CSR_ECI_SINTE 0x0400 +#define PCNET_CSR_ECI_EXDINT 0x0080 +#define PCNET_CSR_ECI_EXDINTE 0x0040 +#define PCNET_CSR_ECI_MPPLBA 0x0020 +#define PCNET_CSR_ECI_MPINT 0x0010 +#define PCNET_CSR_ECI_MPINTE 0x0008 +#define PCNET_CSR_ECI_MPEN 0x0004 +#define PCNET_CSR_ECI_MPMODE 0x0002 +#define PCNET_CSR_ECI_SPND 0x0001 + +#define PCNET_CSR_MODE_PROM 0x8000 +#define PCNET_CSR_MODE_DRCVBC 0x4000 +#define PCNET_CSR_MODE_DRCVPA 0x2000 +#define PCNET_CSR_MODE_PORTSEL 0x0180 +#define PCNET_CSR_MODE_INTL 0x0040 +#define PCNET_CSR_MODE_DRTY 0x0020 +#define PCNET_CSR_MODE_FCOLL 0x0010 +#define PCNET_CSR_MODE_DXMTFCS 0x0008 +#define PCNET_CSR_MODE_LOOP 0x0004 +#define PCNET_CSR_MODE_DTX 0x0002 +#define PCNET_CSR_MODE_DRX 0x0001 + +// BCR registers +#define PCNET_BCR_SWSTYLE (20 |PCNET_BCR_FLAG) +#define PCNET_BCR_MIIADDR (33 |PCNET_BCR_FLAG) +#define PCNET_BCR_MIIDATA (34 |PCNET_BCR_FLAG) + +#define PCNET_BCR_MIIADDR_PHYAD 0x03e0 + + +// ANR registers +#define PCNET_ANR_PHYCTRL ( 0 |PCNET_ANR_FLAG) +#define PCNET_ANR_PHYSTAT ( 1 |PCNET_ANR_FLAG) + +#define PCNET_ANR_PHYCTRL_100MBPS 0x2000 +#define PCNET_ANR_PHYCTRL_DUPLEX 0x0100 + +#define PCNET_ANR_PHYSTAT_LINK 0x0004 + + +//---------------------------------------------------------------------------- +// Receive buffer Descriptor +#if 1 +#define PCNET_RD_PTR 0x00 // 32 bit +#define PCNET_RD_BLEN 0x04 // 16 bit (2's complement, negative) +#define PCNET_RD_MLEN 0x06 // 16 bit +#define PCNET_RD_SIZE 0x08 + +#define PCNET_RD_PTR_OWN 0x80000000 +#define PCNET_RD_PTR_ERR 0x40000000 +#define PCNET_RD_PTR_FRAM 0x20000000 +#define PCNET_RD_PTR_OFLO 0x10000000 +#define PCNET_RD_PTR_CRC 0x08000000 +#define PCNET_RD_PTR_BUFF 0x04000000 +#define PCNET_RD_PTR_STP 0x02000000 +#define PCNET_RD_PTR_ENP 0x01000000 +#define PCNET_RD_PTR_MASK 0x00ffffff +#else + +#define PCNET_RD_PTR 0x00 +#define PCNET_RD_BLEN 0x04 +#define PCNET_RD_MLEN 0x08 +#define PCNET_RD_USER 0x0c +#define PCNET_RD_SIZE 0x10 + +#define PCNET_RD_BLEN_OWN 0x80000000 +#define PCNET_RD_BLEN_ERR 0x40000000 +#define PCNET_RD_BLEN_FRAM 0x20000000 +#define PCNET_RD_BLEN_OFLO 0x10000000 +#define PCNET_RD_BLEN_CRC 0x08000000 +#define PCNET_RD_BLEN_BUFF 0x04000000 +#define PCNET_RD_BLEN_STP 0x02000000 +#define PCNET_RD_BLEN_ENP 0x01000000 +#define PCNET_RD_BLEN_BPE 0x00800000 +#define PCNET_RD_BLEN_PAM 0x00400000 +#define PCNET_RD_BLEN_LAFM 0x00200000 +#define PCNET_RD_BLEN_BAM 0x00100000 +#define PCNET_RD_BLEN_MASK 0x0000ffff +#endif + +// Transmit buffer Descriptor +#if 1 +#define PCNET_TD_PTR 0x00 // 32 bit +#define PCNET_TD_LEN 0x04 // 16 bit (2's complement, negative) +#define PCNET_TD_MISC 0x06 // 16 bit +#define PCNET_TD_SIZE 0x08 + +#define PCNET_TD_PTR_OWN 0x80000000 +#define PCNET_TD_PTR_ERR 0x40000000 +#define PCNET_TD_PTR_ADD_FCS 0x20000000 +#define PCNET_TD_PTR_MORE 0x10000000 +#define PCNET_TD_PTR_ONE 0x08000000 +#define PCNET_TD_PTR_DEF 0x04000000 +#define PCNET_TD_PTR_STP 0x02000000 +#define PCNET_TD_PTR_ENP 0x01000000 +#define PCNET_TD_PTR_MASK 0x00ffffff +#else +#define PCNET_TD_PTR 0x00 +#define PCNET_TD_LEN 0x04 +#define PCNET_TD_MISC 0x08 +#define PCNET_TD_USER 0x0c +#define PCNET_TD_SIZE 0x10 + +#define PCNET_TD_LEN_OWN 0x80000000 +#define PCNET_TD_LEN_ERR 0x40000000 +#define PCNET_TD_LEN_ADD_FCS 0x20000000 +#define PCNET_TD_LEN_MORE 0x10000000 +#define PCNET_TD_LEN_ONE 0x08000000 +#define PCNET_TD_LEN_DEF 0x04000000 +#define PCNET_TD_LEN_STP 0x02000000 +#define PCNET_TD_LEN_ENP 0x01000000 +#define PCNET_TD_LEN_BPE 0x00800000 +#define PCNET_TD_LEN_MASK 0x0000ffff + +#define PCNET_TD_FLAGS_BUFF 0x80000000 +#define PCNET_TD_FLAGS_UFLO 0x40000000 +#define PCNET_TD_FLAGS_EX_DEF 0x20000000 +#define PCNET_TD_FLAGS_LCOL 0x10000000 +#define PCNET_TD_FLAGS_LCAR 0x08000000 +#define PCNET_TD_FLAGS_RTRY 0x04000000 +#define PCNET_TD_FLAGS_TRC_MASK 0x0000000f +#endif + + +#define PCNET_TD_MISC_BUFF 0x8000 +#define PCNET_TD_MISC_UFLO 0x4000 +#define PCNET_TD_MISC_EXDEF 0x2000 +#define PCNET_TD_MISC_LCOL 0x1000 +#define PCNET_TD_MISC_LCAR 0x0800 +#define PCNET_TD_MISC_RTRY 0x0400 +#define PCNET_TD_MISC_TDR 0x03ff + +// Initialization Buffer +#define PCNET_IB_MODE 0 +#define PCNET_IB_PADR0 2 +#define PCNET_IB_PADR1 4 +#define PCNET_IB_PADR2 6 +#define PCNET_IB_LADRF0 8 +#define PCNET_IB_LADRF1 10 +#define PCNET_IB_LADRF2 12 +#define PCNET_IB_LADRF3 14 +#define PCNET_IB_RDRA 16 +#define PCNET_IB_TDRA 20 +#define PCNET_IB_SIZE 24 + +#define PCNET_IB_TDRA_CNT_shift 29 +#define PCNET_IB_TDRA_PTR_mask 0x00ffffff +#define PCNET_IB_RDRA_CNT_shift 29 +#define PCNET_IB_RDRA_PTR_mask 0x00ffffff + +// ------------------------------------------------------------------------ + +#ifdef KEEP_STATISTICS +struct amd_pcnet_stats { + unsigned int tx_good ; + unsigned int tx_max_collisions ; + unsigned int tx_late_collisions ; + unsigned int tx_underrun ; + unsigned int tx_carrier_loss ; + unsigned int tx_deferred ; + unsigned int tx_sqetesterrors ; + unsigned int tx_single_collisions; + unsigned int tx_mult_collisions ; + unsigned int tx_total_collisions ; + unsigned int rx_good ; + unsigned int rx_crc_errors ; + unsigned int rx_align_errors ; + unsigned int rx_resource_errors ; + unsigned int rx_overrun_errors ; + unsigned int rx_collisions ; + unsigned int rx_short_frames ; + unsigned int rx_too_long_frames ; + unsigned int rx_symbol_errors ; + unsigned int interrupts ; + unsigned int rx_count ; + unsigned int rx_deliver ; + unsigned int rx_resource ; + unsigned int rx_restart ; + unsigned int tx_count ; + unsigned int tx_complete ; + unsigned int tx_dropped ; +}; +#endif + +typedef struct pcnet_priv_data { + int index; + cyg_uint8 // (split up for atomic byte access) + found:1, // was hardware discovered? + mac_addr_ok:1, // can we bring up? + active:1, // has this if been brung up? + hardwired_esa:1, // set if ESA is hardwired via CDL + txbusy:1, // A packet has been sent + spare1:3; + + unsigned long txkey; // Used to ack when packet sent + unsigned char* base; // Base address of controller EPROM region + int interrupt; // Interrupt vector used by controller + unsigned char esa[6]; // Controller ESA + // Function to configure the ESA - may fetch ESA from EPROM or + // RedBoot config option. + void (*config_esa)(struct pcnet_priv_data* cpd); + void *ndp; // Network Device Pointer + + cyg_handle_t interrupt_handle; + cyg_interrupt interrupt_object; + int devid; + + cyg_uint8* rx_buffers; // ptr to base of buffer mem + cyg_uint8* rx_ring; // ptr to base of rx ring memory + int rx_ring_cnt; // number of entries in ring + int rx_ring_log_cnt; // log of above + int rx_ring_next; // index of next full ring entry + + cyg_uint8* tx_buffers; + cyg_uint8* tx_ring; + int tx_ring_cnt; + int tx_ring_log_cnt; + int tx_ring_free; // index of next free ring entry + int tx_ring_alloc; // index of first controller owned ring + int tx_ring_owned; // number of controller owned ring entries + + int rxpacket; +#ifdef KEEP_STATISTICS + struct amd_pcnet_stats stats; +#endif +#if DEBUG & 1 + cyg_uint32 txd; +#endif +} pcnet_priv_data; + +// ------------------------------------------------------------------------ + +static __inline__ cyg_uint16 +get_reg(struct eth_drv_sc *sc, int regno) +{ + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + cyg_uint16 val, addr; + + if (regno & PCNET_ANR_FLAG) { + // We could do this with recursive calls to get/put reg + // functions, but might as well just do it directly. + // First set ANR address + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIADDR & PCNET_RAP_MASK); + HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, addr); + addr &= PCNET_BCR_MIIADDR_PHYAD; + addr |= (regno & PCNET_RAP_MASK); + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, addr); + // Then read ANR register data + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIDATA & PCNET_RAP_MASK); + HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, val); + } else { + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, regno & PCNET_RAP_MASK); + if (regno & PCNET_BCR_FLAG) + HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, val); + else + HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_RDP, val); + } +#if DEBUG & 2 + diag_printf("read %s reg %d val 0x%04x\n", + (regno & PCNET_ANR_FLAG) ? "anr" : (regno & PCNET_BCR_FLAG) ? "bcr" : "csr", + regno & PCNET_RAP_MASK, val); +#endif + return val; +} + +static __inline__ void +put_reg(struct eth_drv_sc *sc, int regno, cyg_uint16 val) +{ + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + cyg_uint16 addr; + + if (regno & PCNET_ANR_FLAG) { + // We could do this with recursive calls to get/put reg + // functions, but might as well just do it directly. + // First set ANR address + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIADDR & PCNET_RAP_MASK); + HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, addr); + addr &= PCNET_BCR_MIIADDR_PHYAD; + addr |= (regno & PCNET_RAP_MASK); + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, addr); + // Then write ANR register data + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIDATA & PCNET_RAP_MASK); + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, val); + } else { + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, regno & PCNET_RAP_MASK); + if (regno & PCNET_BCR_FLAG) + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, val); + else + HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RDP, val); + } + +#if DEBUG & 2 + diag_printf("write %s reg %d val 0x%04x\n", + (regno & PCNET_ANR_FLAG) ? "anr" : (regno & PCNET_BCR_FLAG) ? "bcr" : "csr", + regno & PCNET_RAP_MASK, val); +#endif +} + +// ------------------------------------------------------------------------ +#endif CYGONCE_DEVS_ETH_AMD_PCNET_H +// EOF amd_pcnet.h
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c @@ -0,0 +1,1244 @@ +//========================================================================== +// +// dev/if_pcnet.c +// +// Ethernet device driver for AMD PCNET compatible controllers +// +//========================================================================== +//####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, 2001 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//####BSDCOPYRIGHTBEGIN#### +// +// ------------------------------------------- +// +// Portions of this software may have been derived from OpenBSD or other sources, +// and are covered by the appropriate copyright disclaimers included herein. +// +// ------------------------------------------- +// +//####BSDCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov, based on lan91cxx driver by hmt & jskov +// Contributors: gthomas, jskov, hmt +// Date: 2001-04-02 +// Purpose: +// Description: hardware driver for AMD PCNet (and possibly Lance) ethernet +// Notes: The controller is used in its 16bit mode. That means that +// all addresses are 24bit only - and that all controller +// accessed memory must be within the same 16MB region +// (starting at 0 on older controllers). +// +// The KEEP_STATISTICS code is not implemented yet. Look +// for FIXME macro. +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include <pkgconf/system.h> +#include <pkgconf/devs_eth_amd_pcnet.h> +#include <cyg/infra/cyg_type.h> +#include <cyg/hal/hal_arch.h> +#include <cyg/hal/hal_intr.h> +#include <cyg/infra/cyg_ass.h> +#include <cyg/infra/diag.h> +#include <cyg/hal/drv_api.h> +#include <cyg/hal/hal_if.h> // delays +#include <netdev.h> +#include <eth_drv.h> +#ifdef CYGPKG_NET +#include <pkgconf/net.h> +#include <cyg/kernel/kapi.h> +#include <net/if.h> /* Needed for struct ifnet */ +#include <pkgconf/io_eth_drivers.h> +#endif +#include CYGHWR_MEMORY_LAYOUT_H + +#ifdef CYGPKG_IO_PCI +#include <cyg/io/pci.h> +#else +#error "Need PCI package here" +#endif + +#define FIXME 0 + +#define _BUF_SIZE 1544 + +#ifdef CYGPKG_INFRA_DEBUG +// Then we log, OOI, the number of times we get a bad packet number +// from the tx done fifo. +int pcnet_txfifo_good = 0; +int pcnet_txfifo_bad = 0; +#endif + +#include "amd_pcnet.h" +#define __WANT_DEVS +#include CYGDAT_DEVS_ETH_AMD_PCNET_INL +#undef __WANT_DEVS + +static void pcnet_poll(struct eth_drv_sc *sc); + +// This ISR is called when the ethernet interrupt occurs +static cyg_uint32 +pcnet_isr(cyg_vector_t vector, cyg_addrword_t data) +{ + struct pcnet_priv_data *cpd = (struct pcnet_priv_data *)data; + + DEBUG_FUNCTION(); + + INCR_STAT( interrupts ); + + cyg_drv_interrupt_mask(cpd->interrupt); + cyg_drv_interrupt_acknowledge(cpd->interrupt); + return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR +} + +static void +pcnet_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + // This conditioning out is necessary because of explicit calls to this + // DSR - which would not ever be called in the case of a polled mode + // usage ie. in RedBoot. +#ifdef CYGPKG_IO_ETH_DRIVERS_NET + struct pcnet_priv_data* cpd = (struct pcnet_priv_data *)data; + struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp); + struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance); + + // but here, it must be a *sc: + eth_drv_dsr( vector, count, (cyg_addrword_t)sc ); +#else +# ifndef CYGPKG_REDBOOT +# error Empty PCnet ethernet DSR is compiled. Is this what you want? +# endif +#endif +} + + +// The deliver function (ex-DSR) handles the ethernet [logical] processing +static void +pcnet_deliver(struct eth_drv_sc *sc) +{ + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + + DEBUG_FUNCTION(); + + // Service the interrupt: + pcnet_poll(sc); + // Allow interrupts to happen again + cyg_drv_interrupt_unmask(cpd->interrupt); +} + +static int +pcnet_int_vector(struct eth_drv_sc *sc) +{ + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + + return (cpd->interrupt); +} + +// ------------------------------------------------------------------------ +// Memory management +// +// Simply carve off from the front of the PCI mapped window into real memory +static cyg_uint32 pcnet_heap_size; +static cyg_uint8 *pcnet_heap_base; +static cyg_uint8 *pcnet_heap_free; + +static void* +pciwindow_mem_alloc(int size) +{ + void *p_memory; + int _size = size; + + CYG_ASSERT( + (CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE <= (int)pcnet_heap_free) + && + ((CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE + + CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE) > (int)pcnet_heap_free) + && + (0 < pcnet_heap_size) + && + (CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE >= pcnet_heap_size) + && + (CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE == (int)pcnet_heap_base), + "Heap variables corrupted" ); + + p_memory = (void *)0; + size = (size + 3) & ~3; + if ( (pcnet_heap_free+size) < (pcnet_heap_base+pcnet_heap_size) ) { + cyg_uint32 *p; + p_memory = (void *)pcnet_heap_free; + pcnet_heap_free += size; + for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 ) + *p++ = 0; + } + +#if DEBUG & 9 + diag_printf("Allocated %d bytes at 0x%08x\n", size, p_memory); +#endif + + return p_memory; +} + +static cyg_pci_match_func find_pcnet_match_func; + +static cyg_bool +find_pcnet_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p ) +{ +#if DEBUG & 9 + diag_printf("PCI match vendor 0x%04x device 0x%04x\n", v, d); +#endif + return (0x1022 == v) && (0x2000 == d); +} + +static int +pci_init_find_pcnet( void ) +{ + cyg_pci_device_id devid; + cyg_pci_device dev_info; + cyg_uint16 cmd; + int device_index; + int found_devices = 0; + + DEBUG_FUNCTION(); + +#ifdef CYGARC_UNCACHED_ADDRESS + CYG_ASSERT( CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) == + CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE, + "PCI window configured does not match PCI memory section base" ); +#else + CYG_ASSERT( (CYG_ADDRWORD)CYGMEM_SECTION_pci_window == + CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE, + "PCI window configured does not match PCI memory section base" ); +#endif + CYG_ASSERT( CYGMEM_SECTION_pci_window_SIZE == + CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE, + "PCI window configured does not match PCI memory section size" ); + + if ( +#ifdef CYGARC_UNCACHED_ADDRESS + CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) != +#else + (CYG_ADDRWORD)CYGMEM_SECTION_pci_window != +#endif + CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE + || + CYGMEM_SECTION_pci_window_SIZE != + CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE ) { +#if DEBUG & 8 + diag_printf("pci_init_find_pcnets(): PCI window misconfigured\n"); +#endif + return 0; + } + + // First initialize the heap in PCI window'd memory + pcnet_heap_size = CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE; + pcnet_heap_base = (cyg_uint8 *)CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE; + pcnet_heap_free = pcnet_heap_base; +#if DEBUG & 9 + diag_printf("pcimem : 0x%08x size: 0x%08x\n", pcnet_heap_base, pcnet_heap_size); +#endif + + cyg_pci_init(); +#if DEBUG & 8 + diag_printf("Finished cyg_pci_init();\n"); +#endif + + devid = CYG_PCI_NULL_DEVID; + + for (device_index = 0; + device_index < CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT; + device_index++) { + struct pcnet_priv_data* cpd = pcnet_priv_array[device_index]; + + cpd->index = device_index; + + // See above for find_pcnet_match_func - it selects any of several + // variants. This is necessary in case we have multiple mixed-type + // devices on one board in arbitrary orders. + if (cyg_pci_find_matching( &find_pcnet_match_func, NULL, &devid )) { +#if DEBUG & 8 + diag_printf("eth%d = pcnet\n", device_index); +#endif + cyg_pci_get_device_info(devid, &dev_info); + + cpd->interrupt_handle = 0; // Flag not attached. + if (cyg_pci_translate_interrupt(&dev_info, &cpd->interrupt)) { +#if DEBUG & 8 + diag_printf(" Wired to HAL vector %d\n", cpd->interrupt); +#endif + cyg_drv_interrupt_create( + cpd->interrupt, + 1, // Priority - unused + (cyg_addrword_t)cpd,// Data item passed to ISR & DSR + pcnet_isr, // ISR + pcnet_dsr, // DSR + &cpd->interrupt_handle, // handle to intr obj + &cpd->interrupt_object ); // space for int obj + + cyg_drv_interrupt_attach(cpd->interrupt_handle); + + // Don't unmask the interrupt yet, that could get us into a + // race. + } + else { + cpd->interrupt = 0; +#if DEBUG & 8 + diag_printf(" Does not generate interrupts.\n"); +#endif + } + + if (cyg_pci_configure_device(&dev_info)) { +#if DEBUG & 8 + int i; + diag_printf("Found device on bus %d, devfn 0x%02x:\n", + CYG_PCI_DEV_GET_BUS(devid), + CYG_PCI_DEV_GET_DEVFN(devid)); + + if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) { + diag_printf(" Note that board is active. Probed" + " sizes and CPU addresses invalid!\n"); + } + diag_printf(" Vendor 0x%04x", dev_info.vendor); + diag_printf("\n Device 0x%04x", dev_info.device); + diag_printf("\n Command 0x%04x, Status 0x%04x\n", + dev_info.command, dev_info.status); + + diag_printf(" Class/Rev 0x%08x", dev_info.class_rev); + diag_printf("\n Header 0x%02x\n", dev_info.header_type); + + diag_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n", + dev_info.header.normal.sub_vendor, + dev_info.header.normal.sub_id); + + for(i = 0; i < CYG_PCI_MAX_BAR; i++) { + diag_printf(" BAR[%d] 0x%08x /", i, dev_info.base_address[i]); + diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n", + dev_info.base_size[i], dev_info.base_map[i]); + } + diag_printf(" eth%d configured\n", device_index); +#endif + found_devices++; + cpd->found = 1; + cpd->active = 0; + cpd->devid = devid; + cpd->base = (unsigned char*) dev_info.base_map[0]; +#if DEBUG & 8 + diag_printf(" I/O address = 0x%08x\n", cpd->base); +#endif + + // Don't use cyg_pci_set_device_info since it clears + // some of the fields we want to print out below. + cyg_pci_read_config_uint16(dev_info.devid, + CYG_PCI_CFG_COMMAND, &cmd); + cmd |= (CYG_PCI_CFG_COMMAND_IO // enable I/O space + | CYG_PCI_CFG_COMMAND_MEMORY // enable memory space + | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master + cyg_pci_write_config_uint16(dev_info.devid, + CYG_PCI_CFG_COMMAND, cmd); + + // This is the indicator for "uses an interrupt" + if (cpd->interrupt_handle != 0) { + cyg_drv_interrupt_acknowledge(cpd->interrupt); + cyg_drv_interrupt_unmask(cpd->interrupt); +#if DEBUG & 8 + diag_printf(" Enabled interrupt %d\n", cpd->interrupt); +#endif + } +#if DEBUG & 8 + diag_printf(" **** Device enabled for I/O and Memory " + "and Bus Master\n"); +#endif + } + else { + cpd->found = 0; + cpd->active = 0; +#if DEBUG & 8 + diag_printf("Failed to configure device %d\n", device_index); +#endif + } + } + else { + cpd->found = 0; + cpd->active = 0; +#if DEBUG & 8 + diag_printf("eth%d not found\n", device_index); +#endif + } + } + + if (0 == found_devices) + return 0; + + return 1; +} + + +static bool +amd_pcnet_init(struct cyg_netdevtab_entry *tab) +{ + static int initialized = 0; // only probe PCI et al *once* + struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + cyg_uint16 val; + cyg_uint32 b; + cyg_uint8* p; + cyg_uint8* d; + cyg_uint8* init_table; + int i; + + DEBUG_FUNCTION(); + + + if ( 0 == initialized++ ) { + // then this is the first time ever: + if ( ! pci_init_find_pcnet() ) { +#if DEBUG & 8 + diag_printf( "pci_init_find_pcnet failed" ); +#endif + return false; + } + } + + // If this device is not present, exit + if (0 == cpd->found) + return 0; + + cpd->txbusy = 0; + +#if DEBUG & 8 + diag_printf("PCNet at base 0x%08x, EEPROM key 0x%04x\n", + cpd->base, _SU16(cpd->base, PCNET_IO_ID)); +#endif + +#if 0 + // FIXME: Doesn't work with non-conforming EEPROMS + if (PCNET_IO_ID_KEY != _SU16(cpd->base, PCNET_IO_ID) ) { + diag_printf("PCNet EPROM key not found\n"); + return false; + } +#endif + +#if DEBUG & 9 + diag_printf("pcimem : %08x size: %08x\n", pcnet_heap_base, pcnet_heap_size); +#endif + + // Prepare ESA + if (!cpd->hardwired_esa) { + // Use the address from the serial EEPROM + p = cpd->base + PCNET_IO_EEPROM; + for (i = 0; i < 6; i++) + cpd->esa[i] = *p++; + } +#if DEBUG & 9 + diag_printf("PCNET - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", + (cpd->hardwired_esa) ? "static" : "eeprom", + cpd->esa[0], cpd->esa[1], cpd->esa[2], + cpd->esa[3], cpd->esa[4], cpd->esa[5] ); +#endif + + // Prepare RX and TX rings + p = cpd->rx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->rx_ring_log_cnt)*PCNET_RD_SIZE)); + d = cpd->rx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->rx_ring_cnt)); + for (i = 0; i < cpd->rx_ring_cnt; i++) { + HAL_PCI_CPU_TO_BUS(d, b); + _SU32(p, PCNET_RD_PTR) = (b & PCNET_RD_PTR_MASK) | PCNET_RD_PTR_OWN; + _SU16(p, PCNET_RD_BLEN) = (-_BUF_SIZE); + p += PCNET_RD_SIZE; + d += _BUF_SIZE; + } + cpd->rx_ring_next = 0; + + p = cpd->tx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc((1<<cpd->tx_ring_log_cnt)*PCNET_TD_SIZE)); + d = cpd->tx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(_BUF_SIZE*cpd->tx_ring_cnt)); + for (i = 0; i < cpd->tx_ring_cnt; i++) { + HAL_PCI_CPU_TO_BUS(d, b); + _SU32(p, PCNET_RD_PTR) = b & PCNET_TD_PTR_MASK; + p += PCNET_TD_SIZE; + d += _BUF_SIZE; + } + cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0; + + // Initialization table + init_table = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS((cyg_uint32)pciwindow_mem_alloc(PCNET_IB_SIZE)); + _SU16(init_table, PCNET_IB_MODE) = 0x0000; + for (i = 0; i < 6; i++) + _SU8(init_table, PCNET_IB_PADR0+i) = cpd->esa[i]; + for (i = 0; i < 8; i++) + _SU8(init_table, PCNET_IB_LADRF0+i) = 0; + + HAL_PCI_CPU_TO_BUS(cpd->rx_ring, b); + _SU32(init_table, PCNET_IB_RDRA) = ((b & PCNET_IB_RDRA_PTR_mask) + | (cpd->rx_ring_log_cnt << PCNET_IB_RDRA_CNT_shift)); + HAL_PCI_CPU_TO_BUS(cpd->tx_ring, b); + _SU32(init_table, PCNET_IB_TDRA) = ((b & PCNET_IB_TDRA_PTR_mask) + | (cpd->tx_ring_log_cnt << PCNET_IB_TDRA_CNT_shift)); + +#if DEBUG & 9 + diag_printf("Loading up PCNet controller from table at 0x%08x\n", init_table); + diag_printf(" Mode 0x%04x\n", _SU16(init_table, PCNET_IB_MODE)); + diag_printf(" PADR %02x:%02x:%02x:%02x:%02x:%02x ", + _SU8(init_table, PCNET_IB_PADR0+0), _SU8(init_table, PCNET_IB_PADR0+1), + _SU8(init_table, PCNET_IB_PADR0+2), _SU8(init_table, PCNET_IB_PADR0+3), + _SU8(init_table, PCNET_IB_PADR0+4), _SU8(init_table, PCNET_IB_PADR0+5)); + diag_printf("LADR %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + _SU8(init_table, PCNET_IB_LADRF0+0), _SU8(init_table, PCNET_IB_LADRF0+1), + _SU8(init_table, PCNET_IB_LADRF0+2), _SU8(init_table, PCNET_IB_LADRF0+3), + _SU8(init_table, PCNET_IB_LADRF0+4), _SU8(init_table, PCNET_IB_LADRF0+5), + _SU8(init_table, PCNET_IB_LADRF0+5), _SU8(init_table, PCNET_IB_LADRF0+7)); + diag_printf(" RX 0x%08x (len %d) TX 0x%08x (len %d)\n", + _SU32(init_table, PCNET_IB_RDRA) & 0x1fffffff, + (_SU32(init_table, PCNET_IB_RDRA) >> PCNET_IB_RDRA_CNT_shift) & 7, + _SU32(init_table, PCNET_IB_TDRA) & 0x1fffffff, + (_SU32(init_table, PCNET_IB_TDRA) >> PCNET_IB_TDRA_CNT_shift) & 7); +#endif + + // Reset chip + HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_RESET, val); + + // Load up chip with buffers. + // Note: There is a 16M limit on the addresses used by the driver + // since the top 8 bits of the init_table address is appended to + // all other addresses used by the controller. + HAL_PCI_CPU_TO_BUS(init_table, b); + put_reg(sc, PCNET_CSR_IBA0, (b >> 0) & 0xffff); + put_reg(sc, PCNET_CSR_IBA1, (b >> 16) & 0xffff); + // Disable automatic TX polling (_send will force a poll), pad + // XT frames to legal length, mask status interrupts. + put_reg(sc, PCNET_CSR_TFC, (PCNET_CSR_TFC_TXDPOLL | PCNET_CSR_TFC_APAD_XMT + | PCNET_CSR_TFC_MFCOM | PCNET_CSR_TFC_RCVCCOM + | PCNET_CSR_TFC_TXSTRTM)); + // Recover after TX FIFO underflow + put_reg(sc, PCNET_CSR_IM, PCNET_CSR_IM_DXSUFLO); + // Initialize controller - load up init_table + put_reg(sc, PCNET_CSR_CSCR, PCNET_CSR_CSCR_INIT); + while (0 == (get_reg(sc, PCNET_CSR_CSCR) & PCNET_CSR_CSCR_IDON)); + + // Stop controller + put_reg(sc, PCNET_CSR_CSCR, PCNET_CSR_CSCR_STOP); + +#if DEBUG & 9 + diag_printf("PCNet controller state is now:\n"); + diag_printf(" Mode 0x%04x TFC 0x%04x\n", _SU16(init_table, PCNET_IB_MODE), get_reg(sc, PCNET_CSR_TFC)); + diag_printf(" PADR %04x:%04x:%04x ", + get_reg(sc, PCNET_CSR_PAR0), + get_reg(sc, PCNET_CSR_PAR1), + get_reg(sc, PCNET_CSR_PAR2)); + diag_printf("LADR %04x:%04x:%04x:%04x\n", + get_reg(sc, PCNET_CSR_LAR0), + get_reg(sc, PCNET_CSR_LAR1), + get_reg(sc, PCNET_CSR_LAR2), + get_reg(sc, PCNET_CSR_LAR3)); + diag_printf(" RX 0x%04x%04x (len 0x%04x) TX 0x%04x%04x (len 0x%04x)\n", + get_reg(sc, PCNET_CSR_BARRU), get_reg(sc, PCNET_CSR_BARRL), + get_reg(sc, PCNET_CSR_RRLEN), + get_reg(sc, PCNET_CSR_BATRU), get_reg(sc, PCNET_CSR_BATRL), + get_reg(sc, PCNET_CSR_TRLEN)); + + val = get_reg(sc, PCNET_CSR_ID_LO); + diag_printf("PCnet ID 0x%04x (%s) ", + val, + (0x5003 == val) ? "Am79C973" : (0x7003 == val) ? "Am79C975" : "Unknown"); + val = get_reg(sc, PCNET_CSR_ID_HI); + diag_printf("Part IDU 0x%03x Silicon rev %d\n", + val & 0x0fff, (val >> 12) & 0xf); +#endif + + // and record the net dev pointer + cpd->ndp = (void *)tab; + + // Start controller, but put it in suspended mode + put_reg(sc, PCNET_CSR_CSCR, PCNET_CSR_CSCR_STOP); + put_reg(sc, PCNET_CSR_CSCR, (PCNET_CSR_CSCR_IENA | PCNET_CSR_CSCR_STRT)); + i = 0; + while (0 == (PCNET_CSR_CSCR_STRT & get_reg(sc, PCNET_CSR_CSCR))) { + CYGACC_CALL_IF_DELAY_US(1000); + put_reg(sc, PCNET_CSR_CSCR, (PCNET_CSR_CSCR_IENA | PCNET_CSR_CSCR_STRT)); + if (i++ == 1000) { +#if DEBUG & 9 + diag_printf("Failed to start the controller\n"); +#endif + return false; + } + } + + val = get_reg(sc, PCNET_CSR_ECI); + val |= PCNET_CSR_ECI_SPND; + put_reg(sc, PCNET_CSR_ECI, val); + // Wait for device to suspend + do { + val = get_reg(sc, PCNET_CSR_ECI); + } while (0 == (val & PCNET_CSR_ECI_SPND)); + cpd->active = 0; + + // Initialize upper level driver + (sc->funs->eth_drv->init)(sc, cpd->esa); + +#if DEBUG & 9 + diag_printf("Done\n"); +#endif + return true; +} + +static void +pcnet_stop(struct eth_drv_sc *sc) +{ + cyg_uint16 reg; + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + + DEBUG_FUNCTION(); + + reg = get_reg(sc, PCNET_CSR_ECI); + reg |= PCNET_CSR_ECI_SPND; + put_reg(sc, PCNET_CSR_ECI, reg); + // Wait for device to suspend + do { + reg = get_reg(sc, PCNET_CSR_ECI); + } while (0 == (reg & PCNET_CSR_ECI_SPND)); + cpd->active = 0; +} + +// +// This function is called to "start up" the interface. It may be called +// multiple times, even when the hardware is already running. It will be +// called whenever something "hardware oriented" changes and should leave +// the hardware ready to send/receive packets. +// +static void +pcnet_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags) +{ + cyg_uint16 reg; + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; +#ifdef CYGPKG_NET + struct ifnet *ifp = &sc->sc_arpcom.ac_if; +#endif + DEBUG_FUNCTION(); + + // If device is already active, suspend it + if (cpd->active) { + reg = get_reg(sc, PCNET_CSR_ECI); + reg |= PCNET_CSR_ECI_SPND; + put_reg(sc, PCNET_CSR_ECI, reg); + // Wait for device to suspend + do { + reg = get_reg(sc, PCNET_CSR_ECI); + } while (0 == (reg & PCNET_CSR_ECI_SPND)); + cpd->active = 0; + } + +#ifdef CYGPKG_NET + if (( 0 +#ifdef ETH_DRV_FLAGS_PROMISC_MODE + != (flags & ETH_DRV_FLAGS_PROMISC_MODE) +#endif + ) || (ifp->if_flags & IFF_PROMISC) + ) { + // Then we select promiscuous mode. + cyg_uint16 rcr; + rcr = get_reg(sc, PCNET_CSR_MODE ); + rcr |= PCNET_CSR_MODE_PROM; + put_reg(sc, PCNET_CSR_MODE, rcr ); + } +#endif + + // Unsuspend the device + reg = get_reg(sc, PCNET_CSR_ECI); + reg &= ~PCNET_CSR_ECI_SPND; + put_reg(sc, PCNET_CSR_ECI, reg); + cpd->active = 1; +} + +// +// This routine is called to perform special "control" opertions +// +static int +pcnet_control(struct eth_drv_sc *sc, unsigned long key, + void *data, int data_length) +{ + cyg_uint8 *esa = (cyg_uint8 *)data; + int i, res; + cyg_uint16 reg; + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + cyg_bool was_active = cpd->active; + + DEBUG_FUNCTION(); + + // If device is already active, suspend it + if (cpd->active) { + reg = get_reg(sc, PCNET_CSR_ECI); + reg |= PCNET_CSR_ECI_SPND; + put_reg(sc, PCNET_CSR_ECI, reg); + // Wait for device to suspend + do { + reg = get_reg(sc, PCNET_CSR_ECI); + } while (0 == (reg & PCNET_CSR_ECI_SPND)); + cpd->active = 0; + } + + res = 0; // expect success + switch (key) { + case ETH_DRV_SET_MAC_ADDRESS: +#if 9 & DEBUG + diag_printf("PCNET - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", + esa[0], esa[1], esa[2], esa[3], esa[4], esa[5] ); +#endif // DEBUG + + for ( i = 0; i < sizeof(cpd->esa); i++ ) + cpd->esa[i] = esa[i]; + for (i = 0; i < sizeof(cpd->esa); i += 2) { + reg = cpd->esa[i] | (cpd->esa[i+1] << 8); + put_reg(sc, PCNET_CSR_PAR0+i/2, reg ); + } + break; + +#ifdef ETH_DRV_GET_MAC_ADDRESS + case ETH_DRV_GET_MAC_ADDRESS: + // Extract the MAC address that is in the chip, and tell the + // system about it. + for (i = 0; i < sizeof(cpd->esa); i += 2) { + cyg_uint16 z = get_reg(sc, PCNET_CSR_PAR0+i/2 ); + esa[i] = (cyg_uint8)(0xff & z); + esa[i+1] = (cyg_uint8)(0xff & (z >> 8)); + } + break; +#endif + +#ifdef ETH_DRV_GET_IF_STATS_UD + case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE +#endif + // drop through +#ifdef ETH_DRV_GET_IF_STATS + case ETH_DRV_GET_IF_STATS: +#endif + +#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD) + { + cyg_uint16 anr; + struct ether_drv_stats *p = (struct ether_drv_stats *)data; + // Chipset entry is no longer supported; RFC1573. + for ( i = 0; i < SNMP_CHIPSET_LEN; i++ ) + p->snmp_chipset[i] = 0; + + // This perhaps should be a config opt, so you can make up your own + // description, or supply it from the instantiation. + strcpy( p->description, "AMD PCNet" ); + // CYG_ASSERT( 48 > strlen(p->description), "Description too long" ); + + anr = get_reg(sc, PCNET_ANR_PHYSTAT); + if ((anr & PCNET_ANR_PHYSTAT_LINK) == 0) { + p->operational = 2; // LINK DOWN + p->duplex = 1; // UNKNOWN + p->speed = 0; + } + else { + p->operational = 3; // LINK UP + anr = get_reg(sc, PCNET_ANR_PHYCTRL); + + if (anr & PCNET_ANR_PHYCTRL_DUPLEX) + p->duplex = 3; // 3 = DUPLEX + else + p->duplex = 2; // 2 = SIMPLEX + p->speed = (anr & PCNET_ANR_PHYCTRL_100MBPS) ? 100 * 1000000 : 10 * 1000000; + } + +#if FIXME +#ifdef KEEP_STATISTICS + { + struct amd_pcnet_stats *ps = &(cpd->stats); + + // Admit to it... + p->supports_dot3 = true; + + p->tx_good = ps->tx_good ; + p->tx_max_collisions = ps->tx_max_collisions ; + p->tx_late_collisions = ps->tx_late_collisions ; + p->tx_underrun = ps->tx_underrun ; + p->tx_carrier_loss = ps->tx_carrier_loss ; + p->tx_deferred = ps->tx_deferred ; + p->tx_sqetesterrors = ps->tx_sqetesterrors ; + p->tx_single_collisions = ps->tx_single_collisions; + p->tx_mult_collisions = ps->tx_mult_collisions ; + p->tx_total_collisions = ps->tx_total_collisions ; + p->rx_good = ps->rx_good ; + p->rx_crc_errors = ps->rx_crc_errors ; + p->rx_align_errors = ps->rx_align_errors ; + p->rx_resource_errors = ps->rx_resource_errors ; + p->rx_overrun_errors = ps->rx_overrun_errors ; + p->rx_collisions = ps->rx_collisions ; + p->rx_short_frames = ps->rx_short_frames ; + p->rx_too_long_frames = ps->rx_too_long_frames ; + p->rx_symbol_errors = ps->rx_symbol_errors ; + + p->interrupts = ps->interrupts ; + p->rx_count = ps->rx_count ; + p->rx_deliver = ps->rx_deliver ; + p->rx_resource = ps->rx_resource ; + p->rx_restart = ps->rx_restart ; + p->tx_count = ps->tx_count ; + p->tx_complete = ps->tx_complete ; + p->tx_dropped = ps->tx_dropped ; + } +#endif // KEEP_STATISTICS +#endif // FIXME + + p->tx_queue_len = 1; + break; + } +#endif + default: + res = 1; + break; + } + + // Restore controller state + if (was_active) { + // Unsuspend the device + reg = get_reg(sc, PCNET_CSR_ECI); + reg &= ~PCNET_CSR_ECI_SPND; + put_reg(sc, PCNET_CSR_ECI, reg); + } + + return res; +} + +// +// This routine is called to see if it is possible to send another packet. +// It will return non-zero if a transmit is possible, zero otherwise. +// +static int +pcnet_can_send(struct eth_drv_sc *sc) +{ + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + cyg_uint16 stat; + + DEBUG_FUNCTION(); + + stat = get_reg(sc, PCNET_ANR_PHYSTAT); + if ((stat & PCNET_ANR_PHYSTAT_LINK) == 0) { + return 0; // Link not connected + } + + return (0 == cpd->txbusy); +} + +// +// This routine is called to send data to the hardware. +static void +pcnet_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, + int total_len, unsigned long key) +{ + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + int i, len, plen, ring_entry; + + cyg_uint8* sdata = NULL; + cyg_uint8 *d, *buf, *txd; + cyg_uint16 ints; + cyg_uint32 b; + + DEBUG_FUNCTION(); + + INCR_STAT( tx_count ); + + cpd->txbusy = 1; + cpd->txkey = key; + + // Find packet length + plen = 0; + for (i = 0; i < sg_len; i++) + plen += sg_list[i].len; + + CYG_ASSERT( plen == total_len, "sg data length mismatch" ); + + // Get next TX descriptor + ring_entry = cpd->tx_ring_free; + do { + if (cpd->tx_ring_owned == cpd->tx_ring_cnt) { + // Is this a dead end? Probably is. +#if DEBUG & 1 + diag_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ ); +#endif + continue; + } + + cpd->tx_ring_free++; + cpd->tx_ring_owned++; + if (cpd->tx_ring_free == cpd->tx_ring_cnt) + cpd->tx_ring_free = 0; + } while (0); + + txd = cpd->tx_ring + ring_entry*PCNET_TD_SIZE; + buf = cpd->tx_buffers + ring_entry*_BUF_SIZE; + CYG_ASSERT(0 == (_SU32(txd, PCNET_TD_PTR) & PCNET_TD_PTR_OWN), + "TX descriptor not free"); + +#if DEBUG & 4 + diag_printf("#####Tx descriptor 0x%08x buffer 0x%08x\n", + txd, buf); +#endif + + // Put data into buffer + d = buf; + for (i = 0; i < sg_len; i++) { + sdata = (cyg_uint8 *)sg_list[i].buf; + len = sg_list[i].len; + + CYG_ASSERT( sdata, "No sg data pointer here" ); + while(len--) + *d++ = *sdata++; + } + CYG_ASSERT( sdata, "No sg data pointer outside" ); + +#if DEBUG & 1 + diag_printf("CSCR %04x\n", get_reg(sc, PCNET_CSR_CSCR)); +#endif + _SU16(txd, PCNET_TD_LEN) = (-plen); + _SU16(txd, PCNET_TD_MISC) = 0; + HAL_PCI_CPU_TO_BUS(buf, b); + _SU32(txd, PCNET_TD_PTR) = ((b & PCNET_TD_PTR_MASK) + | PCNET_TD_PTR_OWN | PCNET_TD_PTR_STP | PCNET_TD_PTR_ENP); + +#if DEBUG & 1 + cpd->txd = txd; + diag_printf("Last TX: LEN %04x MISC %04x PTR %08x\n", + _SU16(cpd->txd, PCNET_TD_LEN), + _SU16(cpd->txd, PCNET_TD_MISC), + _SU32(cpd->txd, PCNET_TD_PTR)); +#endif + + // Set transmit demand + ints = get_reg(sc, PCNET_CSR_CSCR); + ints &= PCNET_CSR_CSCR_EV_MASK; + ints |= PCNET_CSR_CSCR_TDMD; + put_reg(sc, PCNET_CSR_CSCR, ints); + +#if DEBUG & 1 + ints = get_reg(sc, PCNET_CSR_CSCR); + diag_printf("%s:END: ints at TX: 0x%04x\n", __FUNCTION__, ints); +#endif +} + +static void +pcnet_TxEvent(struct eth_drv_sc *sc, int stat) +{ + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + int success = 1; + cyg_uint8 *txd; + cyg_uint16 ints; + cyg_uint32 pkt_stat; + + DEBUG_FUNCTION(); + + INCR_STAT( tx_complete ); + + txd = cpd->tx_ring + cpd->tx_ring_alloc*PCNET_TD_SIZE; + pkt_stat = _SU32(txd, PCNET_TD_PTR); + if (pkt_stat & PCNET_TD_PTR_OWN) { +#if DEBUG & 1 + diag_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__); +#endif + // first dirty ring entry not freed - wtf? + } + + if (pkt_stat & PCNET_TD_PTR_ERR) { + // We had an error. Tell the stack. + success = 0; +#if DEBUG & 1 + diag_printf("%s: TX failure, retrying...\n", __FUNCTION__); +#endif + } + + cpd->tx_ring_alloc++; + if (cpd->tx_ring_alloc == cpd->tx_ring_cnt) + cpd->tx_ring_alloc = 0; + cpd->tx_ring_owned--; + +#if FIXME +#ifdef KEEP_STATISTICS + { + cyg_uint16 reg; + + reg = get_reg( sc, PCNET_CSR_CSCR ); + + // Covering each bit in turn... + if ( reg & PCNET_STATUS_TX_UNRN ) INCR_STAT( tx_underrun ); + //if ( reg & PCNET_STATUS_LINK_OK ) INCR_STAT( ); + //if ( reg & PCNET_STATUS_CTR_ROL ) INCR_STAT( ); + //if ( reg & PCNET_STATUS_EXC_DEF ) INCR_STAT( ); + if ( reg & PCNET_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss ); + if ( reg & PCNET_STATUS_LATCOL ) INCR_STAT( tx_late_collisions ); + //if ( reg & PCNET_STATUS_WAKEUP ) INCR_STAT( ); + if ( reg & PCNET_STATUS_TX_DEFR ) INCR_STAT( tx_deferred ); + //if ( reg & PCNET_STATUS_LTX_BRD ) INCR_STAT( ); + if ( reg & PCNET_STATUS_SQET ) INCR_STAT( tx_sqetesterrors ); + if ( reg & PCNET_STATUS_16COL ) INCR_STAT( tx_max_collisions ); + //if ( reg & PCNET_STATUS_LTX_MULT) INCR_STAT( ); + if ( reg & PCNET_STATUS_MUL_COL ) INCR_STAT( tx_mult_collisions ); + if ( reg & PCNET_STATUS_SNGL_COL ) INCR_STAT( tx_single_collisions ); + if ( reg & PCNET_STATUS_TX_SUC ) INCR_STAT( tx_good ); + + cpd->stats.tx_total_collisions = + cpd->stats.tx_late_collisions + + cpd->stats.tx_max_collisions + + cpd->stats.tx_mult_collisions + + cpd->stats.tx_single_collisions; + + // We do not need to look in the Counter Register (PCNET_COUNTER) + // because it just mimics the info we already have above. + } +#endif // KEEP_STATISTICS +#endif // FIXME + + // Ack the TX int which clears the packet from the TX completion + // queue. + ints = get_reg(sc, PCNET_CSR_CSCR); + ints |= PCNET_CSR_CSCR_TINT; + put_reg(sc, PCNET_CSR_CSCR, ints); + +#if DEBUG & 4 + diag_printf("#####Tx packet freed 0x%08x\n", txd ); +#endif + + if ( cpd->txbusy ) { + cpd->txbusy = 0; + (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success); + } +} + + +// +// This function is called when a packet has been received. Its job is +// to prepare to unload the packet from the hardware. Once the length of +// the packet is known, the upper layer of the driver can be told. When +// the upper layer is ready to unload the packet, the internal function +// 'pcnet_recv' will be called to actually fetch it from the hardware. +// +static void +pcnet_RxEvent(struct eth_drv_sc *sc) +{ + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + cyg_uint8 *rxd; + cyg_uint32 rstat; + cyg_uint16 ints, len; + + DEBUG_FUNCTION(); + + ints = get_reg(sc, PCNET_CSR_CSCR); +#if DEBUG & 1 + diag_printf("RxEvent - CSR: 0x%04x\n", ints); +#endif + + while (1) { + // Get state of next (supposedly) full ring entry + cpd->rxpacket = cpd->rx_ring_next; + rxd = cpd->rx_ring + cpd->rxpacket*PCNET_RD_SIZE; + rstat = _SU32(rxd, PCNET_RD_PTR); + + // Keep going until we hit an entry that is owned by the + // controller. + if (rstat & PCNET_RD_PTR_OWN) { +#if DEBUG & 1 + int i; + for (i = 0; i < cpd->rx_ring_cnt; i++) { + rxd = cpd->rx_ring + i*PCNET_RD_SIZE; + rstat = _SU32(rxd, PCNET_RD_PTR); + + if (!(rstat & PCNET_RD_PTR_OWN)) { + int i; + cyg_uint32 rstat; + cyg_uint16 mlen, blen; + cyg_uint8* rxd; + + diag_printf("%s: Inconsistent RX state\n", __FUNCTION__); + for (i = 0; i < cpd->rx_ring_cnt; i++) { + rxd = cpd->rx_ring + i*PCNET_RD_SIZE; + + rstat = _SU32(rxd, PCNET_RD_PTR); + blen = _SU16(rxd, PCNET_RD_BLEN); + mlen = _SU16(rxd, PCNET_RD_MLEN); + diag_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen); + } + } + } +#endif + break; + } + +#if DEBUG & 4 + diag_printf("#####Rx packet at index %d\n", cpd->rxpacket); +#endif + + // Increment counts + INCR_STAT( rx_count ); + cpd->rx_ring_next++; + if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0; + + len = _SU16(rxd, PCNET_RD_MLEN); + +#ifdef KEEP_STATISTICS + //if ( rstat & PCNET_RD_PTR_FRAM ) INCR_STAT( rx_frame_errors ); + //if ( rstat & PCNET_RD_PTR_OFLO ) INCR_STAT( ); + if ( rstat & PCNET_RD_PTR_CRC ) INCR_STAT( rx_crc_errors ); + //if ( rstat & PCNET_RD_PTR_BUFF ) INCR_STAT( ); +#endif // KEEP_STATISTICS + + if (0 == (rstat & PCNET_RD_PTR_ERR)) { + // It's OK + INCR_STAT( rx_good ); + +#if DEBUG & 1 + diag_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len); +#endif + // Check for bogusly short packets; can happen in promisc + // mode: Asserted against and checked by upper layer + // driver. +#ifdef CYGPKG_NET + if ( len > sizeof( struct ether_header ) ) + // then it is acceptable; offer the data to the network stack +#endif + (sc->funs->eth_drv->recv)(sc, len); + } else { + // Not OK for one reason or another... +#if DEBUG & 1 + diag_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n", + rstat, len); +#endif + } + + // Free packet (clear all status flags, and set OWN) + _SU32(rxd, PCNET_RD_PTR) &= PCNET_RD_PTR_MASK; + _SU32(rxd, PCNET_RD_PTR) |= PCNET_RD_PTR_OWN; + } + + // Ack RX interrupt set + ints = get_reg(sc, PCNET_CSR_CSCR); + ints &= PCNET_CSR_CSCR_EV_MASK; + ints |= PCNET_CSR_CSCR_RINT; + put_reg(sc, PCNET_CSR_CSCR, ints); +} + +// +// This function is called as a result of the "eth_drv_recv()" call above. +// Its job is to actually fetch data for a packet from the hardware once +// memory buffers have been allocated for the packet. Note that the buffers +// may come in pieces, using a scatter-gather list. This allows for more +// efficient processing in the upper layers of the stack. +// +static void +pcnet_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) +{ + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + int i, mlen=0, plen; + cyg_uint8 *data, *rxd, *buf; + + DEBUG_FUNCTION(); + + rxd = cpd->rx_ring + cpd->rxpacket*PCNET_TD_SIZE; + buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE; + + INCR_STAT( rx_deliver ); + + plen = _SU16(rxd, PCNET_RD_MLEN); + + for (i = 0; i < sg_len; i++) { + data = (cyg_uint8*)sg_list[i].buf; + mlen = sg_list[i].len; + +#if DEBUG & 1 + diag_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen); +#endif + if (data) { + while (mlen > 0) { + *data++ = *buf++; + mlen--; + plen--; + } + } + } +} + +static void +pcnet_poll(struct eth_drv_sc *sc) +{ + cyg_uint16 event; + +// DEBUG_FUNCTION(); + + while (1) { + // Get the (unmasked) requests + event = get_reg(sc, PCNET_CSR_CSCR); + if (!((PCNET_CSR_CSCR_ERR|PCNET_CSR_CSCR_INTR) & event)) + break; + + if (event & PCNET_CSR_CSCR_RINT) { + pcnet_RxEvent(sc); + } + else if (event & PCNET_CSR_CSCR_TINT) { + pcnet_TxEvent(sc, event); + } + else if (event & PCNET_CSR_CSCR_MISS) { +#if DEBUG & 1 + int i; + cyg_uint32 rstat; + cyg_uint16 mlen, blen; + cyg_uint8* rxd; + struct pcnet_priv_data *cpd = + (struct pcnet_priv_data *)sc->driver_private; + + diag_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event); + for (i = 0; i < cpd->rx_ring_cnt; i++) { + rxd = cpd->rx_ring + i*PCNET_TD_SIZE; + + rstat = _SU32(rxd, PCNET_RD_PTR); + blen = _SU16(rxd, PCNET_RD_BLEN); + mlen = _SU16(rxd, PCNET_RD_MLEN); + diag_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen); + } +#endif + event &= PCNET_CSR_CSCR_EV_MASK; + event |= PCNET_CSR_CSCR_MISS; + put_reg(sc, PCNET_CSR_CSCR, event); + } + else { +#if DEBUG & 1 + diag_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event); +#endif + put_reg(sc, PCNET_CSR_CSCR, event); + } + } +} + +// EOF if_pcnet.c
--- a/packages/devs/eth/arm/ebsa285/current/ChangeLog +++ b/packages/devs/eth/arm/ebsa285/current/ChangeLog @@ -1,3 +1,17 @@ +2001-08-31 Hugo Tyson <hmt@redhat.com> +2001-08-31 Andrew Lunn <Andrew.Lunn@ascom.ch> + + * src/if_ebsa285.c (TxDone): Check from prev change is moved to + the logical driver. Also, we zero the key in global state before + the callback - this should make no difference, but again it's good + practice, and ASCOM's tests indicate a benefit for CASE 106059. + +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/if_ebsa285.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-06-08 Gary Thomas <gthomas@redhat.com> * src/if_ebsa285.c (TxDone): Defensive programming: only call
--- a/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c +++ b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c @@ -70,7 +70,6 @@ #include <net/if.h> /* Needed for struct ifnet */ #else #include <cyg/hal/hal_if.h> -#define diag_printf printf #endif #ifdef CYGPKG_IO_PCI @@ -1490,14 +1489,14 @@ static void TxDone(struct i82559* p_i825 ( p_i82559->tx_queue_full && (0 != p_i82559->tx_ring[ tx_descriptor_remove ]->txstatus) ) ) { unsigned long key = p_i82559->tx_keys[ tx_descriptor_remove ]; + // Zero the key in global state before the callback: + p_i82559->tx_keys[ tx_descriptor_remove ] = 0; #ifdef DEBUG_82559 os_printf("TxDone %d %x: KEY %x\n", p_i82559->index, (int)p_i82559, key ); #endif - if (key) { - (sc->funs->eth_drv->tx_done)( sc, key, 1 /* status */ ); - } - p_i82559->tx_keys[ tx_descriptor_remove ] = 0; + // tx_done() can now cope with a NULL key, no guard needed here + (sc->funs->eth_drv->tx_done)( sc, key, 1 /* status */ ); if ( ++tx_descriptor_remove >= MAX_TX_DESCRIPTORS ) tx_descriptor_remove = 0;
--- a/packages/devs/eth/arm/iq80310/current/ChangeLog +++ b/packages/devs/eth/arm/iq80310/current/ChangeLog @@ -1,3 +1,14 @@ +2001-08-24 Mark Salter <msalter@redhat.com> + + * src/if_iq80310.c (PacketRxReady): Break out of Rx loop after + one packet is delivered for RedBoot. + +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/if_iq80310.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-08-15 Mark Salter <msalter@redhat.com> * src/if_iq80310.c: Use 32-bit access to MDI. Problem discovered @@ -39,7 +50,7 @@ 2000-11-06 Mark Salter <msalter@redhat // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/devs/eth/arm/iq80310/current/src/if_iq80310.c +++ b/packages/devs/eth/arm/iq80310/current/src/if_iq80310.c @@ -72,7 +72,6 @@ #include <net/if.h> /* Needed for struct ifnet */ #else #include <cyg/hal/hal_if.h> -#define diag_printf printf #endif #ifdef CYGPKG_IO_PCI @@ -1469,6 +1468,10 @@ static void PacketRxReady(struct i82559* CYG_ASSERT( (cyg_uint8 *)p_rfd >= i82559_heap_base, "rfd under" ); CYG_ASSERT( (cyg_uint8 *)p_rfd < i82559_heap_free, "rfd over" ); +#ifdef CYGPKG_REDBOOT + // Need to make this decision at runtime. + break; +#endif } // See if the RU has gone idle (usually because of out of resource
--- a/packages/devs/eth/cf/current/ChangeLog +++ b/packages/devs/eth/cf/current/ChangeLog @@ -1,3 +1,13 @@ +2001-08-25 Gary Thomas <gthomas@redhat.com> + + * src/if_sc_lpe.c (sc_lpe_card_handler): Rework ESA discovery code. + +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/if_sc_lpe.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-06-16 Jesper Skov <jskov@redhat.com> * src/if_sc_lpe.c: Use generic DP83902A driver, only redefining @@ -114,7 +124,7 @@ 2000-07-14 Gary Thomas <gthomas@redhat // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/devs/eth/cf/current/src/if_sc_lpe.c +++ b/packages/devs/eth/cf/current/src/if_sc_lpe.c @@ -65,7 +65,6 @@ #include <pkgconf/net.h> #else #include <cyg/hal/hal_if.h> -#define diag_printf printf #endif #include <cyg/io/dp83902a.h> @@ -159,7 +158,7 @@ sc_lpe_card_handler(cyg_addrword_t param while (*cp++) ; // Skip to nul vers_date = cp; #ifndef CYGPKG_NET - if (tries != 0) printf("\n"); + if (tries != 0) diag_printf("\n"); diag_printf("%s: %s %s %s\n", vers_manuf, vers_product, vers_revision, vers_date); #endif } @@ -174,23 +173,6 @@ sc_lpe_card_handler(cyg_addrword_t param continue; } - // Fetch hardware address from card - terrible, but not well defined - // Note: at least one card has been known to not have a valid ESA anywhere - if (!dp->hardwired_esa) { - if (slot->attr[0x1C0] != (unsigned char)0xFF) { - for (i = 0; i < ETHER_ADDR_LEN; i++) - dp->esa[i] = slot->attr[0x1C0+(i*2)]; - } else { - diag_printf("No valid ESA found in CIS! Hardwiring to 08:88:87:65:43:21\n"); - dp->esa[0] = 0x08; - dp->esa[1] = 0x88; - dp->esa[2] = 0x87; - dp->esa[3] = 0x65; - dp->esa[4] = 0x43; - dp->esa[5] = 0x21; - } - } - ptr = 0; if (cf_get_CIS(slot, CF_CISTPL_CFTABLE_ENTRY, buf, &len, &ptr)) { if (cf_parse_cftable(buf, len, &cftable)) { @@ -207,6 +189,53 @@ sc_lpe_card_handler(cyg_addrword_t param do { DP_IN(base, DP_ISR, tmp); } while (0 == (tmp & DP_ISR_RESET)); + + // Fetch hardware address from card - terrible, but not well defined + // Patterned after what Linux drivers do + if (!dp->hardwired_esa) { + static unsigned char sc_lpe_addr[] = { 0x00, 0xC0, 0x1B, 0x00, 0x99, 0x9E}; + if ((slot->attr[0x1C0] == sc_lpe_addr[0]) && + (slot->attr[0x1C2] == sc_lpe_addr[1]) && + (slot->attr[0x1C4] == sc_lpe_addr[2])) { + sc_lpe_addr[3] = slot->attr[0x1C6]; + sc_lpe_addr[4] = slot->attr[0x1C8]; + sc_lpe_addr[5] = slot->attr[0x1CA]; + } else { + // Coudn't find it in the CIS (attribute) data + unsigned char prom[32]; + + // Tell device to give up ESA + DP_OUT(base, DP_DCR, 0x48); // Bytewide access + DP_OUT(base, DP_RBCH, 0); // Remote byte count + DP_OUT(base, DP_RBCL, 0); + DP_OUT(base, DP_ISR, 0xFF); // Clear any pending interrupts + DP_OUT(base, DP_IMR, 0x00); // Mask all interrupts + DP_OUT(base, DP_RCR, 0x20); // Monitor + DP_OUT(base, DP_TCR, 0x02); // loopback + DP_OUT(base, DP_RBCH, 32); // Remote byte count + DP_OUT(base, DP_RBCL, 0); + DP_OUT(base, DP_RSAL, 0); // Remote address + DP_OUT(base, DP_RSAH, 0); + DP_OUT(base, DP_CR, DP_CR_START|DP_CR_RDMA); // Read data + for (i = 0; i < 32; i++) { + HAL_READ_UINT8(base+DP_DATAPORT, prom[i]); + } + if ((prom[0] == sc_lpe_addr[0]) && + (prom[2] == sc_lpe_addr[1]) && + (prom[4] == sc_lpe_addr[2])) { + diag_printf("Getting address from port\n"); + sc_lpe_addr[3] = prom[6]; + sc_lpe_addr[4] = prom[8]; + sc_lpe_addr[5] = prom[10]; + } else { + diag_printf("No valid ESA found in CIS! Hardwiring to 00:C0:1B:00:99:9E\n"); + } + } + for (i = 0; i < 6; i++) { + dp->esa[i] = sc_lpe_addr[i]; + } + } + // Initialize upper level driver (sc->funs->eth_drv->init)(sc, dp->esa); // Tell system card is ready to talk @@ -229,8 +258,8 @@ sc_lpe_card_handler(cyg_addrword_t param cyg_drv_dsr_unlock(); do_delay(50); // FIXME! #ifndef CYGPKG_NET - if (tries == 0) printf("... Waiting for network card: "); - printf("."); + if (tries == 0) diag_printf("... Waiting for network card: "); + diag_printf("."); if (++tries == 10) { // 5 seconds have elapsed - give up return false;
--- a/packages/devs/eth/intel/i82559/current/ChangeLog +++ b/packages/devs/eth/intel/i82559/current/ChangeLog @@ -1,3 +1,29 @@ +2001-08-29 Hugo Tyson <hmt@redhat.com> + + * cdl/intel_i82559_eth_drivers.cdl: New CDL options called + CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD, .._PRIORITY and + .._DELAY to control the thread. By default this is all disabled + because it is not needed for a real network application which + itself proactively tries to use the net - it's only needed when + the app is totally passive, so the driver otherwise does not get + CPU time at all. + + * src/if_i82559.c (starti82559ticklethread): New code to start a + thread (!) to catch lost interrupts and thus restart jammed + hardware. It's only possible if KERNEL and NET - RedBoot is + unaffected, and it's not needed for RedBoot 'cos RedBoot polls. + (TxMachine): An assert about the CU idle status sometimes fired; + made the code more conservative wrt timing here. + (comments): more documentation on the possible external configury + by .inl file, described the two TIMEOUT macros that can be set, + and indeed must be to use the tickling thread meaningfully. + +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/if_i82559.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-06-22 Jesper Skov <jskov@redhat.com> * src/if_i82559.c (i82559_init): Handle EEPROMS without CRC. @@ -629,7 +655,7 @@ 2000-02-08 Hugo Tyson <hmt@cygnus.co.u // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/devs/eth/intel/i82559/current/cdl/intel_i82559_eth_drivers.cdl +++ b/packages/devs/eth/intel/i82559/current/cdl/intel_i82559_eth_drivers.cdl @@ -136,5 +136,41 @@ cdl_package CYGPKG_DEVS_ETH_INTEL_I82559 global flags." } } + + cdl_component CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD { + display "Create a thread to 'unstick' from lost interrupts" + active_if CYGPKG_KERNEL + active_if CYGPKG_NET + default_value 0 + description " + If this is enabled, the driver creates a thread to tickle the + device(s) periodically, to unblock them when the hardware has + become wedged due to a lost interrupt or other hardware + race-condition type problem. + This is not necessary if a networked app is running, provided + that it tries to send packets itself from time to time - or + uses TCP, or amy similar protocol which exchanges keep-alive + packets periodically and often enough. + Trying to send a packet passes control into the driver; this is + sufficient to detect and unblock jammed hardware." + + cdl_option CYGNUM_DEVS_ETH_INTEL_I82559_TICKLE_THREAD_PRIORITY { + display "Priority of i82559 tickle thread" + flavor data + default_value CYGPKG_NET_THREAD_PRIORITY + 2 + description " + The default is two below the net thread, which is one below + the default prio of the DHCP thread." + } + + cdl_option CYGNUM_DEVS_ETH_INTEL_I82559_TICKLE_THREAD_DELAY { + display "Delay in kernel clocks of i82559 tickle loop" + flavor data + default_value 50 + description " + The default is 50, which will usually mean a delay between + tests for 'stuck' devices of 500mS, that is half a second." + } + } } # EOF intel_i82559_eth_drivers.cdl
--- a/packages/devs/eth/intel/i82559/current/src/if_i82559.c +++ b/packages/devs/eth/intel/i82559/current/src/if_i82559.c @@ -114,6 +114,13 @@ // allocated chunk who appears to contain such a break, and // tries again. // +// CYGHWR_DEVS_ETH_INTEL_I82559_RESET_TIMEOUT( int32 ) +// CYGHWR_DEVS_ETH_INTEL_I82559_TIMEOUT_FIRED( int32 ) if +// both defined give the driver a means to detect that we +// have been fixated on the same transmit operation for too +// long - we missed an interrupt or the device crashed. The +// int32 argument is used to hold a eg. the value of a +// fast-running hardware timer. // // FIXME: replace -1/-2 return values with proper E-defines // FIXME: For 82557/8 compatibility i82559_configure() function @@ -143,8 +150,6 @@ #ifdef CYGPKG_NET #include <pkgconf/net.h> #include <net/if.h> /* Needed for struct ifnet */ -#else -#define diag_printf printf #endif #ifdef CYGPKG_IO_PCI @@ -214,7 +219,8 @@ static struct { int waitcmd_timeouts; int waitcmd_timeouts_cu; int lockup_timeouts; -} missed_interrupt = { 0,0,0, 0,0, 0 }; + int bad_cu_idles; +} missed_interrupt = { 0,0,0, 0,0, 0, 0 }; #endif #define os_printf diag_printf @@ -853,6 +859,17 @@ static int write_enable_eeprom(long ioaddr, int addr_len); #endif +#ifdef CYGPKG_KERNEL +#ifdef CYGPKG_NET +#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD + +static void +starti82559ticklethread( void ); + +#endif // CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD +#endif // CYGPKG_NET +#endif // CYGPKG_KERNEL + // debugging/logging only: void dump_txcb(TxCB* p_txcb); void DisplayStatistics(void); @@ -1295,6 +1312,15 @@ i82559_init(struct cyg_netdevtab_entry * #endif return 0; } +#ifdef CYGPKG_KERNEL +#ifdef CYGPKG_NET +#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD + + starti82559ticklethread(); + +#endif // CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD +#endif // CYGPKG_NET +#endif // CYGPKG_KERNEL } // If this device is not present, exit @@ -2034,7 +2060,16 @@ TxMachine(struct i82559* p_i82559) // start Tx operation wait_for_cmd_done(ioaddr, WAIT_CU); status = INW(ioaddr + SCBStatus); - + // The following assert sometimes fires here, apparantly harmless! + // So check a second time to let the cursed thing settle and not + // tell us lies. + if ( 0 != (status & CU_STATUS_MASK) ) { +#ifdef CYGDBG_USE_ASSERTS + missed_interrupt.bad_cu_idles++; +#endif + wait_for_cmd_done(ioaddr, WAIT_CU); + status = INW(ioaddr + SCBStatus); + } CYG_ASSERT( ( 0 == (status & CU_STATUS_MASK)), "CU not idle"); CYG_ASSERT( (cyg_uint8 *)p_txcb >= i82559_heap_base, "txcb under" ); CYG_ASSERT( (cyg_uint8 *)p_txcb < i82559_heap_free, "txcb over" ); @@ -3547,4 +3582,90 @@ update_statistics(struct i82559* p_i8255 // ------------------------------------------------------------------------ +#ifdef CYGPKG_KERNEL +#ifdef CYGPKG_NET +#ifdef CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD + +// Then we create a thread to tickle the device(s) periodically +// to unblock them when the hardware has become wedged. +// +// This is not necessary if a networked app is running, provided that it +// tries to "send stuff" itself from time to time - or uses TCP, or amy +// similar protocol which exchanges "keep-alive" packets periodically and +// often enough. + +#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL) +static char i82559tickle_stack[STACK_SIZE]; +static cyg_thread i82559tickle_thread_data; +static cyg_handle_t i82559tickle_thread_handle; + +static int +Poll82559ForTxLockupTimeout( void ) +{ + struct eth_drv_sc *sc; + struct cyg_netdevtab_entry *ndp; + struct i82559 *p_i82559; + int i; +#ifdef CYGDBG_USE_ASSERTS + int lockto = missed_interrupt.lockup_timeouts; +#endif + for ( i = 0; i < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT; i++ ) { + p_i82559 = i82559_priv_array[i]; + ndp = (struct cyg_netdevtab_entry *)(p_i82559->ndp); + sc = (struct eth_drv_sc *)(ndp->device_instance); + if ( p_i82559->active ) + (void)i82559_can_send( sc ); // This is a neat way to advance + } + return +#ifdef CYGDBG_USE_ASSERTS + (missed_interrupt.lockup_timeouts - lockto) +#endif + +0; +} + +static void +i82559tickle( cyg_addrword_t param ) +{ + int spl, to; + + while( 1 ) { + cyg_thread_delay(CYGNUM_DEVS_ETH_INTEL_I82559_TICKLE_THREAD_DELAY); + + spl = splnet(); + to = Poll82559ForTxLockupTimeout(); + splx(spl); + +#ifdef DEBUG +#ifdef CYGDBG_USE_ASSERTS + if ( to ) + diag_printf( "###Lockup detected: %d this time, total %d\n", + to, missed_interrupt.lockup_timeouts ); +#endif +#endif + } +} + + +static void +starti82559ticklethread( void ) +{ + // Create background thread + cyg_thread_create(CYGNUM_DEVS_ETH_INTEL_I82559_TICKLE_THREAD_PRIORITY, + i82559tickle, // entry + 0, // entry parameter + "i82559 ethernet tickle", // Name + &i82559tickle_stack[0], // Stack + STACK_SIZE, // Size + &i82559tickle_thread_handle, // Handle + &i82559tickle_thread_data // Thread data structure + ); + cyg_thread_resume(i82559tickle_thread_handle); // Start it +} + +#endif // CYGPKG_DEVS_ETH_INTEL_I82559_TICKLE_THREAD +#endif // CYGPKG_NET +#endif // CYGPKG_KERNEL + +// ------------------------------------------------------------------------ + // EOF if_i82559.c
--- a/packages/devs/eth/ns/dp83902a/current/ChangeLog +++ b/packages/devs/eth/ns/dp83902a/current/ChangeLog @@ -1,3 +1,8 @@ +2001-08-25 Gary Thomas <gthomas@redhat.com> + + * include/dp83902a.h (DP_DATAPORT): Add - used by ESA discovery + on SC/LPE card. + 2001-06-21 Jesper Skov <jskov@redhat.com> * src/if_dp83902a.c: Fix various build problems when net package
--- a/packages/devs/eth/ns/dp83902a/current/include/dp83902a.h +++ b/packages/devs/eth/ns/dp83902a/current/include/dp83902a.h @@ -228,6 +228,7 @@ static void dp83902a_poll(struct eth_drv #define DP_DCR 0x0e // write #define DP_MISSED 0x0f #define DP_IMR 0x0f // write +#define DP_DATAPORT 0x10 // "eprom" data port #define DP_P1_CR 0x00 #define DP_P1_PAR0 0x01
--- a/packages/devs/eth/powerpc/fec/current/ChangeLog +++ b/packages/devs/eth/powerpc/fec/current/ChangeLog @@ -1,3 +1,9 @@ +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/if_fec.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-06-26 Jonathan Larmour <jlarmour@redhat.com> * src/if_fec.c (fec_eth_init): Use correct version register.
--- a/packages/devs/eth/powerpc/fec/current/src/if_fec.c +++ b/packages/devs/eth/powerpc/fec/current/src/if_fec.c @@ -89,11 +89,7 @@ RedBoot_config_option("Network hardware #endif #endif -#ifdef CYGPKG_REDBOOT -#define os_printf printf -#else #define os_printf diag_printf -#endif // For fetching the ESA from RedBoot #include <cyg/hal/hal_if.h> @@ -310,7 +306,7 @@ fec_eth_init(struct cyg_netdevtab_entry #endif if (!esa_ok) { // Can't figure out ESA - diag_printf("FEC_ETH - Warning! ESA unknown\n"); + os_printf("FEC_ETH - Warning! ESA unknown\n"); memcpy(&enaddr, &_default_enaddr, sizeof(enaddr)); } memcpy((void *)&fec->addr[0], &enaddr[0], sizeof(enaddr));
--- a/packages/devs/eth/powerpc/quicc/current/ChangeLog +++ b/packages/devs/eth/powerpc/quicc/current/ChangeLog @@ -1,3 +1,9 @@ +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/if_quicc.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-05-07 Gary Thomas <gthomas@redhat.com> * src/if_quicc.c (quicc_eth_init): Get ESA from RedBoot 'fconfig' data. @@ -155,7 +161,7 @@ 2000-02-21 Gary Thomas <gthomas@cygnus // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c +++ b/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c @@ -450,7 +450,7 @@ quicc_eth_send(struct eth_drv_sc *sc, st #ifdef CYGPKG_NET panic ("No free xmit buffers"); #else - printf("QUICC Ethernet: No free xmit buffers\n"); + diag_printf("QUICC Ethernet: No free xmit buffers\n"); #endif } }
--- a/packages/devs/flash/intel/strata/current/ChangeLog +++ b/packages/devs/flash/intel/strata/current/ChangeLog @@ -1,3 +1,11 @@ +2001-08-25 Gary Thomas <gthomas@redhat.com> + + * src/flash_program_buf.c (flash_program_buf): Allow configuration + specific code sequence for actual writing of data. Define by the + macro CYGHWR_FLASH_WRITE_ELEM. Note: this is required on some + hardware, like the Intel SA185, which handles flash writes in + strange/obscure fashion. + 2001-07-17 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com> * src/flash_query.c (flash_query): Query needs to be done on even
--- a/packages/devs/flash/intel/strata/current/src/flash_program_buf.c +++ b/packages/devs/flash/intel/strata/current/src/flash_program_buf.c @@ -97,7 +97,11 @@ flash_program_buf(volatile flash_t *addr } *BA = FLASHWORD(wc-1); // Count is 0..N-1 for (i = 0; i < wc; i++) { +#ifdef CYGHWR_FLASH_WRITE_ELEM + CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i); +#else *(addr+i) = *(data+i); +#endif } *BA = FLASH_Confirm; @@ -125,7 +129,11 @@ flash_program_buf(volatile flash_t *addr while (len > 0) { ROM[0] = FLASH_Program; +#ifdef CYGHWR_FLASH_WRITE_ELEM + CYGHWR_FLASH_WRITE_ELEM(addr, data); +#else *addr = *data; +#endif timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) {
--- a/packages/devs/kbd/arm/ipaq/current/ChangeLog +++ b/packages/devs/kbd/arm/ipaq/current/ChangeLog @@ -1,3 +1,7 @@ +2001-08-29 Kenichi Nakamura <nakamura@redhat.com> + + * cdl/kbd_ipaq.cdl: Modified dependency on file I/O package. + 2001-04-24 Gary Thomas <gthomas@redhat.com> * cdl/kbd_ipaq.cdl: Add dependency on file I/O package.
--- a/packages/devs/kbd/arm/ipaq/current/cdl/kbd_ipaq.cdl +++ b/packages/devs/kbd/arm/ipaq/current/cdl/kbd_ipaq.cdl @@ -43,7 +43,7 @@ cdl_package CYGPKG_DEVS_KBD_IPAQ { display "Keypad driver for iPAQ" include_dir cyg/io - active_if CYGPKG_FILEIO + active_if CYGPKG_IO_FILEIO requires CYGPKG_IO requires CYGFUN_KERNEL_API_C requires CYGPKG_HAL_ARM_SA11X0_IPAQ
--- a/packages/devs/serial/arm/iq80310/current/ChangeLog +++ b/packages/devs/serial/arm/iq80310/current/ChangeLog @@ -1,3 +1,7 @@ +2001-09-03 Jesper Skov <jskov@redhat.com> + + * include/arm_iq80310_ser.inl: Fix interrupt vector name typos. + 2000-10-25 Mark Salter <msalter@redhat.com> * include/arm_iq80310_ser.inl: Initial checkin.
--- a/packages/devs/serial/arm/iq80310/current/include/arm_iq80310_ser.inl +++ b/packages/devs/serial/arm/iq80310/current/include/arm_iq80310_ser.inl @@ -72,7 +72,7 @@ static unsigned short select_baud[] = { #ifdef CYGPKG_IO_SERIAL_ARM_IQ80310_SERIAL0 static pc_serial_info iq80310_serial_info0 = {0xFE800000, - CYGNUM_HAL_INTERRUPT_SERIALA}; + CYGNUM_HAL_INTERRUPT_SERIAL_A}; #if CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL0_BUFSIZE > 0 static unsigned char iq80310_serial_out_buf0[CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL0_BUFSIZE]; static unsigned char iq80310_serial_in_buf0[CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL0_BUFSIZE]; @@ -112,7 +112,7 @@ DEVTAB_ENTRY(iq80310_serial_io0, #ifdef CYGPKG_IO_SERIAL_ARM_IQ80310_SERIAL1 static pc_serial_info iq80310_serial_info1 = {0xFE810000, - CYGNUM_HAL_INTERRUPT_SERIALB}; + CYGNUM_HAL_INTERRUPT_SERIAL_B}; #if CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL1_BUFSIZE > 0 static unsigned char iq80310_serial_out_buf1[CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL1_BUFSIZE]; static unsigned char iq80310_serial_in_buf1[CYGNUM_IO_SERIAL_ARM_IQ80310_SERIAL1_BUFSIZE];
--- a/packages/devs/touch/arm/ipaq/current/ChangeLog +++ b/packages/devs/touch/arm/ipaq/current/ChangeLog @@ -1,3 +1,7 @@ +2001-08-29 Kenichi Nakamura <nakamura@redhat.com> + + * cdl/touch_ipaq.cdl: Modified dependency on file I/O package. + 2001-04-24 Gary Thomas <gthomas@redhat.com> * cdl/touch_ipaq.cdl: Add dependency on file I/O package.
--- a/packages/devs/touch/arm/ipaq/current/cdl/touch_ipaq.cdl +++ b/packages/devs/touch/arm/ipaq/current/cdl/touch_ipaq.cdl @@ -43,7 +43,7 @@ cdl_package CYGPKG_DEVS_TOUCH_IPAQ { display "Touch screen driver for iPAQ" include_dir cyg/io - active_if CYGPKG_FILEIO + active_if CYGPKG_IO_FILEIO requires CYGPKG_IO requires CYGFUN_KERNEL_API_C requires CYGPKG_HAL_ARM_SA11X0_IPAQ
--- a/packages/ecos.db +++ b/packages/ecos.db @@ -657,6 +657,14 @@ package CYGPKG_DEVS_ETH_ARM_EDB7XXX { description "Ethernet driver for Cirrus Logic EDB7xxx development boards." } +package CYGPKG_DEVS_ETH_AMD_PCNET { + alias { "AMD PCNET ethernet driver" pcnet_eth_driver } + hardware + directory devs/eth/amd/pcnet + script amd_pcnet_eth_drivers.cdl + description "Ethernet driver for AMD PCNET controller." +} + package CYGPKG_DEVS_ETH_ARM_EBSA285 { alias { "Intel EBSA285 with PRO/100+ ethernet driver" devs_eth_arm_ebsa285 ebsa285_eth_driver }
--- a/packages/hal/arm/arch/current/ChangeLog +++ b/packages/hal/arm/arch/current/ChangeLog @@ -1,3 +1,7 @@ +2001-08-24 Mark Salter <msalter@redhat.com> + + * src/arm_stub.c (target_thumb_ins): Add support for pop insn. + 2001-08-21 Hugo Tyson <hmt@redhat.com> * include/hal_intr.h: Only define HAL_CLOCK_LATENCY() if it's not
--- a/packages/hal/arm/arch/current/src/arm_stub.c +++ b/packages/hal/arm/arch/current/src/arm_stub.c @@ -440,7 +440,8 @@ target_thumb_ins(unsigned long pc, unsig { unsigned long new_pc = MAKE_THUMB_ADDR(pc+2); // default is fall-through // to next thumb instruction - unsigned long offset, arm_ins; + unsigned long offset, arm_ins, sp; + int i; switch ((ins & 0xf000) >> 12) { case 0x4: @@ -448,6 +449,20 @@ target_thumb_ins(unsigned long pc, unsig if ((ins & 0xff07) == 0x4700) new_pc = (unsigned long)get_register((ins & 0x00078) >> 3); break; + case 0xb: + // push/pop + // Look for "pop {...,pc}" + if ((ins & 0xf00) == 0xd00) { + // find PC + sp = (unsigned long)get_register(SP); + + for (offset = i = 0; i < 8; i++) + if (ins & (1 << i)) + offset += 4; + + new_pc = *(cyg_uint32 *)(sp + offset); + } + break; case 0xd: // Bcc // Use ARM function to check condition
--- a/packages/hal/arm/ebsa285/current/ChangeLog +++ b/packages/hal/arm/ebsa285/current/ChangeLog @@ -1,3 +1,9 @@ +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/redboot_cmds.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-06-21 Jonathan Larmour <jlarmour@redhat.com> * images/*: Remove. Don't bloat repository with things already on @@ -751,7 +757,7 @@ 1999-07-14 Hugo Tyson <hmt@cygnus.co.u // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/hal/arm/ebsa285/current/src/redboot_cmds.c +++ b/packages/hal/arm/ebsa285/current/src/redboot_cmds.c @@ -23,7 +23,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // @@ -118,15 +118,15 @@ do_exec(int argc, char *argv[]) } } if (wait_time_set) { - printf("About to start execution at %p - abort with ^C within %d seconds\n", - (void *)entry, wait_time); - res = gets(line, sizeof(line), wait_time*1000); + diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", + (void *)entry, wait_time); + res = _rb_gets(line, sizeof(line), wait_time*1000); if (res == _GETS_CTRLC) { return; } } if (base_addr_set && !length_set) { - printf("Length required for non-standard base address\n"); + diag_printf("Length required for non-standard base address\n"); return; } ip = (unsigned long *)&&lab1;
--- a/packages/hal/arm/iq80310/current/ChangeLog +++ b/packages/hal/arm/iq80310/current/ChangeLog @@ -1,3 +1,18 @@ +2001-08-27 Mark Salter <msalter@redhat.com> + + * cdl/hal_arm_iq80310.cdl (CYGSEM_HAL_ARM_IQ80310_BTB): New option. + (CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY) New option. + + * src/iq80310_pci.c (cyg_hal_plf_pci_init): Clear PCI retry based on + CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY. + + * include/hal_platform_setup.h: Turn on BTB based on configure option. + +2001-08-24 Mark Salter <msalter@redhat.com> + + * src/iq80310_misc.c (iq80310_program_new_stack): Convert to inline + asm so that code generation differences won't break it. + 2001-08-15 Mark Salter <msalter@redhat.com> * include/hal_iq80310.h: Fix size of PATUSR, SATUSR, PSR, and SSR regs.
--- a/packages/hal/arm/iq80310/current/cdl/hal_arm_iq80310.cdl +++ b/packages/hal/arm/iq80310/current/cdl/hal_arm_iq80310.cdl @@ -253,6 +253,31 @@ cdl_package CYGPKG_HAL_ARM_IQ80310 { compiler flags used only in building this package, and details of which tests are built." + cdl_option CYGSEM_HAL_ARM_IQ80310_BTB { + display "Enable Branch Target Buffer" + flavor bool + default_value 0 + description " + Enable this option to turn on the IQ80200 Branch Target Buffer + which is used for branch prediction. This is turned off by + default because of CPU errata which may cause thumb branches + to execute improperly on A-step CPUs. Normal ARM programs are + not affected by this errata, so enabling this option for + ARM-only applications may improve program performance." + } + + cdl_option CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY { + display "Have RedBoot clear PCI Retry bit" + flavor bool + default_value 1 + description " + This option controls whether or not RedBoot allows the host PC + to completely boot. In some cases, you may not want to allow + this if RedBoot is used to automatically launch an application + which needs to run some setup code before allowing the PC to + finish booting. In that case, the application code, not RedBoot + will clear the PCI retry bit." + } cdl_option CYGPKG_HAL_ARM_IQ80310_CFLAGS_ADD { display "Additional compiler flags"
--- a/packages/hal/arm/iq80310/current/include/hal_platform_setup.h +++ b/packages/hal/arm/iq80310/current/include/hal_platform_setup.h @@ -128,6 +128,16 @@ sub pc,pc,#4 .endm + // Enable the BTB + .macro BTB_INIT reg +#ifdef CYGSEM_HAL_ARM_IQ80310_BTB + mrc p15, 0, \reg, c1, c0, 0 + orr \reg, \reg, #MMU_Control_BTB + mcr p15, 0, \reg, c1, c0, 0 + CPWAIT \reg +#endif + .endm + // form a first-level section entry .macro FL_SECTION_ENTRY base,x,ap,p,d,c,b .word (\base << 20) | (\x << 12) | (\ap << 10) | (\p << 9) |\ @@ -696,11 +706,8 @@ SDRAM_DRIVE_2_BANK_X8: mcr p15, 0, r0, c1, c0, 0 CPWAIT r0 - // Enable the BTB - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #MMU_Control_BTB - mcr p15, 0, r0, c1, c0, 0 - CPWAIT r0 + // Initialize branch target buffer + BTB_INIT r0 // Battery Backup SDRAM Memory Test // Move 4 byte Test Pattern into register prior to zeroing out
--- a/packages/hal/arm/iq80310/current/src/diag/cycduart.c +++ b/packages/hal/arm/iq80310/current/src/diag/cycduart.c @@ -44,7 +44,7 @@ #define DFLTLOOPERMS 500 -extern int printf(char*,...); +//extern int printf(char*,...); extern long hexIn(); int break_flag = 0;
--- a/packages/hal/arm/iq80310/current/src/diag/ether_test.c +++ b/packages/hal/arm/iq80310/current/src/diag/ether_test.c @@ -58,7 +58,7 @@ static int waitForRxInt(); static int get_ether_addr(); /* Externals */ -void printf(); +//void printf(); void bcopy(); extern void sgets(); extern int atod();
--- a/packages/hal/arm/iq80310/current/src/diag/pci_serv.c +++ b/packages/hal/arm/iq80310/current/src/diag/pci_serv.c @@ -107,8 +107,7 @@ typedef struct /* Table where the interrupt handler addresses are stored. */ INT_HANDLER pci_int_handlers[4][MAX_PCI_HANDLERS]; - -extern void printf(); +//extern void printf(); extern void hexIn(); extern int pci_config_cycle;
--- a/packages/hal/arm/iq80310/current/src/iq80310_misc.c +++ b/packages/hal/arm/iq80310/current/src/iq80310_misc.c @@ -129,17 +129,16 @@ void hal_hardware_init(void) } #include CYGHWR_MEMORY_LAYOUT_H -typedef void code_fun(void); -void iq80310_program_new_stack(void *func) +void __attribute__ ((naked)) iq80310_program_new_stack(void *func) { - register CYG_ADDRESS stack_ptr asm("sp"); - register CYG_ADDRESS old_stack asm("r4"); - register code_fun *new_func asm("r0"); - old_stack = stack_ptr; - stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS); - new_func = (code_fun*)func; - new_func(); - stack_ptr = old_stack; + asm volatile ("mov r12,sp\n" + "stmdb sp!, {r4, r12, lr, pc}\n" + "sub r4,r12, #4\n" + "mov r12,#0xa0000000\n" + "add sp,r12,#0x1000000\n" + "mov lr,pc\n" + "mov pc,r0\n" + "ldmdb r4, {r4, sp, pc}\n"); return; }
--- a/packages/hal/arm/iq80310/current/src/iq80310_pci.c +++ b/packages/hal/arm/iq80310/current/src/iq80310_pci.c @@ -113,8 +113,10 @@ void cyg_hal_plf_pci_init(void) *(cyg_uint32 *)POIOWVR_ADDR = PRIMARY_IO_BASE; } +#ifdef CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY // clear RETRY *(cyg_uint16 *)EBCR_ADDR = 0x0008; +#endif // ******** Secondary Inbound ATU *********** @@ -185,6 +187,7 @@ void cyg_hal_plf_pci_init(void) // set the primary bus number to 0 *(cyg_uint8 *)PBNR_ADDR = PRIMARY_BUS_NUM; } else { +#ifdef CYGSEM_HAL_ARM_IQ80310_CLEAR_PCI_RETRY // Wait for PC BIOS to initialize bus number int i; @@ -193,7 +196,7 @@ void cyg_hal_plf_pci_init(void) break; hal_delay_us(1000); // 1msec } - +#endif if (*((volatile cyg_uint8 *)SBNR_ADDR) == 0) *(cyg_uint8 *)SBNR_ADDR = SECONDARY_BUS_NUM; } @@ -220,9 +223,6 @@ void cyg_hal_plf_pci_init(void) cyg_pci_set_memory_base(SECONDARY_MEM_BASE); cyg_pci_set_io_base(SECONDARY_IO_BASE); cyg_pci_configure_bus(sbus_nr, &next_bus); - - // clear RETRY - *(cyg_uint16 *)EBCR_ADDR = 0x0008; } void cyg_hal_plf_pci_config_setup( cyg_uint32 bus,
--- a/packages/hal/arm/sa11x0/ipaq/current/ChangeLog +++ b/packages/hal/arm/sa11x0/ipaq/current/ChangeLog @@ -1,3 +1,10 @@ +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/redboot_cmds.c: + * src/lcd_support.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-07-23 Gary Thomas <gthomas@redhat.com> * include/hal_platform_ints.h:
--- a/packages/hal/arm/sa11x0/ipaq/current/src/lcd_support.c +++ b/packages/hal/arm/sa11x0/ipaq/current/src/lcd_support.c @@ -896,7 +896,7 @@ lcd_comm_getc_nonblock(void* __ch_data, #ifdef KBD_DEBUG { int cur = start_console(0); - printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events); + diag_printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events); end_console(cur); dump_info = !dump_info; } @@ -923,7 +923,7 @@ lcd_comm_getc_nonblock(void* __ch_data, #ifdef KBD_DEBUG if (dump_info) { int cur = start_console(0); - printf("start pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events); + diag_printf("start pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events); end_console(cur); } #endif @@ -955,7 +955,7 @@ lcd_comm_getc_nonblock(void* __ch_data, #ifdef KBD_DEBUG if (dump_info) { int cur = start_console(0); - printf("going idle\n"); + diag_printf("going idle\n"); end_console(cur); } #endif @@ -965,7 +965,7 @@ lcd_comm_getc_nonblock(void* __ch_data, #ifdef KBD_DEBUG if (dump_info) { int cur = start_console(0); - printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events); + diag_printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events); end_console(cur); } #endif @@ -980,7 +980,7 @@ lcd_comm_getc_nonblock(void* __ch_data, #ifdef KBD_DEBUG if (dump_info) { int cur = start_console(0); - printf("Pen[%d] at %d/%d\n", total_events, x, y); + diag_printf("Pen[%d] at %d/%d\n", total_events, x, y); end_console(cur); } #endif @@ -995,7 +995,7 @@ lcd_comm_getc_nonblock(void* __ch_data, #ifdef KBD_DEBUG if (dump_info) { int cur = start_console(0); - printf("Row/Col = %d/%d = %x\n", row, col, kbd_ch); + diag_printf("Row/Col = %d/%d = %x\n", row, col, kbd_ch); end_console(cur); } #endif @@ -1390,13 +1390,13 @@ lcd_comm_init(void) lcd_kbd(LCD_KBD_NORM); } #if 0 - printf("KBD Limits[] = %d/%d, %d/%d, %d/%d, %d/%d\n", - kbd_limits[CS_UL].x, kbd_limits[CS_UL].y, - kbd_limits[CS_UR].x, kbd_limits[CS_UR].y, - kbd_limits[CS_LL].x, kbd_limits[CS_LL].y, - kbd_limits[CS_LR].x, kbd_limits[CS_LR].y); - printf("KBD in %d/%d .. %d/%d\n", minX, minY, maxX, maxY); - printf("screen %d x %d\n", screen_height, screen_width); + diag_printf("KBD Limits[] = %d/%d, %d/%d, %d/%d, %d/%d\n", + kbd_limits[CS_UL].x, kbd_limits[CS_UL].y, + kbd_limits[CS_UR].x, kbd_limits[CS_UR].y, + kbd_limits[CS_LL].x, kbd_limits[CS_LL].y, + kbd_limits[CS_LR].x, kbd_limits[CS_LR].y); + diag_printf("KBD in %d/%d .. %d/%d\n", minX, minY, maxX, maxY); + diag_printf("screen %d x %d\n", screen_height, screen_width); #endif } }
--- a/packages/hal/arm/sa11x0/ipaq/current/src/redboot_cmds.c +++ b/packages/hal/arm/sa11x0/ipaq/current/src/redboot_cmds.c @@ -91,24 +91,24 @@ do_gpio(int argc,char *argv[]) { } if ( !set_bits_set && !clr_bits_set ) { // display only - printf(" gpio = 0x%08lX\n", *SA11X0_GPIO_PIN_LEVEL); - printf(" 0x%08lX are output\n", *SA11X0_GPIO_PIN_DIRECTION); - printf(" 0x%08lX rising edge detect\n", *SA11X0_GPIO_RISING_EDGE_DETECT); - printf(" 0x%08lX falling edge detect\n", *SA11X0_GPIO_FALLING_EDGE_DETECT); - printf(" 0x%08lX edge detect status\n", *SA11X0_GPIO_EDGE_DETECT_STATUS); - printf(" 0x%08lX alternate function\n", *SA11X0_GPIO_ALTERNATE_FUNCTION); + diag_printf(" gpio = 0x%08lX\n", *SA11X0_GPIO_PIN_LEVEL); + diag_printf(" 0x%08lX are output\n", *SA11X0_GPIO_PIN_DIRECTION); + diag_printf(" 0x%08lX rising edge detect\n", *SA11X0_GPIO_RISING_EDGE_DETECT); + diag_printf(" 0x%08lX falling edge detect\n", *SA11X0_GPIO_FALLING_EDGE_DETECT); + diag_printf(" 0x%08lX edge detect status\n", *SA11X0_GPIO_EDGE_DETECT_STATUS); + diag_printf(" 0x%08lX alternate function\n", *SA11X0_GPIO_ALTERNATE_FUNCTION); return; } - printf( " gpio 0x%08lX, ", *SA11X0_GPIO_PIN_LEVEL); + diag_printf( " gpio 0x%08lX, ", *SA11X0_GPIO_PIN_LEVEL); if ( set_bits_set ) { - printf("set(0x%08X) ",set_bits); + diag_printf("set(0x%08X) ",set_bits); *SA11X0_GPIO_PIN_OUTPUT_SET = set_bits; } if ( clr_bits_set ) { - printf("clear(0x%08X) ",clr_bits); + diag_printf("clear(0x%08X) ",clr_bits); *SA11X0_GPIO_PIN_OUTPUT_CLEAR = clr_bits; } - printf( "gives 0x%08lX\n", *SA11X0_GPIO_PIN_LEVEL); + diag_printf( "gives 0x%08lX\n", *SA11X0_GPIO_PIN_LEVEL); } static void @@ -123,19 +123,19 @@ do_egpio(int argc,char *argv[]) { if (!scan_opts(argc, argv, 1, opts, 2, NULL, 0, NULL)) return; if ( !set_bits_set && !clr_bits_set ) { // display only - printf(" egpio = 0x%04X\n", (int)(_ipaq_EGPIO & 0xffff)); + diag_printf(" egpio = 0x%04X\n", (int)(_ipaq_EGPIO & 0xffff)); return; } - printf( " egpio 0x%04X, ", (int)(_ipaq_EGPIO & 0xffff)); + diag_printf( " egpio 0x%04X, ", (int)(_ipaq_EGPIO & 0xffff)); if ( set_bits_set ) { - printf("set(0x%08X) ",set_bits); + diag_printf("set(0x%08X) ",set_bits); ipaq_EGPIO( set_bits, set_bits ); } if ( clr_bits_set ) { - printf("clear(0x%08X) ",clr_bits); + diag_printf("clear(0x%08X) ",clr_bits); ipaq_EGPIO( clr_bits, 0x0000 ); } - printf( "gives 0x%04X\n", (int)(_ipaq_EGPIO & 0xffff)); + diag_printf( "gives 0x%04X\n", (int)(_ipaq_EGPIO & 0xffff)); } static void @@ -153,23 +153,23 @@ do_mem(int argc, char *argv[]) { if (!scan_opts(argc, argv, 1, opts, 3, (void*)&value, OPTION_ARG_TYPE_NUM, "address to set")) return; if ( mem_byte && mem_half_word ) { - printf("*ERR: Should not specify both byte and half-word access\n"); + diag_printf("*ERR: Should not specify both byte and half-word access\n"); } else if ( mem_byte ) { *(cyg_uint8*)address = (cyg_uint8)(value & 255); - printf(" Set 0x%08X to 0x%02X (result 0x%02X)\n", address, value & 255, (int)*(cyg_uint8*)address ); + diag_printf(" Set 0x%08X to 0x%02X (result 0x%02X)\n", address, value & 255, (int)*(cyg_uint8*)address ); } else if ( mem_half_word ) { if ( address & 1 ) { - printf( "*ERR: Badly aligned address 0x%08X for half-word store\n", address ); + diag_printf( "*ERR: Badly aligned address 0x%08X for half-word store\n", address ); } else { *(cyg_uint16*)address = (cyg_uint16)(value & 0xffff); - printf(" Set 0x%08X to 0x%04X (result 0x%04X)\n", address, value & 0xffff, (int)*(cyg_uint16*)address ); + diag_printf(" Set 0x%08X to 0x%04X (result 0x%04X)\n", address, value & 0xffff, (int)*(cyg_uint16*)address ); } } else { if ( address & 3 ) { - printf( "*ERR: Badly aligned address 0x%08X for word store\n", address ); + diag_printf( "*ERR: Badly aligned address 0x%08X for word store\n", address ); } else { *(cyg_uint32*)address = (cyg_uint32)value; - printf(" Set 0x%08X to 0x%08X (result 0x%08X)\n", address, value, (int)*(cyg_uint32*)address ); + diag_printf(" Set 0x%08X to 0x%08X (result 0x%08X)\n", address, value, (int)*(cyg_uint32*)address ); } } } @@ -181,7 +181,7 @@ do_physaddr(int argc, char *argv[]) { if ( !scan_opts(argc,argv,1,0,0,(void*)&virt_addr, OPTION_ARG_TYPE_NUM, "virtual address") ) return; phys_addr = hal_virt_to_phys_address(virt_addr); - printf("Virtual addr %p = physical addr %p\n", virt_addr, phys_addr); + diag_printf("Virtual addr %p = physical addr %p\n", virt_addr, phys_addr); } // Get here when RedBoot is idle. If it's been long enough, then
--- a/packages/hal/arm/sa11x0/var/current/ChangeLog +++ b/packages/hal/arm/sa11x0/var/current/ChangeLog @@ -1,3 +1,9 @@ +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/redboot_linux_exec.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-08-21 Hugo Tyson <hmt@redhat.com> * include/hal_var_ints.h (HAL_CLOCK_LATENCY()): Define this if
--- a/packages/hal/arm/sa11x0/var/current/src/redboot_linux_exec.c +++ b/packages/hal/arm/sa11x0/var/current/src/redboot_linux_exec.c @@ -282,10 +282,10 @@ do_exec(int argc, char *argv[]) unsigned char *hold_script = script; script = (unsigned char *)0; #endif - printf("About to start execution at %p - abort with ^C within %d seconds\n", - (void *)entry, wait_time); + diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", + (void *)entry, wait_time); while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { - res = gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); + res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res == _GETS_CTRLC) { #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT script = hold_script; // Re-enable script @@ -296,7 +296,7 @@ do_exec(int argc, char *argv[]) } } if (base_addr_set && !length_set) { - printf("Length required for non-standard base address\n"); + diag_printf("Length required for non-standard base address\n"); return; } ip = (unsigned long *)&&lab1;
--- a/packages/hal/common/current/ChangeLog +++ b/packages/hal/common/current/ChangeLog @@ -1,3 +1,8 @@ +2001-08-24 Mark Salter <msalter@redhat.com> + + * src/generic-stub.c (__process_packet): Add support for 'D' packet. + (__process_packet): Check for impossible mem write length. + 2001-08-17 Jonathan Larmour <jlarmour@redhat.com> * cdl/hal.cdl: Add CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT
--- a/packages/hal/common/current/src/generic-stub.c +++ b/packages/hal/common/current/src/generic-stub.c @@ -1264,7 +1264,11 @@ int && __hexToInt (&ptr, &length) && *ptr++ == ':') { - if (is_binary) + /* GDB sometimes sends an impossible length */ + if (length < 0 || length >= BUFMAX) + strcpy (remcomOutBuffer, "E01"); + + else if (is_binary) { while (length > 0) { @@ -1290,7 +1294,7 @@ int else strcpy (remcomOutBuffer, "E03"); } - else + else { if (__hex2mem_safe (ptr, addr, length) != NULL) strcpy (remcomOutBuffer, "OK"); @@ -1389,8 +1393,10 @@ int return -1; } - /* kill the program */ - case 'k' : + case 'D' : /* detach */ + __putpacket (remcomOutBuffer); + /* fall through */ + case 'k' : /* kill the program */ #ifdef __ECOS__ hal_flush_output(); #endif
--- a/packages/hal/i386/arch/current/ChangeLog +++ b/packages/hal/i386/arch/current/ChangeLog @@ -1,3 +1,23 @@ +2001-09-05 Jonathan Larmour <jlarmour@redhat.com> + + * src/vectors.S (__default_interrupt_vsr): Adjust saved stack pointer + for the hardware and trampoline saved data. + (__default_exception_vsr): Ditto. + +2001-08-31 Nick Garnett <nickg@redhat.com> + + * include/arch.inc: Clean up typo in stack switching macros. + +2001-08-22 Nick Garnett <nickg@redhat.com> + + * include/hal_io.h: Added some macros to do in-memory data + accesses for memory mapped devices. + + * include/hal_arch.h: Attempted to make some sense out of the + stack size macros. + + * include/hal_intr.h: Extended VSR table to its full 256 entries. + 2001-07-31 Jonathan Larmour <jlarmour@redhat.com> * src/hal_misc.c: Fix "implicit decl of diag_printf" warning.
--- a/packages/hal/i386/arch/current/cdl/hal_i386.cdl +++ b/packages/hal/i386/arch/current/cdl/hal_i386.cdl @@ -72,6 +72,7 @@ cdl_package CYGPKG_HAL_I386 { @rm target.tmp } + cdl_option CYGBLD_BUILD_I386_ROMBOOT { display "Build ROM bootstrap code" calculated { CYG_HAL_STARTUP == "ROM" }
--- a/packages/hal/i386/arch/current/include/arch.inc +++ b/packages/hal/i386/arch/current/include/arch.inc @@ -78,7 +78,80 @@ #endif +#------------------------------------------------------------------------------ + .macro hal_smp_init + .endm + + .macro hal_smp_cpu reg + movl $0,\reg + .endm + + +#------------------------------------------------------------------------------ +# Stack switching macros + +#ifndef CYG_HAL_PPC_INTSTACK_MACROS_DEFINED + +#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK + + .macro hal_init_istack reg,tr + movl $__interrupt_stack,\reg // Load interrupt stack + .endm + + .macro hal_load_istack reg + movl $__interrupt_stack,\reg // Load interrupt stack + .endm + + .macro hal_load_istack_base reg + movl $__interrupt_stack_base,\reg // Load interrupt stack base + .endm + + + .macro hal_to_intstack + hal_load_istack_base %ebx // EBX = stack base + movl %ebx,%eax + addl $CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE,%eax + cmpl %ebx,%ebp # compare SP with istack base + jb 1f # if sp < istack base, switch + cmpl %eax,%ebp # compare SP with istack top + jbe 2f # if sp < istack top, dont switch +1: + movl %eax,%esp # move on to new stack +2: + pushl %ebp # Save old SP on new stack + .endm + + .macro hal_from_intstack + popl %esp # pop old SP from stack + .endm + +#define CYG_HAL_PPC_INTSTACK_MACROS_DEFINED + + +#else // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK + + .macro hal_init_istack reg + .endm + + .macro hal_load_istack_base reg + .endm + + .macro hal_load_istack reg + .endm + + .macro hal_to_intstack + .endm + + .macro hal_from_intstack + .endm + +#define CYG_HAL_PPC_INTSTACK_MACROS_DEFINED + +#endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK + +#endif // CYG_HAL_PPC_INTSTACK_MACROS_DEFINED + #------------------------------------------------------------------------------ # FPU macros. @@ -127,10 +200,54 @@ # up. subl $i386reg_fpucontext_size,%esp movl $0,i386reg_fpucontext_valid(%esp) - movl %esp,cyg_hal_fpustate_current + hal_smp_cpu %ebx # get CPU id + movl $cyg_hal_fpustate_current,%ecx # current state table + movl %esp,0(%ecx,%ebx,4) # save in table[cpu] entry #endif .endm + .macro hal_fpu_cpu_init + # Tell the CPU to use the math hardware. + movl %cr0, %eax + orl $0x32, %eax # Set MP, ET, NE bits + andl $~0x8, %eax # And clear TS bit + movl %eax, %cr0 + + finit # and initialize... + + ## Enable floating point exceptions. Bit mask: + ## 1 - invalid operation + ## 2 - denormalized operand + ## 4 - zero divide + ## 8 - overflow + ## 16 - underflow + ## 32 - precision + pushl $0 # space for CW + fstcw 0(%esp) # store FPCW to stack + movl 0(%esp),%eax # get into EAX + andb $(~0x04),%al # allow only zero divide exceptions + movl %eax,0(%esp) # put back into memory + fldcw 0(%esp) # reload + addl $4,%esp # pop value + +#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY + # Tell the CPU to generate an FPU unavailable exception + # when the FPU is first used. + movl %cr0, %eax + orl $0x8, %eax + movl %eax, %cr0 + # Now create an FPU context on the stack so that we can take + # FPU-using interrupts and exceptions before the kernel starts + # up. + subl $i386reg_fpucontext_size,%esp + movl $0,i386reg_fpucontext_valid(%esp) + hal_smp_cpu %ebx # get CPU id + movl $cyg_hal_fpustate_current,%ecx # current state table + movl %esp,0(%ecx,%ebx,4) # save in table[cpu] entry +#endif + + .endm + #ifndef CYGHWR_HAL_I386_FPU_SWITCH_LAZY # Non-lazy CPU state switching. We simply switch the entire @@ -206,7 +323,9 @@ 2: # threads FPU context save area. .macro hal_fpu_push_ctx - pushl cyg_hal_fpustate_current # push our FPU state ptr + hal_smp_cpu %ebx # Get CPU id + movl $cyg_hal_fpustate_current,%ecx # current state table + pushl 0(%ecx,%ebx,4) # push table[cpu] entry .endm # We do nothing here but set the CR0:TS bit to force @@ -217,7 +336,9 @@ 2: movl %cr0, %ecx # get CR0 orl $0x8, %ecx # set TS bit movl %ecx, %cr0 # restore CR0 - popl cyg_hal_fpustate_current # set current FPU state pointer + hal_smp_cpu %ebx # get CPU id + movl $cyg_hal_fpustate_current,%ecx # current state table + popl 0(%ecx,%ebx,4) # pop table[cpu] entry .endm # ------------------------------------------------------------ @@ -228,7 +349,9 @@ 2: # interrupt. .macro hal_fpu_push_int - pushl cyg_hal_fpustate_current # push current threads FPU state ptr + hal_smp_cpu %ebx # get CPU id + movl $cyg_hal_fpustate_current,%ecx # current state table + pushl 0(%ecx,%ebx,4) # push table[cpu] entry # ensure that CR0:TS bit is set movl %cr0, %ecx # get CR0 orl $0x8, %ecx # set TS bit @@ -242,7 +365,9 @@ 2: .macro hal_fpu_push_int_annex subl $i386reg_fpucontext_size,%esp movl $0,i386reg_fpucontext_valid(%esp) - movl %esp,cyg_hal_fpustate_current + hal_smp_cpu %ebx # get CPU id + movl $cyg_hal_fpustate_current,%ecx # current state table + movl %esp,0(%ecx,%ebx,4) # save in table[cpu] entry .endm # This is invoked just before any transfer back to the thread stack. @@ -251,9 +376,11 @@ 2: # own state over the top of it. .macro hal_fpu_pop_int_annex - cmpl cyg_hal_fpustate_owner,%esp # are we FPU owner? + hal_smp_cpu %ebx # get CPU id + movl $cyg_hal_fpustate_owner,%ecx # current state table + cmpl 0(%ecx,%ebx,4),%esp # are we FPU owner? jne 1f # if not, then just continue - movl $0,cyg_hal_fpustate_owner # no one owns FPU now + movl $0,0(%ecx,%ebx,4) # no one owns FPU now # ensure that CR0:TS bit is set to force a reload of # the previous FPU state movl %cr0, %ecx # get CR0 @@ -266,7 +393,9 @@ 1: # Final return from interrupt handling. Just pull the current # FPU context off the stack. .macro hal_fpu_pop_int - popl cyg_hal_fpustate_current # set current FPU state pointer + hal_smp_cpu %ebx # get CPU id + movl $cyg_hal_fpustate_current,%ecx # current state table + popl 0(%ecx,%ebx,4) # pop table[cpu] entry .endm # ------------------------------------------------------------ @@ -277,13 +406,16 @@ 1: # whole machine state is saved in memory. .macro hal_fpu_push_exc - pushl cyg_hal_fpustate_current # push our FPU state ptr - movl cyg_hal_fpustate_owner,%eax # EAX = FPU state owner + hal_smp_cpu %ebx # get CPU id + movl $cyg_hal_fpustate_current,%ecx # current state table + pushl 0(%ecx,%ebx,4) # push table[cpu] entry + movl $cyg_hal_fpustate_owner,%ecx # current owner table + movl 0(%ecx,%ebx,4),%eax # EAX = FPU state owner cmpl $0,%eax # test it je 1f # skip if zero fsave i386reg_fpucontext_state(%eax) # save state movl $1,i386reg_fpucontext_valid(%eax) # set valid - movl $0,cyg_hal_fpustate_owner # zero owner pointer + movl $0,0(%ecx,%ebx,4) # zero owner pointer 1: .endm @@ -311,6 +443,9 @@ 1: .macro hal_fpu_init .endm + .macro hal_fpu_cpu_init + .endm + .macro hal_fpu_push_ctx .endm
--- a/packages/hal/i386/arch/current/include/hal_arch.h +++ b/packages/hal/i386/arch/current/include/hal_arch.h @@ -292,26 +292,31 @@ externC void hal_idle_thread_action(cyg_ // This is not a config option because it should not be adjusted except // under "enough rope" sort of disclaimers. -// Stack frame overhead per call. 3 local registers (edi, esi, ebx) and -// return address. -#define CYGNUM_HAL_STACK_FRAME_SIZE (4 * 4) +// Stack frame overhead per call. Four arguments, 3 local registers +// (edi, esi, ebx), four local variables and return address. +#define CYGNUM_HAL_STACK_FRAME_SIZE (12 * 4) -// Stack needed for a context switch (i386reg_context_size from i386.inc) -#define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 24) +// Stack needed for a context switch ( sizeof(HAL_SavedRegisters) ). +#ifdef CYGHWR_HAL_I386_FPU +# ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY +# define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 13) +# else +# define CYGNUM_HAL_STACK_CONTEXT_SIZE ((4 * 12) + 108) +# endif +#else +# define CYGNUM_HAL_STACK_CONTEXT_SIZE (4 * 12) +#endif // Interrupt + call to ISR, interrupt_end() and the DSR #define CYGNUM_HAL_STACK_INTERRUPT_SIZE \ - ((6*4*2 /* 2*sizeof(HAL_SavedRegisters) */) + 4 * CYGNUM_HAL_STACK_FRAME_SIZE) - -// We have lots of registers so no particular amount is added in for -// typical local variable usage. + ((4*CYGNUM_HAL_STACK_CONTEXT_SIZE) + 4 * CYGNUM_HAL_STACK_FRAME_SIZE) // We define a minimum stack size as the minimum any thread could ever // legitimately get away with. We can throw asserts if users ask for less // than this. Allow enough for three interrupt sources - clock, serial and // one other -#if 0 // defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK) +#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK) // An interrupt stack which is large enough for all possible interrupt // conditions (and only used for that purpose) exists. "User" stacks
--- a/packages/hal/i386/arch/current/include/hal_intr.h +++ b/packages/hal/i386/arch/current/include/hal_intr.h @@ -77,11 +77,11 @@ #define CYGNUM_HAL_VECTOR_FPE 16 #define CYGNUM_HAL_VECTOR_ALIGNMENT 17 -// The default size of the VSR table is 64 entries. +// The default size of the VSR table is 256 entries. #ifndef CYGNUM_HAL_VSR_MIN #define CYGNUM_HAL_VSR_MIN 0 -#define CYGNUM_HAL_VSR_MAX 63 -#define CYGNUM_HAL_VSR_COUNT 64 +#define CYGNUM_HAL_VSR_MAX 255 +#define CYGNUM_HAL_VSR_COUNT 256 #endif // Common exception vectors.
--- a/packages/hal/i386/arch/current/include/hal_io.h +++ b/packages/hal/i386/arch/current/include/hal_io.h @@ -167,5 +167,18 @@ CYG_MACRO_END CYG_MACRO_END //----------------------------------------------------------------------------- + +// Macros for acessing shared memory structures + +#define HAL_READMEM_UINT8( _reg_, _val_ ) ((_val_) = *((volatile CYG_BYTE *)(_reg_))) +#define HAL_WRITEMEM_UINT8( _reg_, _val_ ) (*((volatile CYG_BYTE *)(_reg_)) = (_val_)) + +#define HAL_READMEM_UINT16( _reg_, _val_ ) ((_val_) = *((volatile CYG_WORD16 *)(_reg_))) +#define HAL_WRITEMEM_UINT16( _reg_, _val_ ) (*((volatile CYG_WORD16 *)(_reg_)) = (_val_)) + +#define HAL_READMEM_UINT32( _reg_, _val_ ) ((_val_) = *((volatile CYG_WORD32 *)(_reg_))) +#define HAL_WRITEMEM_UINT32( _reg_, _val_ ) (*((volatile CYG_WORD32 *)(_reg_)) = (_val_)) + +//----------------------------------------------------------------------------- #endif // ifndef CYGONCE_HAL_HAL_IO_H // End of hal_io.h
--- a/packages/hal/i386/arch/current/src/i386.ld +++ b/packages/hal/i386/arch/current/src/i386.ld @@ -144,10 +144,8 @@ GROUP(libtarget.a libgcc.a) // Standard tables at base of memory idtStart = 0x00001000; -//idtEnd = 0x00001800; hal_vsr_table = 0x00001800; -hal_virtual_vector_table = 0x00001900; +hal_virtual_vector_table = 0x00001c00; -
--- a/packages/hal/i386/arch/current/src/vectors.S +++ b/packages/hal/i386/arch/current/src/vectors.S @@ -47,6 +47,7 @@ #include <pkgconf/system.h> #include <pkgconf/hal.h> +#include <pkgconf/hal_i386_pc.h> #ifdef CYGPKG_KERNEL #include <pkgconf/kernel.h> @@ -67,6 +68,7 @@ _start: hal_cpu_init + hal_smp_init hal_diag_init hal_mmu_init hal_memc_init @@ -74,7 +76,8 @@ hal_cache_init hal_timer_init - # loading the stack pointer seems appropriate now. + # Loading the stack pointer seems appropriate now. + movl $__interrupt_stack, %esp #if defined(CYG_HAL_STARTUP_FLOPPY) || defined(CYG_HAL_STARTUP_ROM) @@ -131,6 +134,7 @@ .extern cyg_hal_invoke_constructors call cyg_hal_invoke_constructors + .extern cyg_start call cyg_start @@ -153,13 +157,12 @@ 1: hlt pusha # save all registers hal_fpu_push_exc # save FPU state - + mov %esp,%edi # save state pointer in EDI + + # adjust ESP by 16 for the state stored before the pusha + add $16,i386reg_esp(%edi) -#if 0 //def CYGSEM_HAL_ROM_MONITOR - # In a monitor, switch to interrupt stack to handle this - movl $__interrupt_stack,%esp -#endif hal_fpu_push_exc_annex @@ -171,18 +174,12 @@ 1: hlt hal_fpu_pop_exc_annex -#if 0 //def CYGSEM_HAL_ROM_MONITOR - - # If we switched to the interrupt stack, switch back here - # %edi will have been preserved across the call to - # cyg_hal_exception_handler() - - movl %edi,%esp -#endif hal_fpu_pop_exc # restore FPU state popa # restore all our registers. addl $4, %esp # skip the vector number + # Note: we do not need to re-adjust ESP + # back by 16 as popa does not pop ESP. iret # and return to the program. #============================================================================== @@ -203,7 +200,7 @@ 1: hlt pusha # save registers hal_fpu_push_int # save FPU state - + #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) || \ defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) # Save the context just to be able to set a breakpoint @@ -212,7 +209,8 @@ 1: hlt movl %esp,hal_saved_interrupt_state #endif -#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT +#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \ + !defined(CYGPKG_HAL_SMP_SUPPORT) # Increment scheduler lock .extern cyg_scheduler_sched_lock incl cyg_scheduler_sched_lock @@ -220,21 +218,11 @@ 1: hlt movl %esp,%ebp # EBP = copy of ESP -#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK - - # Switch to interrupt stack if we are not already on it - - movl $__interrupt_stack,%eax # eax = stack top - cmpl $__interrupt_stack_base,%ebp # compare SP with istack base - jb 1f # if sp < istack base, switch - cmpl %eax,%ebp # compare SP with istack top - jbe 2f # if sp < istack top, dont switch -1: - movl %eax,%esp # move on to new stack -2: - pushl %ebp # Save old SP on new stack -#endif - + # adjust ESP by 16 for the state stored before the pusha + add $16,i386reg_esp(%esp) + + hal_to_intstack + hal_fpu_push_int_annex # save extra FPU state #ifdef CYGSEM_HAL_COMMON_INTERRUPTS_ALLOW_NESTING @@ -285,17 +273,11 @@ 2: hal_fpu_pop_int_annex # Pop any saved interrupt state -#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK - # If we are returning from the last nested interrupt, move back # to the thread stack. interrupt_end() must be called on the # thread stack since it potentially causes a context switch. - # Since we have arranged for the top of stack location to - # contain the sp we need to go back to here, just pop it off - # into ESP. - popl %esp -#endif + hal_from_intstack #ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT @@ -323,7 +305,8 @@ 2: #============================================================================== ## Execute pending DSRs on the interrupt stack with interrupts enabled. -## Note: this can only be called from code running on a thread stack +## Note: this can only be called from code running on a thread stack so we +## can always just jump to the interrupt stack without looking. #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK @@ -332,33 +315,34 @@ 2: hal_interrupt_stack_call_pending_DSRs: - pushl %esi # save a work register + pushl %ebp # save EBP pushfl # save flags - movl %esp,%esi # ESI = old stack + movl %esp,%ebp # EBP = saved SP - movl $__interrupt_stack,%esp # ESP = interrupt stack + hal_load_istack %edx # load new SP into EDX + movl %edx,%esp # move it to ESP sti # Enable interrupts # Call back to kernel to run DSRs call cyg_interrupt_call_pending_DSRs - # On return ESI will still contain the old ESP since + # On return EBP will still contain the old ESP since # it is a callee saved register. - movl %esi,%esp # restore original stack + movl %ebp,%esp # restore saved SP # Now merge the original IF bit into the current # EFLAGS. - popl %esi # ESI = saved flags + popl %eax # EAX = saved flags pushfl # 0(%esp) = current flags btrl $9,0(%esp) # clear IF bit in current flags - andl $0x00000200,%esi # isolate saved IF bit - orl %esi,0(%esp) # OR it in to the saved flags + andl $0x00000200,%eax # isolate saved IF bit + orl %eax,0(%esp) # OR it in to the saved flags popfl # restore flags - popl %esi # retrieve work register + popl %ebp # restore EBP ret # and return #endif @@ -373,22 +357,41 @@ hal_interrupt_stack_call_pending_DSRs: #ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY +#ifndef CYGPKG_HAL_SMP_CPU_MAX +#define CYGPKG_HAL_SMP_CPU_MAX 1 +#endif + .data .global cyg_hal_fpustate_owner -cyg_hal_fpustate_owner: +cyg_hal_fpustate_owner: + .rept CYGPKG_HAL_SMP_CPU_MAX .long 0 # pointer to FPU owning context + .endr .global cyg_hal_fpustate_current cyg_hal_fpustate_current: + .rept CYGPKG_HAL_SMP_CPU_MAX .long 0 # pointer to current threads FPU context - + .endr + .text __fpu_switch_vsr: + ## We enter here with the CPU state still in the registers and: + ## 0(%esp) vector number pushed by trampoline + ## 4(%esp) PC pushed by hardware + ## 8(%esp) CS pushed by hardware + ## 12(%esp) EFLAGS pushed by hardware + clts # clear CR0:TS bit pusha # save all regs - movl cyg_hal_fpustate_owner,%eax # EAX = FPU context owner - movl cyg_hal_fpustate_current,%ebx # EBX = current threads context + hal_smp_cpu %ecx # ECX = CPU id + movl $cyg_hal_fpustate_owner,%esi # ESI = FPU context owner table + leal 0(%eax,%ecx,4),%esi # ESI = address of owner pointer + movl $cyg_hal_fpustate_current,%edi # EDI = current threads context table + leal 0(%ebx,%ecx,4),%edi # EDI = address of context pointer + movl 0(%esi),%eax # EAX = Current FPU context owner + movl 0(%edi),%ebx # EBX = Current threads FPU context cmpl %ebx,%eax # current == owner ? je 9f # yes, nothing else to do cmpl $0,%eax # is FPU even in use? @@ -396,7 +399,7 @@ cyg_hal_fpustate_current: fsave i386reg_fpucontext_state(%eax) # save FPU state movl $1,i386reg_fpucontext_valid(%eax) # mark valid 1: - movl %ebx,cyg_hal_fpustate_owner # Set new owner + movl %ebx,0(%esi) # Set new owner btl $0,i386reg_fpucontext_valid(%ebx) # Valid state? jc 2f # If yes, go to restore it finit # Otherwise init FPU @@ -409,17 +412,8 @@ 9: iret # and return to the thread. #endif - -#============================================================================== -# hal_idle_thread_action(cyg_uint32 loop_count) - - .align 4 - .globl hal_idle_thread_action -hal_idle_thread_action: - hlt - ret - +#if 0 #============================================================================== # Assembler swap routines @@ -444,7 +438,8 @@ CPU_swap_u32: movb 6(%esp), %ah movb 7(%esp), %al ret - +#endif + #============================================================================== # Exception trampolines # IDT exception gates point to short code sequences that push the vector @@ -561,7 +556,9 @@ default_vsr_iret: #ifndef CYG_HAL_PPC_INTERRUPT_STACK_DEFINED .bss + + .balign 16 .global cyg_interrupt_stack_base cyg_interrupt_stack_base: __interrupt_stack_base: @@ -572,8 +569,9 @@ cyg_interrupt_stack_base: .global cyg_interrupt_stack cyg_interrupt_stack: __interrupt_stack: - - .long 0,0,0,0,0,0,0,0 + + .long 0,0,0,0,0,0,0,0 + #endif
--- a/packages/hal/i386/pc/current/ChangeLog +++ b/packages/hal/i386/pc/current/ChangeLog @@ -1,3 +1,23 @@ +2001-09-07 Jonathan Larmour <jlarmour@redhat.com> + + * misc/redboot_FLOPPY.ecm: Disable + CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS + * misc/redboot_ROM.ecm: Ditto. + +2001-09-05 Jonathan Larmour <jlarmour@redhat.com> + + * src/plf_misc.c (hal_platform_init): If not RAM startup, install + exception VSRs. + +2001-08-22 Nick Garnett <nickg@redhat.com> + + * include/pkgconf/mlt_i386_pc_floppy.ldi: + * include/pkgconf/mlt_i386_pc_floppy.mlt: + Moved load base address from 0x2000 to 0x3000. + + * include/platform.inc (hal_idt_init): Added entries to set up IDT + entries 48..67. + 2001-08-13 Jonathan Larmour <jlarmour@redhat.com> * cdl/hal_i386_pc.cdl: Fix CYG_HAL_STARTUP description.
--- a/packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.ldi +++ b/packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.ldi @@ -12,7 +12,7 @@ MEMORY SECTIONS { SECTIONS_BEGIN - SECTION_vectors (ram, 0x2000, LMA_EQ_VMA) + SECTION_vectors (ram, 0x3000, LMA_EQ_VMA) SECTION_text (ram, ALIGN (0x4), LMA_EQ_VMA) SECTION_fini (ram, ALIGN (0x4), LMA_EQ_VMA) SECTION_rodata1 (ram, ALIGN (0x8), LMA_EQ_VMA)
--- a/packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.mlt +++ b/packages/hal/i386/pc/current/include/pkgconf/mlt_i386_pc_floppy.mlt @@ -1,6 +1,6 @@ version 0 region ram 0 a0000 0 ! -section vectors 0 1 0 1 1 1 1 1 2000 2000 text text ! +section vectors 0 1 0 1 1 1 1 1 3000 3000 text text ! section text 0 4 0 1 0 1 0 1 fini fini ! section fini 0 4 0 1 0 1 0 1 rodata1 rodata1 ! section rodata1 0 8 0 1 0 1 0 1 rodata rodata !
--- a/packages/hal/i386/pc/current/misc/redboot_FLOPPY.ecm +++ b/packages/hal/i386/pc/current/misc/redboot_FLOPPY.ecm @@ -32,6 +32,10 @@ cdl_option CYGBLD_BUILD_REDBOOT { user_value 1 }; +cdl_option CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS { + user_value 0 +}; + #cdl_option CYGSEM_REDBOOT_FLASH_CONFIG { # user_value 1 #};
--- a/packages/hal/i386/pc/current/misc/redboot_ROM.ecm +++ b/packages/hal/i386/pc/current/misc/redboot_ROM.ecm @@ -32,6 +32,10 @@ cdl_option CYGBLD_BUILD_REDBOOT { user_value 1 }; +cdl_option CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS { + user_value 0 +}; + #cdl_option CYGSEM_REDBOOT_FLASH_CONFIG { # user_value 1 #};
--- a/packages/hal/i386/pc/current/src/plf_misc.c +++ b/packages/hal/i386/pc/current/src/plf_misc.c @@ -74,6 +74,7 @@ extern void patch_dbg_syscalls(void * ve extern void hal_pcmb_init(void); + //---------------------------------------------------------------------------- // ISR tables @@ -114,9 +115,18 @@ void hal_platform_init(void) cyg_uint32 index; HAL_TRANSLATE_VECTOR( vector, index ); hal_interrupt_handlers[index] = (CYG_ADDRESS) HAL_DEFAULT_ISR; - HAL_VSR_SET( vector, __default_interrupt_vsr, NULL ); + HAL_VSR_SET( vector, &__default_interrupt_vsr, NULL ); } +#if !defined(CYG_HAL_STARTUP_RAM) + for (vector = CYGNUM_HAL_EXCEPTION_MIN; + vector <= CYGNUM_HAL_EXCEPTION_MAX; + vector++) + { + HAL_VSR_SET( vector, &__default_exception_vsr, NULL ); + } +#endif + #if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) { void hal_ctrlc_isr_init(void); @@ -125,14 +135,6 @@ void hal_platform_init(void) #endif -#if 0 // !defined(CYGSEM_HAL_ROM_MONITOR) - /* Connect to the floating point interrupt. */ - cyg_interrupt_create(CYGNUM_HAL_VECTOR_NO_DEVICE, 1, 0, - hal_pc_fpe_isr, hal_pc_fpe_dsr, - &hal_pc_fpe_interrupt, &hal_pc_fpe_interrupt_object); - cyg_interrupt_attach(hal_pc_fpe_interrupt); -#endif - #ifdef CYGPKG_REDBOOT // Start the timer device running if we are in a RedBoot @@ -144,6 +146,7 @@ void hal_platform_init(void) hal_if_init(); + } /*------------------------------------------------------------------------*/
--- a/packages/hal/i386/pcmb/current/ChangeLog +++ b/packages/hal/i386/pcmb/current/ChangeLog @@ -1,3 +1,11 @@ +2001-08-22 Nick Garnett <nickg@redhat.com> + + * src/pcmb_misc.c: Added spinlock to clock read operation. + + * include/pcmb_io.h (PC_WRITE_SCREEN_*): Added casts to make these + macros more universal. + + 2001-07-31 Mark Salter <msalter@redhat.com> * include/pcmb_io.h: Add IDE I/O macros.
--- a/packages/hal/i386/pcmb/current/cdl/hal_i386_pcmb.cdl +++ b/packages/hal/i386/pcmb/current/cdl/hal_i386_pcmb.cdl @@ -87,6 +87,7 @@ cdl_package CYGPKG_HAL_I386_PCMB { } } + cdl_interface CYGINT_HAL_I386_PCMB_SCREEN_SUPPORT { display "Enable PC screen support" compile pcmb_screen.c
--- a/packages/hal/i386/pcmb/current/include/pcmb_intr.h +++ b/packages/hal/i386/pcmb/current/include/pcmb_intr.h @@ -96,11 +96,12 @@ #define CYGNUM_HAL_INTERRUPT_HDD 46 #define CYGNUM_HAL_ISR_MIN 32 -#define CYGNUM_HAL_ISR_MAX 47 +#define CYGNUM_HAL_ISR_MAX 255 #define CYGNUM_HAL_ISR_COUNT (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1) #define CYGNUM_HAL_INTERRUPT_RTC CYGNUM_HAL_INTERRUPT_TIMER + //-------------------------------------------------------------------------- // Interrupt vector translation @@ -111,6 +112,7 @@ //-------------------------------------------------------------------------- // PIC interrupt acknowledge + #define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ ) \ CYG_MACRO_START \ int x; \ @@ -121,9 +123,11 @@ CYG_MACRO_START HAL_WRITE_UINT8( 0x20, 0x20 ); \ CYG_MACRO_END + //-------------------------------------------------------------------------- // PIC per-interrupt source masking + #define HAL_INTERRUPT_MASK( _vector_ ) \ CYG_MACRO_START \ int x; \ @@ -193,6 +197,7 @@ CYG_MACRO_END #define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ ) + //--------------------------------------------------------------------------- // Clock support.
--- a/packages/hal/i386/pcmb/current/include/pcmb_io.h +++ b/packages/hal/i386/pcmb/current/include/pcmb_io.h @@ -180,17 +180,17 @@ CYG_MACRO_END #define PC_WRITE_SCREEN_8( __pos, __val ) \ { \ char __hex[] = "0123456789ABCDEF"; \ - PC_WRITE_SCREEN( (__pos), __hex[((__val)>>4)&0xF] ); \ - PC_WRITE_SCREEN( ((__pos)+1), __hex[(__val)&0xF] ); \ + PC_WRITE_SCREEN( (__pos), __hex[((int)(__val)>>4)&0xF] ); \ + PC_WRITE_SCREEN( ((__pos)+1), __hex[(int)(__val)&0xF] ); \ } #define PC_WRITE_SCREEN_16( __pos, __val ) \ - PC_WRITE_SCREEN_8( __pos, (__val)>>8 ); \ - PC_WRITE_SCREEN_8( (__pos)+2, __val ); + PC_WRITE_SCREEN_8( __pos, (int)(__val)>>8 ); \ + PC_WRITE_SCREEN_8( (__pos)+2, (int)(__val) ); #define PC_WRITE_SCREEN_32( __pos, __val ) \ - PC_WRITE_SCREEN_16( __pos, (__val)>>16 ); \ - PC_WRITE_SCREEN_16( (__pos)+4, __val ); + PC_WRITE_SCREEN_16( __pos, (int)(__val)>>16 ); \ + PC_WRITE_SCREEN_16( (__pos)+4, (int)(__val) ); //----------------------------------------------------------------------------- // IDE interface macros
--- a/packages/hal/i386/pcmb/current/src/pcmb_misc.c +++ b/packages/hal/i386/pcmb/current/src/pcmb_misc.c @@ -43,6 +43,7 @@ //========================================================================*/ #include <pkgconf/hal.h> +#include <pkgconf/hal_i386.h> #include <pkgconf/hal_i386_pcmb.h> #include <cyg/infra/cyg_type.h> // Base types @@ -88,6 +89,7 @@ void hal_pcmb_init(void) #endif cyg_hal_pcmb_memsize_extended = ((hi<<8)+lo)*1024; + } /*------------------------------------------------------------------------*/ @@ -108,12 +110,17 @@ cyg_uint8 *hal_i386_mem_real_region_top( /*------------------------------------------------------------------------*/ // Clock initialization and access +#define HAL_SPINLOCK_SPIN( lock ) +#define HAL_SPINLOCK_CLEAR( lock ) + void hal_pc_clock_initialize(cyg_uint32 period) { /* Select mode 2: rate generator. Then we'll load LSB, and finally MSB. */ HAL_WRITE_UINT8( PC_PIT_CONTROL, 0x34 ); HAL_WRITE_UINT8( PC_PIT_CLOCK_0, period & 0xFF ); HAL_WRITE_UINT8( PC_PIT_CLOCK_0, period >> 8 ); + + HAL_SPINLOCK_CLEAR( pc_clock_lock ); } @@ -121,11 +128,13 @@ void hal_pc_clock_read(cyg_uint32 * coun { cyg_uint8 lo = 0,hi = 0; cyg_uint32 curr = 0; - cyg_uint32 interruptState ; + CYG_INTERRUPT_STATE interruptState ; /* Hold off on interrupts for a bit. */ HAL_DISABLE_INTERRUPTS(interruptState) ; + HAL_SPINLOCK_SPIN( pc_clock_lock ); + /* Latch counter 0. */ HAL_WRITE_UINT8(PC_PIT_CONTROL, 0x00); @@ -134,6 +143,8 @@ void hal_pc_clock_read(cyg_uint32 * coun HAL_READ_UINT8( PC_PIT_CLOCK_0, hi ); curr = (hi<<8) | lo; + + HAL_SPINLOCK_CLEAR( pc_clock_lock ); /* (Maybe) restore interrupts. */ HAL_RESTORE_INTERRUPTS(interruptState) ; @@ -143,11 +154,11 @@ void hal_pc_clock_read(cyg_uint32 * coun /*------------------------------------------------------------------------*/ -#if 0 void hal_idle_thread_action(cyg_uint32 loop_count) -{ asm("hlt") ; +{ + asm("hlt") ; + } -#endif /*------------------------------------------------------------------------*/ /* End of pcmb_misc.c */
--- a/packages/hal/mips/arch/current/ChangeLog +++ b/packages/hal/mips/arch/current/ChangeLog @@ -1,3 +1,9 @@ +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/redboot_linux_exec.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-08-01 Hugo Tyson <hmt@redhat.com> * src/vectors.S (restore_state): (see the change below 2001-07-03) @@ -1459,7 +1465,7 @@ 1998-07-23 Nick Garnett <nickg@cygnus. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/hal/mips/arch/current/src/redboot_linux_exec.c +++ b/packages/hal/mips/arch/current/src/redboot_linux_exec.c @@ -107,14 +107,14 @@ do_exec(int argc, char *argv[]) __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); baud = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD); - printf("Now booting linux kernel:\n"); - printf(" Base address 0x%08x Entry 0x%08x\n", base_addr, entry); - printf(" Cmdline : %s\n", cmd_line); + diag_printf("Now booting linux kernel:\n"); + diag_printf(" Base address 0x%08x Entry 0x%08x\n", base_addr, entry); + diag_printf(" Cmdline : %s\n", cmd_line); if (wait_time_set) { - printf("About to start execution at %p - abort with ^C within %d seconds\n", - (void *)entry, wait_time); - res = gets(line, sizeof(line), wait_time*1000); + diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", + (void *)entry, wait_time); + res = _rb_gets(line, sizeof(line), wait_time*1000); if (res == _GETS_CTRLC) { return; } @@ -126,23 +126,23 @@ do_exec(int argc, char *argv[]) pcmd = pb->text; pb->memsize.name = pcmd; - pcmd += sprintf(pcmd, "memsize"); + pcmd += diag_sprintf(pcmd, "memsize"); pb->memsize.val = ++pcmd; - pcmd += sprintf(pcmd, "0x%08x", (ram_end - ram_start + 0xFFFFF) & ~0xFFFFF); + pcmd += diag_sprintf(pcmd, "0x%08x", (ram_end - ram_start + 0xFFFFF) & ~0xFFFFF); pb->modetty0.name = ++pcmd; - pcmd += sprintf(pcmd, "modetty0"); + pcmd += diag_sprintf(pcmd, "modetty0"); pb->modetty0.val = ++pcmd; - pcmd += sprintf(pcmd, "%d,n,8,1,hw", baud); + pcmd += diag_sprintf(pcmd, "%d,n,8,1,hw", baud); #ifdef CYGPKG_REDBOOT_NETWORKING pb->ethaddr.name = ++pcmd; - pcmd += sprintf(pcmd, "ethaddr"); + pcmd += diag_sprintf(pcmd, "ethaddr"); pb->ethaddr.val = ++pcmd; - pcmd += sprintf(pcmd, "%02x.%02x.%02x.%02x.%02x.%02x", - __local_enet_addr[0], __local_enet_addr[1], - __local_enet_addr[2], __local_enet_addr[3], - __local_enet_addr[4], __local_enet_addr[5]); + pcmd += diag_sprintf(pcmd, "%02x.%02x.%02x.%02x.%02x.%02x", + __local_enet_addr[0], __local_enet_addr[1], + __local_enet_addr[2], __local_enet_addr[3], + __local_enet_addr[4], __local_enet_addr[5]); pb->env_end.name = NULL; pb->env_end.val = NULL; #else
--- a/packages/hal/mips/rm7000/ocelot/current/ChangeLog +++ b/packages/hal/mips/rm7000/ocelot/current/ChangeLog @@ -1,3 +1,9 @@ +2001-08-31 David Woodhouse <dwmw2@redhat.com> + + * cfl/hal_mips_rm7000_ocelot.cdl: Fix compiler options to use + -mips2 for BE build, and make the LE options match the BE options + in all but endianness. + 2001-08-09 Jonathan Larmour <jlarmour@redhat.com> * include/plf_intr.h: Move HAL_INTERRUPT_ interrupt controller
--- a/packages/hal/mips/rm7000/ocelot/current/cdl/hal_mips_rm7000_ocelot.cdl +++ b/packages/hal/mips/rm7000/ocelot/current/cdl/hal_mips_rm7000_ocelot.cdl @@ -256,7 +256,7 @@ cdl_package CYGPKG_HAL_MIPS_RM7000_OCELO flavor data no_define # -mabi=eabi -mips2 - default_value { CYGPKG_HAL_MIPS_MSBFIRST ? "-G0 -mips32 -EB -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" : "-mips2 -EL -mabi=eabi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" } + default_value { CYGPKG_HAL_MIPS_MSBFIRST ? "-G0 -mips2 -EB -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" : "-G0 -mips2 -EL -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Woverloaded-virtual -g -O2 -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -fvtable-gc -finit-priority" } description " This option controls the global compiler flags which are used to compile all packages by
--- a/packages/hal/mn10300/stb/current/ChangeLog +++ b/packages/hal/mn10300/stb/current/ChangeLog @@ -1,3 +1,8 @@ +2001-09-05 David Howells <dhowells@redhat.com> + + * src/plf_misc.c: made inclusion here of hal_ctrlc_isr() + contingent on the lack of virtual vector support. + 2001-08-15 David Howells <dhowells@redhat.com> * src/hal_diag.c: included hal_misc.h.
--- a/packages/hal/mn10300/stb/current/src/plf_misc.c +++ b/packages/hal/mn10300/stb/current/src/plf_misc.c @@ -128,7 +128,8 @@ void hal_platform_init(void) /*------------------------------------------------------------------------*/ /* Control C ISR support */ -#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) +#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) && \ + !defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT) #if CYGHWR_HAL_MN10300_AM33_STB_GDB_PORT == 0
--- a/packages/hal/powerpc/mpc8xx/current/ChangeLog +++ b/packages/hal/powerpc/mpc8xx/current/ChangeLog @@ -1,3 +1,7 @@ +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/mpc8xxrev.c: Don't use printf(), but rather diag_printf(). + 2001-06-29 Jesper Skov <jskov@redhat.com> * src/var_intr.c: Include new arbiter header. @@ -164,7 +168,7 @@ 2000-02-07 Jesper Skov <jskov@redhat.c // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/hal/powerpc/mpc8xx/current/src/mpc8xxrev.c +++ b/packages/hal/powerpc/mpc8xx/current/src/mpc8xxrev.c @@ -39,6 +39,7 @@ #include <stdio.h> #include <cyg/hal/ppc_regs.h> #include <cyg/hal/hal_io.h> +#include <cyg/infra/diag.h> int main( void ) @@ -49,17 +50,17 @@ main( void ) CYG_TEST_INIT(); asm volatile ("mfspr %0, 287;": "=r" (pvr)); - printf ("Processor PVR: 0x%08x\n", pvr); + diag_printf("Processor PVR: 0x%08x\n", pvr); asm volatile ("mfspr %0, 638;": "=r" (part_mask)); - printf ("Processor IMMR[16:31]: 0x%04x\n", (part_mask & 0xffff)); + diag_printf("Processor IMMR[16:31]: 0x%04x\n", (part_mask & 0xffff)); HAL_READ_UINT16(CYGARC_REG_REV_NUM, rev_num); - printf ("Processor REV_NUM: 0x%04x\n", rev_num); + diag_printf("Processor REV_NUM: 0x%04x\n", rev_num); - printf("\nSee http://www.motorola.com/SPS/RISC/netcomm/ for erratas.\n"); - printf("Look for MPC8xx Versions and Masks in the Publications Library\n"); + diag_printf("\nSee http://www.motorola.com/SPS/RISC/netcomm/ for erratas.\n"); + diag_printf("Look for MPC8xx Versions and Masks in the Publications Library\n"); CYG_TEST_PASS_FINISH("mpc8xx revision dump"); }
--- a/packages/hal/sh/arch/current/ChangeLog +++ b/packages/hal/sh/arch/current/ChangeLog @@ -1,3 +1,13 @@ +2001-09-05 Jesper Skov <jskov@redhat.com> + + * src/sh_stub.c (__single_step): Changed type 2 handling. + +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/redboot_linux_exec.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-07-09 Jesper Skov <jskov@redhat.com> * src/sh_stub.c: Fixed potential SH4 problem in UBC handling. @@ -833,7 +843,7 @@ 1999-04-22 Jesper Skov <jskov@lassi.cy // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/hal/sh/arch/current/src/sh_stub.c +++ b/packages/hal/sh/arch/current/src/sh_stub.c @@ -133,19 +133,27 @@ void __single_step (void) // Match entire address. #if (CYGARC_SH_MOD_UBC == 1) HAL_WRITE_UINT8(CYGARC_REG_BAMRA, CYGARC_REG_BAMRA_BARA_UNMASKED); -#else - HAL_WRITE_UINT32(CYGARC_REG_BAMRA, 0xffffffff); +#elif (CYGARC_SH_MOD_UBC == 2) + // For some reason, matching all bits causes the system to hang + // (not just run amok - it appears to stop execution). + //HAL_WRITE_UINT32(CYGARC_REG_BAMRA, 0xffffffff); + HAL_WRITE_UINT32(CYGARC_REG_BAMRA, 0); #endif + // Stop after instruction at matching address has executed. - HAL_WRITE_UINT16(CYGARC_REG_BRCR, CYGARC_REG_BRCR_PCBA); +#if (CYGARC_SH_MOD_UBC == 1) + HAL_WRITE_UINT16(CYGARC_REG_BRCR, CYGARC_REG_BRCR_ONE_STEP); +#else + HAL_WRITE_UINT32(CYGARC_REG_BRCR, CYGARC_REG_BRCR_ONE_STEP); +#endif // Stop on IFETCH/READ -#if (CYGARC_SH_MOD_UBC == 3) +#if (CYGARC_SH_MOD_UBC == 1) + HAL_WRITE_UINT16(CYGARC_REG_BBRA, + CYGARC_REG_BBRA_IFETCH|CYGARC_REG_BBRA_READ); +#else HAL_WRITE_UINT16(CYGARC_REG_BBRA, CYGARC_REG_BBRA_CPU|CYGARC_REG_BBRA_IFETCH|CYGARC_REG_BBRA_READ); -#else - HAL_WRITE_UINT16(CYGARC_REG_BBRA, - CYGARC_REG_BBRA_IFETCH|CYGARC_REG_BBRA_READ); #endif #ifdef CYGPKG_HAL_SH_SH4
--- a/packages/hal/sh/sh3/current/ChangeLog +++ b/packages/hal/sh/sh3/current/ChangeLog @@ -1,3 +1,9 @@ +2001-09-05 Jesper Skov <jskov@redhat.com> + + * include/mod_regs_ubc.h: Type 2 BRCR definitions. + + * include/mod_7729.h (CYGARC_SH_MOD_UBC): Changed to type 2. + 2001-07-26 Jesper Skov <jskov@redhat.com> * include/var_cache.h: Fix cache query function.
--- a/packages/hal/sh/sh3/current/include/mod_7729.h +++ b/packages/hal/sh/sh3/current/include/mod_7729.h @@ -55,7 +55,7 @@ #define CYGARC_SH_MOD_PFC 1 #define CYGARC_SH_MOD_SCI 1 #define CYGARC_SH_MOD_SCIF 1 -//#define CYGARC_SH_MOD_UBC 3 +#define CYGARC_SH_MOD_UBC 2 //-----------------------------------------------------------------------------
--- a/packages/hal/sh/sh3/current/include/mod_regs_ubc.h +++ b/packages/hal/sh/sh3/current/include/mod_regs_ubc.h @@ -41,7 +41,7 @@ //-------------------------------------------------------------------------- // User Break Control -#define CYGARC_REG_BRCR 0xffffff98 // 16 bit +#define CYGARC_REG_BRCR 0xffffff98 // 16 bit (v1) / 32 bit #define CYGARC_REG_BARA 0xffffffb0 // 32 bit #define CYGARC_REG_BAMRA 0xffffffb4 // 8 bit (v1) / 32 bit @@ -55,20 +55,39 @@ #define CYGARC_REG_BDRB 0xffffff90 // 32 bit #define CYGARC_REG_BDMRB 0xffffff94 // 32 bit +#ifdef CYGARC_SH_MOD_UBC -#define CYGARC_REG_BRCR_CMFA 0x8000 // condition match flag A -#define CYGARC_REG_BRCR_CMFB 0x4000 // condition match flag B -#define CYGARC_REG_BRCR_PCBA 0x0400 // post execute channel A -#define CYGARC_REG_BRCR_DBEB 0x0080 // data break enable B -#define CYGARC_REG_BRCR_PCBB 0x0040 // post execute channel B -#define CYGARC_REG_BRCR_SEQ 0x0008 // sequence condition select +#if (CYGARC_SH_MOD_UBC == 1) +# define CYGARC_REG_BRCR_CMFA 0x8000 // condition match flag A +# define CYGARC_REG_BRCR_CMFB 0x4000 // condition match flag B +# define CYGARC_REG_BRCR_PCBA 0x0400 // post execute channel A +# define CYGARC_REG_BRCR_DBEB 0x0080 // data break enable B +# define CYGARC_REG_BRCR_PCBB 0x0040 // post execute channel B +# define CYGARC_REG_BRCR_SEQ 0x0008 // sequence condition select +# define CYGARC_REG_BRCR_ONE_STEP (CYGARC_REG_BRCR_PCBA) +#else +# define CYGARC_REG_BRCR_BASMA 0x00200000 // asid not checked +# define CYGARC_REG_BRCR_BASMB 0x00100000 +# define CYGARC_REG_BRCR_SCMFCA 0x00008000 +# define CYGARC_REG_BRCR_SCMFCB 0x00004000 +# define CYGARC_REG_BRCR_SCMFDA 0x00002000 +# define CYGARC_REG_BRCR_SCMFDB 0x00001000 +# define CYGARC_REG_BRCR_PCTE 0x00000800 // PC trace enable +# define CYGARC_REG_BRCR_PCBA 0x00000400 // post execute +# define CYGARC_REG_BRCR_DBEB 0x00000080 // data break +# define CYGARC_REG_BRCR_PCBB 0x00000040 +# define CYGARC_REG_BRCR_SEQ 0x00000008 // A and B channel in sequence +# define CYGARC_REG_BRCR_ETBE 0x00000001 // execution count on B matches +# define CYGARC_REG_BRCR_ONE_STEP (CYGARC_REG_BRCR_BASMA | CYGARC_REG_BRCR_PCBA) +#endif -#if defined(CYGARC_SH_MOD_UBC) && (CYGARC_SH_MOD_UBC == 1) -#define CYGARC_REG_BAMRA_BASMA 0x04 // BASRA masked -#define CYGARC_REG_BAMRA_BARA_UNMASKED 0x00 // BARA not masked -#define CYGARC_REG_BAMRA_BARA_10BIT 0x01 // Lowest 10 bit masked -#define CYGARC_REG_BAMRA_BARA_12BIT 0x02 // Lowest 12 bit masked -#define CYGARC_REG_BAMRA_BARA_MASKED 0x03 // All bits masked + +#if (CYGARC_SH_MOD_UBC == 1) +# define CYGARC_REG_BAMRA_BASMA 0x04 // BASRA masked +# define CYGARC_REG_BAMRA_BARA_UNMASKED 0x00 // BARA not masked +# define CYGARC_REG_BAMRA_BARA_10BIT 0x01 // Lowest 10 bit masked +# define CYGARC_REG_BAMRA_BARA_12BIT 0x02 // Lowest 12 bit masked +# define CYGARC_REG_BAMRA_BARA_MASKED 0x03 // All bits masked #else // mask is fully configurable in other versions of the UBC #endif @@ -85,7 +104,7 @@ //---------------------------------------------------------------------------- // Other types -#if defined(CYGARC_SH_MOD_UBC) && (CYGARC_SH_MOD_UBC >= 3) +#if (CYGARC_SH_MOD_UBC == 2) #define CYGARC_REG_BETR 0xffffff9c // 16 bit #define CYGARC_REG_BRSR 0xffffffac // 32 bit #define CYGARC_REG_BRDR 0xffffffbc // 32 bit @@ -93,3 +112,5 @@ #define CYGARC_REG_BBRA_DMA 0x0080 // Break on DMAC cycle #define CYGARC_REG_BBRA_CPU 0x0040 // Break on CPU cycle #endif + +#endif // CYGARC_SH_MOD_UBC
--- a/packages/infra/current/ChangeLog +++ b/packages/infra/current/ChangeLog @@ -1,3 +1,43 @@ +2001-08-25 Gary Thomas <gthomas@redhat.com> + + * src/diag.cxx (_vprintf): Fix confusion between signed and unsigned + descriptors (only %d is signed). + +2001-08-24 Gary Thomas <gthomas@redhat.com> + + * include/diag.h: Export diag_dump_buf_with_offset. + + * src/diag.cxx (_vprintf): Fix problems with signed/unsigned prints. + (diag_dump_buf_with_offset): Export. + +2001-08-23 Gary Thomas <gthomas@redhat.com> + + * src/diag.cxx (_vprintf): Restore functionality of %D,%U,%X,%B,%S,%C + which were present in old code. + +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/diag.cxx: + * include/diag.h: + * cdl/infra.cdl: Restructuring to support more flexible versions + of diag_printf() and related functions. Remove old cruft which + was workaround for possibly failing compilers [K&R support]. + These versions of printf(), etc, were part of the RedBoot package + and have been moved here (and renamed) to reduce code duplication. + +2001-08-22 Jonathan Larmour <jlarmour@redhat.com> + + * src/eprintf.c: New file to implement __eprintf called from libgcc. + * cdl/infra.cdl: Build it. + * include/cyg_type.h: Provide __THROW default empty throw specifier. + * include/cyg_ass.h (cyg_assert_fail): Add __THROW. + (cyg_assert_msg): Ditto. + * src/buffer.cxx (cyg_assert_fail): Ditto. + * src/fancy.cxx (cyg_assert_fail): Ditto. + * src/null.cxx (cyg_assert_fail): Ditto (twice). + * src/simple.cxx (cyg_assert_fail): Ditto. + * src/tcdiag.cxx (cyg_assert_msg): Ditto. + 2001-08-03 Nick Garnett <nickg@cygnus.co.uk> Imported from a development branch: @@ -731,7 +771,7 @@ 1998-08-20 Nick Garnett <nickg@cygnus. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/infra/current/cdl/infra.cdl +++ b/packages/infra/current/cdl/infra.cdl @@ -23,7 +23,7 @@ # # The Initial Developer of the Original Code is Red Hat. # Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. # All Rights Reserved. # ------------------------------------------- # @@ -50,7 +50,7 @@ cdl_package CYGPKG_INFRA { compile startup.cxx prestart.cxx pkgstart.cxx userstart.cxx \ dummyxxmain.cxx null.cxx simple.cxx fancy.cxx buffer.cxx \ - diag.cxx tcdiag.cxx memcpy.c memset.c delete.cxx + diag.cxx tcdiag.cxx memcpy.c memset.c delete.cxx eprintf.c # ==================================================================== @@ -65,19 +65,6 @@ cdl_package CYGPKG_INFRA { # set up according to the selected HAL." # } - cdl_option CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG { - display "Use varargs in diag_printf()" - default_value 1 - description " - The diagnostic routine diag_printf() can be defined - using either variadic arguments or a K&R style definition. - The former will work in most circumstances, but if variable - argument handling is broken or missing then the K&R variant - may be used. This will also generate warnings about the - declaration of diag_printf() not being a prototype. - These may safely be ignored." - } - # ==================================================================== cdl_component CYGPKG_INFRA_DEBUG { display "Asserts & Tracing" @@ -182,14 +169,6 @@ cdl_package CYGPKG_INFRA { # ======================================================================== # Debugging-related miscellania. - # - # NOTE: this is not yet fully supported, by CDL nor by having a proper - # symbol name. - # - # Define how diag data is directed off of the board. If using an actual - # device then a device must be configured to support diag. - # - #undef CYGDBG_INFRA_DIAG_USE_DEVICE define_proc { puts $::cdl_header "/***** proc output start *****/"
--- a/packages/infra/current/include/cyg_ass.h +++ b/packages/infra/current/include/cyg_ass.h @@ -75,7 +75,7 @@ externC void cyg_assert_fail( const char* /* psz_func */, const char* /* psz_file */, - cyg_uint32 /* linenum */, const char* /* psz_msg */ ) + cyg_uint32 /* linenum */, const char* /* psz_msg */ ) __THROW CYGBLD_ATTRIB_NORET CYGBLD_ATTRIB_WEAK;
--- a/packages/infra/current/include/cyg_type.h +++ b/packages/infra/current/include/cyg_type.h @@ -362,6 +362,12 @@ typedef cyg_haladdrword CYG_ADDRWORD; # define CYGBLD_ATTRIB_WEAK_ALIAS(__symbol__) \ CYGBLD_ATTRIB_WEAK CYGBLD_ATTRIB_ALIAS(__symbol__) +#ifdef __cplusplus +# define __THROW throw() +#else +# define __THROW +#endif + // ------------------------------------------------------------------------- // Variable annotations // These annotations may be added to various static variables in the
--- a/packages/infra/current/include/diag.h +++ b/packages/infra/current/include/diag.h @@ -26,7 +26,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // @@ -35,7 +35,7 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): nickg -// Contributors: nickg +// Contributors: nickg, gthomas // Date: 1998-03-02 // Purpose: Diagnostic Routines for Infra Development // Description: Diagnostic routines for use during infra development. @@ -47,14 +47,7 @@ #include <pkgconf/infra.h> #include <cyg/infra/cyg_type.h> - -#ifdef CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG #include <stdarg.h> -#endif - -#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE -#include <cyg/io/io_diag.h> -#endif /*---------------------------------------------------------------------------*/ /* Diagnostic routines */ @@ -70,35 +63,23 @@ externC void diag_write_dec( cyg_int32 n externC void diag_write_hex( cyg_uint32 n); /* Write hexadecimal value */ externC void diag_dump_buf(void *buf, CYG_ADDRWORD len); - -#ifdef CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG +externC void diag_dump_buf_with_offset(cyg_uint8 *p, + CYG_ADDRWORD s, + cyg_uint8 *base); -externC void diag_printf( const char *fmt, ... ); /* Formatted print */ - -#else +externC int diag_printf( const char *fmt, ... ); /* Formatted print */ -// This function deliberately has a K&R prototype to avoid having to use -// varargs, or pad arglists or anything grody like that. - -#warning CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG not enabled -#warning Expect a "function declaration isn't a prototype" warning +externC void diag_init_putc(void (*putc)(char c, void **param)); +externC int diag_sprintf(char *buf, const char *fmt, ...); +externC int diag_vsprintf(char *buf, const char *fmt, va_list ap); +externC int diag_vprintf(const char *fmt, va_list ap); -externC void diag_printf(/* const char *fmt, CYG_ADDRWORD, CYG_ADDRWORD, - CYG_ADDRWORD, CYG_ADDRWORD, CYG_ADDRWORD, - CYG_ADDRWORD, CYG_ADDRWORD, CYG_ADDRWORD */); - -#endif /*---------------------------------------------------------------------------*/ /* Internal Diagnostic MACROS */ -#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE -#define DIAG_DEVICE_START_SYNC() diag_device_start_sync() -#define DIAG_DEVICE_END_SYNC() diag_device_end_sync() -#else #define DIAG_DEVICE_START_SYNC() #define DIAG_DEVICE_END_SYNC() -#endif /*---------------------------------------------------------------------------*/ #endif /* CYGONCE_INFRA_DIAG_H */
--- a/packages/infra/current/src/buffer.cxx +++ b/packages/infra/current/src/buffer.cxx @@ -711,7 +711,7 @@ cyg_trace_dump(void) externC void cyg_assert_fail( const char *psz_func, const char *psz_file, - cyg_uint32 linenum, const char *psz_msg ) + cyg_uint32 linenum, const char *psz_msg ) __THROW { cyg_uint32 old_ints;
--- a/packages/infra/current/src/diag.cxx +++ b/packages/infra/current/src/diag.cxx @@ -23,7 +23,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // @@ -31,8 +31,8 @@ //======================================================================== //#####DESCRIPTIONBEGIN#### // -// Author(s): nickg -// Contributors: nickg +// Author(s): nickg,gthomas,jlarmour +// Contributors: // Date: 1999-02-22 // Purpose: Infrastructure diagnostic output // Description: Implementations of infrastructure diagnostic routines. @@ -46,26 +46,18 @@ #include <pkgconf/infra.h> #include <cyg/infra/cyg_type.h> // base types - + #include <cyg/infra/diag.h> // HAL polled output #include <cyg/hal/hal_arch.h> // architectural stuff for... #include <cyg/hal/hal_intr.h> // interrupt control #include <cyg/hal/hal_diag.h> // diagnostic output routines - -#ifdef CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG - #include <stdarg.h> - -#endif - -#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE -#include <cyg/io/io_diag.h> -#endif - +#include <limits.h> + #ifdef CYG_HAL_DIAG_LOCK_DATA_DEFN CYG_HAL_DIAG_LOCK_DATA_DEFN; #endif - + /*----------------------------------------------------------------------*/ externC void diag_write_num( @@ -79,30 +71,10 @@ externC void diag_write_num( class Cyg_dummy_diag_init_class { public: Cyg_dummy_diag_init_class() { -#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE - diag_device_init(); -#else HAL_DIAG_INIT(); -#endif } }; -#ifdef CYGDBG_INFRA_DIAG_USE_DEVICE - -// Initialize after IO devices. -static Cyg_dummy_diag_init_class cyg_dummy_diag_init_obj - CYGBLD_ATTRIB_INIT_AFTER(CYG_INIT_IO); - -/*----------------------------------------------------------------------*/ -/* Write single char to output */ - -externC void diag_write_char(char c) -{ - diag_device_write_char(c); -} - -#else - // Initialize after HAL. static Cyg_dummy_diag_init_class cyg_dummy_diag_init_obj CYGBLD_ATTRIB_INIT_AFTER(CYG_INIT_HAL); @@ -110,23 +82,24 @@ static Cyg_dummy_diag_init_class cyg_dum /*----------------------------------------------------------------------*/ /* Write single char to output */ -#define PREFIX() -//#define PREFIX() HAL_DIAG_WRITE_CHAR(0x0F) - externC void diag_write_char(char c) { /* Translate LF into CRLF */ if( c == '\n' ) { - PREFIX(); HAL_DIAG_WRITE_CHAR('\r'); } - PREFIX(); HAL_DIAG_WRITE_CHAR(c); } -#endif + +// Default wrapper function used by diag_printf +static void +_diag_write_char(char c, void **param) +{ + diag_write_char(c); +} /*----------------------------------------------------------------------*/ /* Initialize. Call to pull in diag initializing constructor */ @@ -135,6 +108,18 @@ externC void diag_init(void) { } +// +// This routine is used to send characters during 'printf()' functions. +// It can be replaced by providing a replacement via diag_init_putc(). +// +static void (*_putc)(char c, void **param) = _diag_write_char; + +void +diag_init_putc(void (*putc)(char c, void **param)) +{ + _putc = putc; +} + /*----------------------------------------------------------------------*/ /* Write zero terminated string */ @@ -264,256 +249,310 @@ static cyg_bool diag_check_string( const /*----------------------------------------------------------------------*/ -externC void diag_vprintf( const char *fmt, CYG_ADDRWORD *args) +static int +_cvt(unsigned long long val, char *buf, long radix, char *digits) { + char temp[80]; + char *cp = temp; + int length = 0; - cyg_bool pad = true; + if (val == 0) { + /* Special case */ + *cp++ = '0'; + } else { + while (val) { + *cp++ = digits[val % radix]; + val /= radix; + } + } + while (cp != temp) { + *buf++ = *--cp; + length++; + } + *buf = '\0'; + return (length); +} - if( !diag_check_string(fmt) ) - { - int i; +#define is_digit(c) ((c >= '0') && (c <= '9')) + +static int +_vprintf(void (*putc)(char c, void **param), void **param, const char *fmt, va_list ap) +{ + char buf[sizeof(long long)*8]; + char c, sign, *cp=buf; + int left_prec, right_prec, zero_fill, pad, pad_on_right, + i, islong, islonglong; + long long val = 0; + int res = 0, length = 0; + + if (!diag_check_string(fmt)) { diag_write_string("<Bad format string: "); diag_write_hex((cyg_uint32)fmt); diag_write_string(" :"); - for( i = 0; i < 8; i++ ) - { + for( i = 0; i < 8; i++ ) { diag_write_char(' '); - diag_write_hex(args[i]); + val = va_arg(ap, unsigned long); + diag_write_hex(val); } diag_write_string(">\n"); - return; + return 0; } - - while( *fmt != '\0' ) - { - char c = *fmt; - - if( c != '%' ) diag_write_char( c ); - else - { - cyg_bool pfzero = false; - cyg_count8 width = 0; - char sign = '+'; - cyg_bool long_op = false; - - c = *++fmt; - - if( c == '0' ) pfzero = true; - - while( '0' <= c && c <= '9' ) - { - width = width*10 + c - '0'; - c = *++fmt; + while ((c = *fmt++) != '\0') { + if (c == '%') { + c = *fmt++; + left_prec = right_prec = pad_on_right = islong = islonglong = 0; + if (c == '-') { + c = *fmt++; + pad_on_right++; + } + if (c == '0') { + zero_fill = true; + c = *fmt++; + } else { + zero_fill = false; + } + while (is_digit(c)) { + left_prec = (left_prec * 10) + (c - '0'); + c = *fmt++; } - + if (c == '.') { + c = *fmt++; + zero_fill++; + while (is_digit(c)) { + right_prec = (right_prec * 10) + (c - '0'); + c = *fmt++; + } + } else { + right_prec = left_prec; + } + sign = '\0'; if (c == 'l') { - // %lx and %ld are equivalent to %x/%d - c = *++fmt; - // %llx or %lld used to indicate (long long) operand + // 'long' qualifier + c = *fmt++; + islong = 1; if (c == 'l') { - long_op = true; - c = *++fmt; + // long long qualifier + c = *fmt++; + islonglong = 1; } } - - if (long_op) { - if(pad) args++; - pad=false; - } else { - pad=!pad; - } - - switch( c ) - { + // Fetch value [numeric descriptors only] + switch (c) { + case 'p': + islong = 1; case 'd': case 'D': - { - if (long_op) { - long long *lp = (long long *)args; - long long val = *lp++; - args = (CYG_ADDRWORD *)lp; - if( val < 0 ) val = -val, sign = '-'; - diag_write_long_num(val, 10, sign, pfzero, width); + case 'x': + case 'X': + case 'u': + case 'U': + case 'b': + case 'B': + if (islonglong) { + val = va_arg(ap, long long); + } else if (islong) { + val = (long long)va_arg(ap, long); + } else{ + val = (long long)va_arg(ap, int); + } + if ((c == 'd') || (c == 'D')) { + if (val < 0) { + sign = '-'; + val = -val; + } } else { - long val = (long)(*args++); - if( val < 0 ) val = -val, sign = '-'; - diag_write_num(val, 10, sign, pfzero, width); + // Mask to unsigned, sized quantity + if (islong) { + val &= ((long long)1 << (sizeof(long) * 8)) - 1; + } else{ + val &= ((long long)1 << (sizeof(int) * 8)) - 1; + } } break; + default: + break; } - + // Process output + switch (c) { + case 'p': // Pointer + (*putc)('0', param); + (*putc)('x', param); + zero_fill = true; + left_prec = sizeof(unsigned long)*2; + case 'd': + case 'D': + case 'u': + case 'U': case 'x': case 'X': - { - if (long_op) { - long long *lp = (long long *)args; - long long val = *lp++; - args = (CYG_ADDRWORD *)lp; - diag_write_long_num(val, 16, sign, pfzero, width); - } else { - unsigned long val = (long)(*args++); - diag_write_num(val, 16, sign, pfzero, width); + switch (c) { + case 'd': + case 'D': + case 'u': + case 'U': + length = _cvt(val, buf, 10, "0123456789"); + break; + case 'p': + case 'x': + length = _cvt(val, buf, 16, "0123456789abcdef"); + break; + case 'X': + length = _cvt(val, buf, 16, "0123456789ABCDEF"); + break; } + cp = buf; break; - } - - case 'c': - case 'C': - { - char ch = (char)(*args++); - diag_write_char(ch); - break; - } - case 's': case 'S': - { - char *s = (char *)(*args++); - cyg_count32 len = 0; - cyg_count32 pre = 0, post = 0; - - if( s == NULL ) s = "<null>"; - else if( !diag_check_string(s) ) - { + cp = va_arg(ap, char *); + if (cp == NULL) + cp = "<null>"; + else if (!diag_check_string(cp)) { diag_write_string("<Not a string: 0x"); - diag_write_hex((cyg_uint32)s); - s = ">"; - if( width > 25 ) width -= 25; - pfzero = false; - /* Drop through to print the closing ">" */ - /* and pad to the required length. */ + diag_write_hex((cyg_uint32)cp); + cp = ">"; } - - while( s[len] != 0 ) len++; - - if( width && len > width ) len = width; - - if( pfzero ) pre = width-len; - else post = width-len; - - while( pre-- > 0 ) diag_write_char(' '); - - while( *s != '\0' && len-- != 0) - diag_write_char(*s++); - - while( post-- > 0 ) diag_write_char(' '); - + length = 0; + while (cp[length] != '\0') length++; break; - } - + case 'c': + case 'C': + c = va_arg(ap, int /*char*/); + (*putc)(c, param); + res++; + continue; case 'b': case 'B': - { - unsigned long val = (unsigned long)(*args++); - cyg_uint32 i; - if( width == 0 ) width = 32; - - for( i = width-1; i >= 0; i-- ) - diag_write_char( (val&(1<<i))?'1':'.' ); - + length = left_prec; + if (left_prec == 0) { + if (islonglong) + length = sizeof(long long)*8; + else if (islong) + length = sizeof(long)*8; + else + length = sizeof(int)*8; + } + for (i = 0; i < length-1; i++) { + buf[i] = ((val & ((long long)1<<i)) ? '1' : '.'); + } + cp = buf; break; - } - case '%': - diag_write_char('%'); - break; - - default: - diag_write_char('%'); - diag_write_char(c); + (*putc)('%', param); break; + default: + (*putc)('%', param); + (*putc)(c, param); + res += 2; } + pad = left_prec - length; + if (sign != '\0') { + pad--; + } + if (zero_fill) { + c = '0'; + if (sign != '\0') { + (*putc)(sign, param); + res++; + sign = '\0'; + } + } else { + c = ' '; + } + if (!pad_on_right) { + while (pad-- > 0) { + (*putc)(c, param); + res++; + } + } + if (sign != '\0') { + (*putc)(sign, param); + res++; + } + while (length-- > 0) { + c = *cp++; + if (c == '\n') { + (*putc)('\r', param); + res++; + } + (*putc)(c, param); + res++; + } + if (pad_on_right) { + while (pad-- > 0) { + (*putc)(' ', param); + res++; + } + } + } else { + if (c == '\n') { + (*putc)('\r', param); + res++; + } + (*putc)(c, param); + res++; } - - fmt++; - } - + } + return (res); } -/*-----------------------------------------------------------------------*/ -/* Formatted diagnostic output. */ - -#ifdef CYGDBG_INFRA_DIAG_PRINTF_USE_VARARG - -externC void diag_printf(const char *fmt, ... ) +static void +_sputc(char c, void **param) { - - CYG_ADDRWORD args[8]; + char *_sprintf_ptr = (char *)*param; - va_list a; - - va_start(a, fmt); + *_sprintf_ptr++ = c; + *_sprintf_ptr = '\0'; + *param = _sprintf_ptr; +} - /* Move all of the arguments into simple scalars. This avoids - * having to use varargs to define diag_vprintf(). - */ - - args[0] = va_arg(a,CYG_ADDRWORD); - args[1] = va_arg(a,CYG_ADDRWORD); - args[2] = va_arg(a,CYG_ADDRWORD); - args[3] = va_arg(a,CYG_ADDRWORD); - args[4] = va_arg(a,CYG_ADDRWORD); - args[5] = va_arg(a,CYG_ADDRWORD); - args[6] = va_arg(a,CYG_ADDRWORD); - args[7] = va_arg(a,CYG_ADDRWORD); +int +diag_sprintf(char *buf, const char *fmt, ...) +{ + int ret; + va_list ap; + char *_sprintf_ptr; - va_end(a); - -#ifdef CYG_HAL_DIAG_LOCK - CYG_HAL_DIAG_LOCK(); -#endif - - diag_vprintf( fmt, args); - -#ifdef CYG_HAL_DIAG_UNLOCK - CYG_HAL_DIAG_UNLOCK(); -#endif - + va_start(ap, fmt); + _sprintf_ptr = buf; + ret = _vprintf(_sputc, (void **)&_sprintf_ptr, fmt, ap); + va_end(ap); + return (ret); } -#else - -/* The prototype for diag_printf in diag.h is defined using K&R syntax */ -/* to allow us to use a variable number of arguments in the call without */ -/* using ellipses, which would require use of varargs stuff. If we ever */ -/* need to support arguments that are not simple words, we may need to */ -/* use varargs. */ -/* For the actual implementation, a normal ANSI C prototype is */ -/* acceptable. */ - -externC void diag_printf(const char *fmt, CYG_ADDRWORD a1, CYG_ADDRWORD a2, - CYG_ADDRWORD a3, CYG_ADDRWORD a4, - CYG_ADDRWORD a5, CYG_ADDRWORD a6, - CYG_ADDRWORD a7, CYG_ADDRWORD a8) +int +diag_vsprintf(char *buf, const char *fmt, va_list ap) { - - CYG_ADDRWORD args[8]; + int ret; + char *_sprintf_ptr; - args[0] = a1; - args[1] = a2; - args[2] = a3; - args[3] = a4; - args[4] = a5; - args[5] = a6; - args[6] = a7; - args[7] = a8; - - -#ifdef CYG_HAL_DIAG_LOCK - CYG_HAL_DIAG_LOCK(); -#endif - - diag_vprintf( fmt, args); - -#ifdef CYG_HAL_DIAG_UNLOCK - CYG_HAL_DIAG_UNLOCK(); -#endif - + _sprintf_ptr = buf; + ret = _vprintf(_sputc, (void **)&_sprintf_ptr, fmt, ap); + return (ret); } -#endif +int +diag_printf(const char *fmt, ...) +{ + va_list ap; + int ret; -static void + va_start(ap, fmt); + ret = _vprintf(_putc, (void **)0, fmt, ap); + va_end(ap); + return (ret); +} + +int +diag_vprintf(const char *fmt, va_list ap) +{ + int ret; + + ret = _vprintf(_putc, (void **)0, fmt, ap); + return (ret); +} + +void diag_dump_buf_with_offset(cyg_uint8 *p, CYG_ADDRWORD s, cyg_uint8 *base)
new file mode 100644 --- /dev/null +++ b/packages/infra/current/src/eprintf.c @@ -0,0 +1,83 @@ +//======================================================================== +// +// eprintf.c +// +// __eprintf() used by libgcc +// +//======================================================================== +//####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) 2001 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//======================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jlarmour +// Contributors: +// Date: 2001-08-21 +// Purpose: Provide __eprintf() as used by libgcc. +// Description: libgcc calls __eprintf() to display errors and abort. +// Usage: +// +//####DESCRIPTIONEND#### +// +//======================================================================== + +// CONFIGURATION + +#include <pkgconf/system.h> +/* We can't do anything without the isoinfra package */ +#ifdef CYGPKG_ISOINFRA +#include <pkgconf/isoinfra.h> // Configuration header + +// INCLUDES + +#include <cyg/infra/cyg_type.h> // Common type definitions and support +#include <cyg/infra/cyg_ass.h> // Default assertion +#include <stdio.h> +#include <stdlib.h> + +// FUNCTIONS + +__externC void +__eprintf (const char *string, const char *expression, + unsigned int line, const char *filename) +{ +#ifdef CYGINT_ISO_STDIO_FORMATTED_IO + fprintf(stderr, string, expression, line, filename); +#else + diag_printf(string, expression, line, filename); +#endif +#ifdef CYGINT_ISO_STDIO_FILEACCESS + fflush (stderr); +#endif +#if CYGINT_ISO_EXIT + abort(); +#else + CYG_FAIL( "Aborting" ); + for (;;); +#endif +} // __eprintf() + +#endif // ifdef CYGPKG_ISOINFRA + +// EOF eprintf.c
--- a/packages/infra/current/src/fancy.cxx +++ b/packages/infra/current/src/fancy.cxx @@ -589,7 +589,7 @@ cyg_trace_dump(void) externC void cyg_assert_fail( const char *psz_func, const char *psz_file, - cyg_uint32 linenum, const char *psz_msg ) + cyg_uint32 linenum, const char *psz_msg ) __THROW { cyg_uint32 old_ints;
--- a/packages/infra/current/src/null.cxx +++ b/packages/infra/current/src/null.cxx @@ -57,7 +57,7 @@ externC void cyg_assert_fail( const char *psz_func, const char *psz_file, - cyg_uint32 linenum, const char *psz_msg ) + cyg_uint32 linenum, const char *psz_msg ) __THROW { for(;;); }; @@ -132,7 +132,7 @@ cyg_trace_dump(void) externC void cyg_assert_fail( const char *psz_func, const char *psz_file, - cyg_uint32 linenum, const char *psz_msg ) + cyg_uint32 linenum, const char *psz_msg ) __THROW { for(;;); };
--- a/packages/infra/current/src/simple.cxx +++ b/packages/infra/current/src/simple.cxx @@ -490,7 +490,7 @@ cyg_trace_dump(void) externC void cyg_assert_fail( const char *psz_func, const char *psz_file, - cyg_uint32 linenum, const char *psz_msg ) + cyg_uint32 linenum, const char *psz_msg ) __THROW { cyg_uint32 old_ints;
--- a/packages/io/eth/current/ChangeLog +++ b/packages/io/eth/current/ChangeLog @@ -1,3 +1,28 @@ +2001-09-05 Gary Thomas <gthomas@redhat.com> + + * src/stand_alone/eth_drv.c (eth_drv_init): Don't initialize + structures if ESA is zero. This is used by low level drivers + to indicate that a device is present, but can't currently be + used. The eCos driver handles this case as well. + +2001-08-31 Hugo Tyson <hmt@redhat.com> +2001-08-31 Andrew Lunn <Andrew.Lunn@ascom.ch> + + * src/net/eth_drv.c (eth_drv_tx_done): Guard against a NULL key + return - which can be caused by race conditions in the driver, + this is the neatest fixup. It's good defensive programming + anyway and ASCOM's tests indicate a benefit for CASE 106059. + +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/stand_alone/eth_drv.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + + * cdl/eth_drivers.cdl: Only enable warning/debug modes if RedBoot + is present as the debug environment (since there are implicit + dependencies on RedBoot functions). + 2001-08-20 Jonathan Larmour <jlarmour@redhat.com> * src/net/eth_drv.c (eth_drv_send): Move endif location to fix build @@ -356,7 +381,7 @@ 2000-02-08 John Dallaway <jld@cygnus.c // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/io/eth/current/cdl/eth_drivers.cdl +++ b/packages/io/eth/current/cdl/eth_drivers.cdl @@ -23,7 +23,7 @@ # # The Initial Developer of the Original Code is Red Hat. # Portions created by Red Hat are -# Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +# Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. # All Rights Reserved. # ------------------------------------------- # @@ -145,6 +145,7 @@ cdl_package CYGPKG_IO_ETH_DRIVERS { cdl_option CYGSEM_IO_ETH_DRIVERS_WARN { display "Show driver warnings" + active_if CYGPKG_REDBOOT flavor bool default_value 0 description " @@ -155,6 +156,7 @@ cdl_package CYGPKG_IO_ETH_DRIVERS { cdl_option CYGSEM_IO_ETH_DRIVERS_DEBUG { display "Print driver debug information" + active_if CYGPKG_REDBOOT flavor booldata default_value { 0 != CYGPKG_REDBOOT ? 1 : 0} description "
--- a/packages/io/eth/current/src/net/eth_drv.c +++ b/packages/io/eth/current/src/net/eth_drv.c @@ -626,8 +626,13 @@ eth_drv_tx_done(struct eth_drv_sc *sc, C // Check for errors here (via 'status') ifp->if_opackets++; // Done with packet - mbuf_key = m0; - m_freem(m0); + + // Guard against a NULL return - can be caused by race conditions in + // the driver, this is the neatest fixup: + if (m0) { + mbuf_key = m0; + m_freem(m0); + } // Start another if possible eth_drv_send(ifp); CYGARC_HAL_RESTORE_GP();
--- a/packages/io/eth/current/src/stand_alone/eth_drv.c +++ b/packages/io/eth/current/src/stand_alone/eth_drv.c @@ -23,7 +23,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // @@ -114,10 +114,10 @@ static struct eth_msg eth_msgs[NUM_ETH_M // Prototypes for functions used in this module static void eth_drv_start(struct eth_drv_sc *sc); +// These functions are defined in RedBoot and control access to +// the "default" console. extern int start_console(void); extern void end_console(int); -extern void printf(char *fmt, ...); -extern void dump_buf(CYG_ADDRWORD, int); // Simple queue management functions @@ -170,11 +170,14 @@ eth_drv_buffers_init(void) static void eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr) { - // Set up hardware address - memcpy(&sc->sc_arpcom.esa, enaddr, ETHER_ADDR_LEN); - memcpy(__local_enet_addr, enaddr, ETHER_ADDR_LEN); - __local_enet_sc = sc; - eth_drv_start(sc); + // enaddr == 0 -> hardware init was incomplete (no ESA) + if (enaddr != 0) { + // Set up hardware address + memcpy(&sc->sc_arpcom.esa, enaddr, ETHER_ADDR_LEN); + memcpy(__local_enet_addr, enaddr, ETHER_ADDR_LEN); + __local_enet_sc = sc; + eth_drv_start(sc); + } } #if 0 // Not currently used. Left in case it's needed in the future @@ -246,9 +249,9 @@ eth_drv_write(char *eth_hdr, char *buf, if (net_debug) { int old_console; old_console = start_console(); - printf("Ethernet send:\n"); - dump_buf((CYG_ADDRWORD)eth_hdr, 14); - dump_buf((CYG_ADDRWORD)buf, len); + diag_printf("Ethernet send:\n"); + diag_dump_buf((CYG_ADDRWORD)eth_hdr, 14); + diag_dump_buf((CYG_ADDRWORD)buf, len); end_console(old_console); } #endif @@ -297,7 +300,7 @@ eth_drv_tx_done(struct eth_drv_sc *sc, C if (net_debug) { int old_console; old_console = start_console(); - printf("tx_done for other key: %x\n", key); + diag_printf("tx_done for other key: %x\n", key); end_console(old_console); } #endif @@ -405,7 +408,7 @@ eth_drv_recv(struct eth_drv_sc *sc, int #ifdef CYGSEM_IO_ETH_DRIVERS_WARN int old_console; old_console = start_console(); - printf("%s: packet of %d bytes dropped\n", __FUNCTION__, total_len); + diag_printf("%s: packet of %d bytes dropped\n", __FUNCTION__, total_len); end_console(old_console); #endif buf = (char *)0; // Drivers know this means "the bit bucket" @@ -419,9 +422,9 @@ eth_drv_recv(struct eth_drv_sc *sc, int if (net_debug) { int old_console; old_console = start_console(); - printf("Ethernet recv:\n"); - dump_buf((CYG_ADDRWORD)buf, 14); - dump_buf((CYG_ADDRWORD)buf+14, total_len-14); + diag_printf("Ethernet recv:\n"); + diag_dump_buf((CYG_ADDRWORD)buf, 14); + diag_dump_buf((CYG_ADDRWORD)buf+14, total_len-14); end_console(old_console); } #endif @@ -448,7 +451,7 @@ eth_drv_recv(struct eth_drv_sc *sc, int eth_drv_msg_put(ð_msg_full, msg); #ifdef CYGSEM_IO_ETH_DRIVERS_WARN } else { - dump_buf(sg_list[0].buf, sg_list[0].len); + diag_dump_buf(sg_list[0].buf, sg_list[0].len); #endif } CYGARC_HAL_RESTORE_GP(); @@ -469,8 +472,8 @@ void eth_drv_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) { - printf( "eth_drv_dsr should not be called: vector %d, data %x\n", - vector, data ); + diag_printf("eth_drv_dsr should not be called: vector %d, data %x\n", + vector, data ); }
--- a/packages/io/pci/current/ChangeLog +++ b/packages/io/pci/current/ChangeLog @@ -1,3 +1,9 @@ +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/pci.c: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. + 2001-02-28 Hugo Tyson <hmt@redhat.com> * tests/pci1.c (pci_scan): Added a new function to re-scan the @@ -262,7 +268,7 @@ 1999-08-12 Jesper Skov <jskov@cygnus.c // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/io/pci/current/src/pci.c +++ b/packages/io/pci/current/src/pci.c @@ -23,7 +23,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // @@ -416,7 +416,7 @@ cyg_pci_find_next( cyg_pci_device_id cur cyg_uint8 fn = CYG_PCI_DEV_GET_FN(devfn); #ifdef CYGPKG_IO_PCI_DEBUG - printf("cyg_pci_find_next: start[%x] ...\n",(unsigned)cur_devid); + diag_printf("cyg_pci_find_next: start[%x] ...\n",(unsigned)cur_devid); #endif // If this is the initializer, start with 0/0/0 @@ -459,7 +459,7 @@ cyg_pci_find_next( cyg_pci_device_id cur CYG_PCI_CFG_VENDOR, &vendor); if (CYG_PCI_VENDOR_UNDEFINED != vendor) { #ifdef CYGPKG_IO_PCI_DEBUG - printf(" Bus: %d, Dev: %d, Fn: %d, Vendor: %x\n", bus, dev, fn, vendor); + diag_printf(" Bus: %d, Dev: %d, Fn: %d, Vendor: %x\n", bus, dev, fn, vendor); #endif *next_devid = CYG_PCI_DEV_MAKE_ID(bus, devfn); return true; @@ -469,7 +469,7 @@ cyg_pci_find_next( cyg_pci_device_id cur } #ifdef CYGPKG_IO_PCI_DEBUG - printf("nothing.\n"); + diag_printf("nothing.\n"); #endif return false; @@ -486,7 +486,7 @@ cyg_pci_find_device( cyg_uint16 vendor, cyg_pci_device_id new_devid = *devid; #ifdef CYGPKG_IO_PCI_DEBUG - printf("cyg_pci_find_device - vendor: %x, device: %x\n", vendor, device); + diag_printf("cyg_pci_find_device - vendor: %x, device: %x\n", vendor, device); #endif // Scan entire bus, check for matches on valid devices. while (cyg_pci_find_next(new_devid, &new_devid)) { @@ -500,7 +500,7 @@ cyg_pci_find_device( cyg_uint16 vendor, cyg_pcihw_read_config_uint16(bus, devfn, CYG_PCI_CFG_DEVICE, &d); #ifdef CYGPKG_IO_PCI_DEBUG - printf("... PCI vendor = %x, device = %x\n", v, d); + diag_printf("... PCI vendor = %x, device = %x\n", v, d); #endif if (v != vendor) continue; @@ -542,7 +542,7 @@ cyg_pci_find_matching( cyg_pci_match_fun cyg_pci_device_id new_devid = *devid; #ifdef CYGPKG_IO_PCI_DEBUG - printf("cyg_pci_find_matching - func is at %x\n", (unsigned int)matchp); + diag_printf("cyg_pci_find_matching - func is at %x\n", (unsigned int)matchp); #endif // Scan entire bus, check for matches on valid devices. while (cyg_pci_find_next(new_devid, &new_devid)) { @@ -560,7 +560,7 @@ cyg_pci_find_matching( cyg_pci_match_fun CYG_PCI_CFG_CLASS_REV, &c); c >>= 8; #ifdef CYGPKG_IO_PCI_DEBUG - printf("... PCI vendor = %x, device = %x, class %x\n", v, d, c); + diag_printf("... PCI vendor = %x, device = %x, class %x\n", v, d, c); #endif // Check that device matches as the caller desires: if ( (*matchp)(v, d, c, match_callback_data) ) { @@ -819,7 +819,7 @@ cyg_pci_configure_bus( cyg_uint8 bus, devid = CYG_PCI_DEV_MAKE_ID(bus, 0) | CYG_PCI_NULL_DEVFN; #ifdef CYGPKG_IO_PCI_DEBUG - printf("Configuring bus %d.\n", bus); + diag_printf("Configuring bus %d.\n", bus); #endif while (cyg_pci_find_next(devid, &devid) && bus == CYG_PCI_DEV_GET_BUS(devid)) { @@ -830,12 +830,12 @@ cyg_pci_configure_bus( cyg_uint8 bus, cyg_pci_get_device_info(devid, &dev_info); #ifdef CYGPKG_IO_PCI_DEBUG - printf("\n"); - printf("Configuring PCI Bus : %d\n", bus); - printf(" PCI Device: %d\n", CYG_PCI_DEV_GET_DEV(devfn)); - printf(" PCI Func : %d\n", CYG_PCI_DEV_GET_FN(devfn)); - printf(" Vendor Id : 0x%08X\n", dev_info.vendor); - printf(" Device Id : 0x%08X\n", dev_info.device); + diag_printf("\n"); + diag_printf("Configuring PCI Bus : %d\n", bus); + diag_printf(" PCI Device: %d\n", CYG_PCI_DEV_GET_DEV(devfn)); + diag_printf(" PCI Func : %d\n", CYG_PCI_DEV_GET_FN(devfn)); + diag_printf(" Vendor Id : 0x%08X\n", dev_info.vendor); + diag_printf(" Device Id : 0x%08X\n", dev_info.device); #endif header_type = dev_info.header_type & CYG_PCI_CFG_HEADER_TYPE_MASK; @@ -1012,7 +1012,7 @@ cyg_pci_configure_bus( cyg_uint8 bus, } } #ifdef CYGPKG_IO_PCI_DEBUG - printf("Finished configuring bus %d.\n", bus); + diag_printf("Finished configuring bus %d.\n", bus); #endif return true;
--- a/packages/kernel/current/ChangeLog +++ b/packages/kernel/current/ChangeLog @@ -1,8 +1,134 @@ +2001-09-05 Jesper Skov <jskov@redhat.com> + + * include/mqueue.inl (Cyg_Mqueue): Initialize busy flag of last + entry in the list. + +2001-09-04 Jonathan Larmour <jlarmour@redhat.com> + + * cdl/instrument.cdl (CYGDBG_KERNEL_INSTRUMENT_BUILD_HOST_DUMP): + Remove redundant requires, and adjust make rule to be more portable + across hosts. + (CYGDBG_KERNEL_INSTRUMENT_MSGS_BUILD_HEADERFILE): + Invoke script with sh directly rather than rely on executable attribute. + + * host/instr/readme.txt: Update build of host dump as per the changed + CDL. + + * cdl/kernel.cdl: Don't build nullinst.cxx any more. + Build meminst.cxx only in CYGPKG_KERNEL_INSTRUMENT. + * src/instrmnt/nullinst.cxx: Delete. It causes confusion in the + library as it declares cyg_instrument like meminst.cxx does. + +2001-08-31 Nick Garnett <nickg@redhat.com> + + * src/intr/intr.cxx: Clean up typo in DSR table + case. dsr_table_tail and dsr_table_head were not being subscripted + in a couple of places. + +2001-08-23 Hugo Tyson <hmt@redhat.com> +2001-08-20 Andrew Lunn <andrew.lunn@ascom.ch> + + * include/instrument_desc.h: New file. This contains the table of + events used to print the nice information. It should be + regenerated when the instrumentation numbers change. + + * src/instrmnt/meminst.cxx (cyg_instrument_msg): + returns an ASCII string describing the type of event the + instrumentation code logged. + + * include/instrmnt.h: Added function prototype. + + * cdl/instrument.cdl: Configury for enabling the new function, and + optionally rebuilding its header file and building a host tool. + + * host/instr/dump_instr.c: New file. A host program to print the + instrumentation information in a human readable form. + + * host/instr/instrument.sh: New file. Script to generate table of + events with textual representation. + + * host/instr/readme.txt: New file. Helpful information. + +2001-08-23 Nick Garnett <nickg@redhat.com> + + * include/kapidata.h (CYG_THREADTIMER_MEMBERS): + Substituted an expicit cyg_alarm object for CYG_ALARM_MEMBERS in + this definition. In some architectures (MIPS in particular) the + structures need to be padded to a multiple of 64 bits. This was + not happening with the macro substituted versions. + This is just a temporary fix, I'll leave it to Jifl to sort out a + real patch when he returns. + +2001-08-23 Hugo Tyson <hmt@redhat.com> + + * src/common/thread.cxx: Properly qualify Cyg_Thread::destructors + array so that it builds when destructors are not used. + +2001-08-23 Nick Garnett <nickg@redhat.com> + + * src/sched/mlqueue.cxx: Added code to + Cyg_SchedThread_Implementation::to_queue_head() to handle a NULL + thread queue pointer. This compensates for a minor change in + behaviour of the scheduler. + +2001-08-22 Jonathan Larmour <jlarmour@redhat.com> + + * cdl/thread.cdl: Add kernel thread destructor options. + * include/kapidata.h: Add thread destructor entries to cyg_thread + * include/thread.hxx (Cyg_Thread): Give per-thread data indexes + their own type, cyg_data_index. + Include new thread destructor data members, and new add_destructor + and rem_destructor member functions. + * include/thread.inl: Use a cyg_data_index for per-thread data handle. + (add_destructor): New Cyg_Thread member function. + (rem_destructor): Ditto. + * src/common/kapi.cxx: Use cyg_data_index type for per-thread data + functions. + * src/common/thread.cxx (Cyg_Thread): initialise per-thread + destructors if needed. + Define static destructors if needed. + (exit): Call destructors. + (new_data_index): Use cyg_data_index type. + (free_data_index): Ditto. + +2001-08-22 Hugo Tyson <hmt@redhat.com> + + * src/sync/mutex.cxx (Cyg_Mutex): Add initialization of the + priority ceiling value in the non-dynamic protocol case. + +2001-08-22 Nick Garnett <nickg@redhat.com> + + * tests/intr0.c: + * tests/kintr0.c: + Swapped order of interrupt enable/disable calls to keep kernel + happy when assertions are enabled. Otherwise the enable call + complains that interrupts have not been disabled. + + * src/sched/mlqueue.cxx: + Simplified algorithm in set_need_reschedule(). + + * include/smp.hxx: + * include/kapidata.h: Change spinlock to be a cyg_uint32, rather + than a cyg_atomic. + + * src/intr/intr.cxx: + * include/intr.hxx: + Now arrange for DSRs to be called on the same CPU as the ISR. This + is necessary if the DSR needs to access per-CPU hardware (such as + interrupt controllers). This is achieved by keeping a separate DSR + list/table for each CPU. + + * tests/smp.cxx: Some modifications to make this test work in a + real SMP environment. + + * tests/timeslice.c: + * cdl/kernel.cdl: Added timeslice test. + 2001-08-21 Hugo Tyson <hmt@redhat.com> * src/sync/mutex.cxx (lock): Bugfix: a ceiling priority mutex wasn't elevated until after it had acquired the mutex. This meant - is slept with a low priority, and so did not run when awakened by + it slept with a low priority, and so did not run when awakened by the release of the mutex. The fix is to elevate the potential claimant before it sleeps in contention.
--- a/packages/kernel/current/cdl/instrument.cdl +++ b/packages/kernel/current/cdl/instrument.cdl @@ -248,3 +248,56 @@ cdl_option CYGDBG_KERNEL_INSTRUMENT_USER whether or not application-level instrumentation gets compiled in." } + +cdl_component CYGDBG_KERNEL_INSTRUMENT_MSGS { + display "Print user friendly instrument messages" + default_value 1 + description " + Include code which will convert the instrument type field + into a more human understandable string" + + cdl_option CYGDBG_KERNEL_INSTRUMENT_MSGS_BUILD_HEADERFILE { + display "Rebuild the header file" + default_value 0 + description " + + Make (using a shell script) include/cyg/kernel/instrument_desc.h in + your build tree; this is normally simply copied from the repository. + If you make a permanent change to include/instrmnt.h, such that + instrument_desc.h needs updating, it's up to you to first delete the + master file + ECOS_REPOSITORY/kernel/VERSION/include/instrument_desc.h + in your source repository, make the new version by enabling this + option then copy the new file + back from your build place to its source in + ECOS_REPOSITORY/kernel/VERSION/include/instrument_desc.h + and/or commit this to any version control system that you use." + + make -priority 50 { + <PREFIX>/include/cyg/kernel/instrument_desc.h: <PACKAGE>/include/instrmnt.h <PACKAGE>/cdl/instrument.cdl + sh $(REPOSITORY)/$(PACKAGE)/host/instr/instrument.sh $< > $@ + } + } + + cdl_component CYGDBG_KERNEL_INSTRUMENT_BUILD_HOST_DUMP { + display "Build the host tool to print out a dump" + default_value 0 + description " + Generate a host program which can dump the instrumentation + data in a human readable format. You have to somehow get the + instrumentation buffer into a file on the host. 'Exercise for + the reader' as university lecturers tend to say." + + make -priority 51 { + <PREFIX>/bin/dump_instr: <PREFIX>/include/cyg/kernel/instrument_desc.h <PACKAGE>/cdl/instrument.cdl + @mkdir -p $(dir $@) + @mkdir -p tempinc + @cp -r $(PREFIX)/include/cyg tempinc + @cp -r $(PREFIX)/include/pkgconf tempinc + cc -I./tempinc $(REPOSITORY)/$(PACKAGE)/host/instr/dump_instr.c -o $(PREFIX)/bin/dump_instr + @rm -rf tempinc + } + } +} + +# EOF instrument.cdl
--- a/packages/kernel/current/cdl/kernel.cdl +++ b/packages/kernel/current/cdl/kernel.cdl @@ -55,7 +55,6 @@ cdl_package CYGPKG_KERNEL { # will actually be used. compile common/clock.cxx common/timer.cxx common/kapi.cxx \ common/thread.cxx common/except.cxx \ - instrmnt/meminst.cxx instrmnt/nullinst.cxx \ intr/intr.cxx \ sched/bitmap.cxx sched/lottery.cxx sched/mlqueue.cxx \ sched/sched.cxx \ @@ -208,6 +207,7 @@ cdl_package CYGPKG_KERNEL { events occur, and these will be stored in a circular buffer for later reference." + compile instrmnt/meminst.cxx script instrument.cdl } @@ -318,14 +318,14 @@ cdl_package CYGPKG_KERNEL { flavor data no_define calculated { - CYGPKG_HAL_ARM_AEB ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone" : \ - CYGPKG_HAL_ARM_EBSA285 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \ - CYGPKG_HAL_ARM_SA11X0 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \ - CYGPKG_HAL_ARM_EDB7XXX ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \ - CYGPKG_HAL_ARM_CMA230 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone" : \ - CYGPKG_HAL_ARM_E7T ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2" : \ - CYGPKG_HAL_ARM ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone" : \ - "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/smp" + CYGPKG_HAL_ARM_AEB ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/timeslice" : \ + CYGPKG_HAL_ARM_EBSA285 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/timeslice" : \ + CYGPKG_HAL_ARM_SA11X0 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/timeslice" : \ + CYGPKG_HAL_ARM_EDB7XXX ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/timeslice" : \ + CYGPKG_HAL_ARM_CMA230 ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/timeslice" : \ + CYGPKG_HAL_ARM_E7T ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/timeslice" : \ + CYGPKG_HAL_ARM ? "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/timeslice" : \ + "tests/bin_sem0 tests/bin_sem1 tests/bin_sem2 tests/clock0 tests/clock1 tests/clockcnv tests/clocktruth tests/cnt_sem0 tests/cnt_sem1 tests/except1 tests/flag0 tests/flag1 tests/intr0 tests/kclock0 tests/kclock1 tests/kexcept1 tests/kintr0 tests/kmbox1 tests/kmutex0 tests/kmutex1 tests/kmutex3 tests/kmutex4 tests/ksched1 tests/ksem0 tests/ksem1 tests/kflag0 tests/kflag1 tests/klock tests/kthread0 tests/kthread1 tests/mbox1 tests/mqueue1 tests/mutex0 tests/mutex1 tests/mutex2 tests/mutex3 tests/sched1 tests/sync2 tests/sync3 tests/thread0 tests/thread1 tests/thread2 tests/release tests/kill tests/thread_gdb tests/tm_basic tests/dhrystone tests/stress_threads tests/kcache1 tests/kcache2 tests/smp tests/timeslice" } description " This option specifies the set of tests for the eCos kernel."
--- a/packages/kernel/current/cdl/thread.cdl +++ b/packages/kernel/current/cdl/thread.cdl @@ -220,6 +220,38 @@ cdl_component CYGVAR_KERNEL_THREADS_DATA } } +cdl_component CYGPKG_KERNEL_THREADS_DESTRUCTORS { + display "Thread destructors" + default_value 0 + description " + This option enables support for registered destructor functions to + be called on thread exit." + + + cdl_option CYGNUM_KERNEL_THREADS_DESTRUCTORS { + display "Number of possible destructors" + flavor data + legal_values 1 to 65535 + default_value 8 + description " + This option gives the number of possible destructors allowed. + Increasing this will increase the size of every + thread control structure if per-thread destructors are + enabled." + } + + cdl_option CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD { + display "Per-thread destructors" + default_value 1 + description " + Enabling this option makes the thread destructors a per-thread + property, with each thread having its own list of destructors. + Disabling this option makes the thread destructor list + global so all threads have the same destructors." + } + +} + cdl_option CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE { display "Stack size for the idle thread" flavor data
new file mode 100644 --- /dev/null +++ b/packages/kernel/current/host/instr/dump_instr.c @@ -0,0 +1,105 @@ + +#include <pkgconf/kernel.h> +#include <cyg/kernel/ktypes.h> // base kernel types +#include <cyg/kernel/instrmnt.h> + +#include <stdio.h> +#include <stdlib.h> + +// ------------------------------------------------------------------------- +// Instrumentation record. + +struct Instrument_Record +{ + CYG_WORD16 type; // record type + CYG_WORD16 thread; // current thread id + CYG_WORD timestamp; // 32 bit timestamp + CYG_WORD arg1; // first arg + CYG_WORD arg2; // second arg +}; + +// ------------------------------------------------------------------------- + +#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS +#include <cyg/kernel/instrument_desc.h> +#define NELEM(x) (sizeof(x)/sizeof*(x)) +externC char * cyg_instrument_msg(CYG_WORD16 type) { + + struct instrument_desc_s *record; + struct instrument_desc_s *end_record; + CYG_WORD cl, event; + + record = instrument_desc; + end_record = &instrument_desc[NELEM(instrument_desc)]; + cl = type & 0xff00; + event = type & 0x00ff; + + while ((record != end_record) && (record->num != cl)) { + record++; + } + + if (record->num == cl) { + record++; + while ((record != end_record) && (record->num != event) && + (record->num < 0xff)) { + record++; + } + + if (record->num == event) { + return (record->msg); + } + } + return("Unknown event"); +} +#endif // CYGDBG_KERNEL_INSTRUMENT_MSGS + +void usage(char *myname) +{ + fprintf(stderr,"Usage: %s <filename>\n",myname); + fprintf(stderr,"where filename is that of the instrumentation data"); +} + +int main(int argc, char * argv[]) +{ + + FILE * file; + char * filename; + struct Instrument_Record record; + int cnt=0; + + if (argc != 1) { + usage(argv[0]); + exit(1); + } + + filename = argv[1]; + + file = fopen(filename, "r"); + if (!file) { + fprintf(stderr,"Error opening file %s: ",filename); + perror(""); + exit(1); + } + + while (!feof(file)) { + fread(&record,sizeof(record),1,file); + if (record.type == 0) { + break; + } + +#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS + printf("%4d Record type (0x%04x): %-20s thread %2d, ", + cnt++,record.type,cyg_instrument_msg(record.type), + record.thread); +#else + printf("%4d Record type 0x%04x, thread %2d, ", + cnt++,record.type, record.thread); +#endif + printf("time %5d, arg1 0x%08x, arg2 0x%08x\n", + record.timestamp, record.arg1, + record.arg2); + } + + fclose(file); + return (0); +}
new file mode 100644 --- /dev/null +++ b/packages/kernel/current/host/instr/instrument.sh @@ -0,0 +1,18 @@ +#!/bin/sh +echo "/* This is an automatically generated file. Do not edit. */" +echo "/* Repository name: PACKAGES/kernel/VERSION/include/instrument_desc.h */" +echo "/* Install tree : INSTALL/include/cyg/kernel/instrument_desc.h */" +echo +echo "struct instrument_desc_s { " +echo " char * msg; " +echo " CYG_WORD num; " +echo "}; " +echo +echo struct instrument_desc_s instrument_desc[] = { + +grep -e \#define.CYG_INSTRUMENT_EVENT -e \#define.CYG_INSTRUMENT_CLASS $1 | grep -v MAX | cut -d " " -f 2- | cut -d "_" -f 4- | sort | awk '{ print("{\""$1"\", " $2 "},") }' + +echo }\; +echo +echo "/* EOF instrument_desc.h */" +
new file mode 100644 --- /dev/null +++ b/packages/kernel/current/host/instr/readme.txt @@ -0,0 +1,80 @@ + +README for User Friendly Instrumentation Messages +================================================= + +The CDL option CYGDBG_KERNEL_INSTRUMENT_MSGS controls whether the +system is capable of displaying user friendly instrumentation +messages. To do this it needs to know what event numbers mean +what events - as a text string to print for you. + +It gets the information from a table created by the header file +instrument_desc.h in the kernel. If the instrumentation numbers +change, you must rebuild that header to match. + +A further CDL option is provided to help you with that. The +procedure is as follows: + +1) Remove kernel/VERSION/include/instrument_desc.h from your + repository. Is is probably a good idea to move it away rather + than deleting it in case the next stages fail. + +2) Make a build configuration, enabling options + CYGDBG_KERNEL_INSTRUMENT, CYGDBG_KERNEL_INSTRUMENT_MSGS and + CYGDBG_KERNEL_INSTRUMENT_MSGS_BUILD_HEADERFILE in the kernel. + Viewed in the GUI configtool, "Kernel instrumentation", "Print + user friendly instrument messages" and "Rebuild the header + file" respectively. + +3) Make eCos within this build configuration. It should create + install/include/cyg/kernel/instrument_desc.h + +4) Copy that new file back to your repository, to + kernel/VERSION/include/instrument_desc.h replacing the file + you moved aside in step 1. + +5) Commit the new file to your version control system or whatever + you use. + +If you wish to rebuild the file "by hand" the command to use, in +a suitable shell, is this: + + $ECOS_REPOSITORY/kernel/$ECOS_VERSION/host/instr/instrument.sh + $ECOS_REPOSITORY/kernel/$ECOS_VERSION/include/instrmnt.h + > $ECOS_BUILD_PREFIX/include/cyg/kernel/instrument_desc.h + +(all on one line of course) or to rebuild it directly into the +kernel source repository: + + $ECOS_REPOSITORY/kernel/$ECOS_VERSION/host/instr/instrument.sh + $ECOS_REPOSITORY/kernel/$ECOS_VERSION/include/instrmnt.h + > $ECOS_REPOSITORY/kernel/$ECOS_VERSION/include/instrument_desc.h + +It's up to you to sort out file permissions for this to work, and +to set environment variables as required or edit these lines as +you type them. + + +There is also a host-based program which can print a buffer +nicely for you - if you can get the data into your host. +Enabling CDL option CYGDBG_KERNEL_INSTRUMENT_BUILD_HOST_DUMP or +"Build the host tool to print out a dump" will build it for you +in install/bin. To build it instead "by hand", use + + mkdir -p tempinc + cp -r $(ECOS_BUILD_PREFIX)/include/cyg tempinc + cp -r $(ECOS_BUILD_PREFIX)/include/pkgconf tempinc + cc -I./tempinc + $(ECOS_REPOSITORY)/kernel/${ECOS_VERSION}/host/instr/dump_instr.c + -o $(PREFIX)/bin/dump_instr + +again with environment variables as required, or type in whatever +is appropriate. You still have to somehow get the +instrumentation buffer into a file on the host. 'Exercise for the +reader' as university lecturers tend to say. + +One possibility is to set up a tftp *server* in the target which +will serve the instrumentation buffer. This hint is as far as +support for this goes. + + +
--- a/packages/kernel/current/include/instrmnt.h +++ b/packages/kernel/current/include/instrmnt.h @@ -26,7 +26,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // @@ -35,7 +35,7 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): nickg -// Contributors: nickg +// Contributors: nickg, andrew.lunn@ascom.ch // Date: 2000-05-04 // Purpose: Define kernel instrumentation // Description: A set of definitions and macros used to implement an @@ -73,6 +73,9 @@ externC void cyg_instrument_enable( cyg_ externC void cyg_instrument_disable( cyg_uint32 cl, cyg_uint32 event ); +#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS +externC char * cyg_instrument_msg(CYG_WORD16 type); +#endif #endif // ------------------------------------------------------------------------- @@ -446,4 +449,4 @@ externC void cyg_instrument_disable( cyg // ------------------------------------------------------------------------- #endif // ifndef CYGONCE_KERNEL_INSTRMNT_HXX -// EOF instrmnt.hxx +// EOF instrmnt.h
new file mode 100644 --- /dev/null +++ b/packages/kernel/current/include/instrument_desc.h @@ -0,0 +1,138 @@ +/* This is an automatically generated file. Do not edit. */ +/* Repository name: PACKAGES/kernel/VERSION/include/instrument_desc.h */ +/* Install tree : INSTALL/include/cyg/kernel/instrument_desc.h */ + +struct instrument_desc_s { + char * msg; + CYG_WORD num; +}; + +struct instrument_desc_s instrument_desc[] = { +{"ALARM", 0x0900}, +{"ALARM_ADD", 1}, +{"ALARM_CALL", 3}, +{"ALARM_INIT", 4}, +{"ALARM_INTERVAL", 6}, +{"ALARM_REM", 2}, +{"ALARM_TRIGGER", 5}, +{"BINSEM", 0x0600}, +{"BINSEM_CLAIM", 1}, +{"BINSEM_POST", 5}, +{"BINSEM_TRY", 4}, +{"BINSEM_WAIT", 2}, +{"BINSEM_WAKE", 6}, +{"BINSEM_WOKE", 3}, +{"CLOCK", 0x0800}, +{"CLOCK_ISR", 3}, +{"CLOCK_TICK_END", 2}, +{"CLOCK_TICK_START", 1}, +{"CNTSEM", 0x0700}, +{"CNTSEM_CLAIM", 1}, +{"CNTSEM_POST", 5}, +{"CNTSEM_TIMEOUT", 7}, +{"CNTSEM_TRY", 4}, +{"CNTSEM_WAIT", 2}, +{"CNTSEM_WAKE", 6}, +{"CNTSEM_WOKE", 3}, +{"CONDVAR", 0x0500}, +{"CONDVAR_BROADCAST", 5}, +{"CONDVAR_SIGNAL", 3}, +{"CONDVAR_TIMED_WAIT", 6}, +{"CONDVAR_WAIT", 1}, +{"CONDVAR_WAKE", 4}, +{"CONDVAR_WOKE", 2}, +{"INTR", 0x0300}, +{"INTR_ACK", 14}, +{"INTR_ATTACH", 6}, +{"INTR_CALL_DSR", 5}, +{"INTR_CHAIN_ISR", 15}, +{"INTR_CONFIGURE", 13}, +{"INTR_DETACH", 7}, +{"INTR_DISABLE", 9}, +{"INTR_ENABLE", 10}, +{"INTR_END", 2}, +{"INTR_GET_CPU", 17}, +{"INTR_MASK", 11}, +{"INTR_POST_DSR", 4}, +{"INTR_RAISE", 1}, +{"INTR_RESTORE", 3}, +{"INTR_SET_CPU", 16}, +{"INTR_SET_VSR", 8}, +{"INTR_UNMASK", 12}, +{"MBOXT", 0x0a00}, +{"MBOXT_GET", 2}, +{"MBOXT_GOT", 3}, +{"MBOXT_PUT", 7}, +{"MBOXT_TIMEOUT", 4}, +{"MBOXT_TRY", 6}, +{"MBOXT_WAIT", 1}, +{"MBOXT_WAKE", 5}, +{"MLQ", 0x0c00}, +{"MLQ_ADD", 3}, +{"MLQ_DEQUEUE", 8}, +{"MLQ_ENQUEUE", 7}, +{"MLQ_REM", 4}, +{"MLQ_REMOVE", 9}, +{"MLQ_RESCHEDULE", 2}, +{"MLQ_SCHEDULE", 1}, +{"MLQ_TIMESLICE", 5}, +{"MLQ_YIELD", 6}, +{"MUTEX", 0x0400}, +{"MUTEX_LOCK", 1}, +{"MUTEX_LOCKED", 3}, +{"MUTEX_RELEASE", 7}, +{"MUTEX_RELEASED", 8}, +{"MUTEX_TRY", 4}, +{"MUTEX_UNLOCK", 5}, +{"MUTEX_WAIT", 2}, +{"MUTEX_WAKE", 6}, +{"SCHED", 0x0100}, +{"SCHED_LOCK", 1}, +{"SCHED_RESCHEDULE", 3}, +{"SCHED_TIMESLICE", 4}, +{"SCHED_UNLOCK", 2}, +{"SMP", 0x0b00}, +{"SMP_CPU_START", 4}, +{"SMP_LOCK_GOT", 6}, +{"SMP_LOCK_INC", 1}, +{"SMP_LOCK_SET", 3}, +{"SMP_LOCK_WAIT", 5}, +{"SMP_LOCK_ZERO", 2}, +{"SMP_RESCHED_RECV", 9}, +{"SMP_RESCHED_SEND", 8}, +{"THREAD", 0x0200}, +{"THREAD_ALARM", 8}, +{"THREAD_ATTACH_STACK", 11}, +{"THREAD_CHECK_STACK", 10}, +{"THREAD_CREATE", 12}, +{"THREAD_DELAY", 7}, +{"THREAD_ENTER", 9}, +{"THREAD_PRIORITY", 6}, +{"THREAD_RESUME", 5}, +{"THREAD_SLEEP", 2}, +{"THREAD_SUSPEND", 4}, +{"THREAD_SWITCH", 1}, +{"THREAD_WAKE", 3}, +{"USER", 0x0f00}, +{"USER_10", 10}, +{"USER_1", 1}, +{"USER_11", 11}, +{"USER_12", 12}, +{"USER_13", 13}, +{"USER_14", 14}, +{"USER_15", 15}, +{"USER_16", 16}, +{"USER_17", 17}, +{"USER_18", 18}, +{"USER_19", 19}, +{"USER_2", 2}, +{"USER_3", 3}, +{"USER_4", 4}, +{"USER_5", 5}, +{"USER_6", 6}, +{"USER_7", 7}, +{"USER_8", 8}, +{"USER_9", 9}, +}; + +/* EOF instrument_desc.h */
--- a/packages/kernel/current/include/intr.hxx +++ b/packages/kernel/current/include/intr.hxx @@ -167,12 +167,15 @@ class Cyg_Interrupt #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE - static Cyg_Interrupt *dsr_table[CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE] - CYGBLD_ANNOTATE_VARIABLE_INTR; + static Cyg_Interrupt *dsr_table[CYGNUM_KERNEL_CPU_MAX] + [CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE] + CYGBLD_ANNOTATE_VARIABLE_INTR; - static cyg_ucount32 dsr_table_head CYGBLD_ANNOTATE_VARIABLE_INTR; + static cyg_ucount32 dsr_table_head[CYGNUM_KERNEL_CPU_MAX] + CYGBLD_ANNOTATE_VARIABLE_INTR; - static volatile cyg_ucount32 dsr_table_tail CYGBLD_ANNOTATE_VARIABLE_INTR; + static volatile cyg_ucount32 dsr_table_tail[CYGNUM_KERNEL_CPU_MAX] + CYGBLD_ANNOTATE_VARIABLE_INTR; #endif #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST @@ -184,7 +187,8 @@ class Cyg_Interrupt Cyg_Interrupt* volatile next_dsr CYGBLD_ANNOTATE_VARIABLE_INTR; // static list of pending DSRs - static Cyg_Interrupt* volatile dsr_list CYGBLD_ANNOTATE_VARIABLE_INTR; + static Cyg_Interrupt* volatile dsr_list[CYGNUM_KERNEL_CPU_MAX] + CYGBLD_ANNOTATE_VARIABLE_INTR; #endif @@ -335,14 +339,15 @@ public: inline cyg_bool Cyg_Interrupt::DSRs_pending() { + HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS(); #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE - return dsr_table_head != dsr_table_tail; + return dsr_table_head[cpu] != dsr_table_tail[cpu]; #endif #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST - return dsr_list != NULL; + return dsr_list[cpu] != NULL; #endif };
--- a/packages/kernel/current/include/kapidata.h +++ b/packages/kernel/current/include/kapidata.h @@ -327,7 +327,7 @@ typedef struct } cyg_schedthread; #define CYG_THREADTIMER_MEMBERS \ - CYG_ALARM_MEMBERS \ + cyg_alarm alarm; \ cyg_thread *thread; /*---------------------------------------------------------------------------*/ @@ -376,6 +376,22 @@ typedef int cyg_reason_t; /* cyg_reason # define CYG_THREAD_LIST_NEXT_MEMBER #endif + + +#ifdef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD +typedef void (*cyg_thread_destructor_fn)(CYG_ADDRWORD); + +struct Cyg_Destructor_Entry { + cyg_thread_destructor_fn fn; + CYG_ADDRWORD data; +}; +# define CYG_THREAD_DESTRUCTORS_MEMBER \ + struct Cyg_Destructor_Entry destructors[ CYGNUM_KERNEL_THREADS_DESTRUCTORS ]; +#else +# define CYG_THREAD_DESTRUCTORS_MEMBER +#endif + + #define CYG_THREAD_MEMBERS \ CYG_HARDWARETHREAD_MEMBERS \ CYG_SCHEDTHREAD_MEMBERS \ @@ -393,6 +409,7 @@ typedef int cyg_reason_t; /* cyg_reason cyg_reason_t wake_reason; \ \ CYG_THREAD_THREAD_DATA_MEMBER \ + CYG_THREAD_DESTRUCTORS_MEMBER \ CYG_THREAD_NAME_MEMBER \ CYG_THREAD_LIST_NEXT_MEMBER @@ -460,7 +477,7 @@ struct cyg_cond_t struct cyg_spinlock_t { - cyg_atomic lock; /* lock word */ + cyg_uint32 lock; /* lock word */ }; /*------------------------------------------------------------------------*/
--- a/packages/kernel/current/include/mqueue.inl +++ b/packages/kernel/current/include/mqueue.inl @@ -163,7 +163,7 @@ Cyg_Mqueue::check_this( cyg_assert_class if ( qlen != (msgs+freemsgs+busymsgs) ) goto fail; #endif - + Cyg_Scheduler::unlock(); } @@ -218,6 +218,7 @@ Cyg_Mqueue::Cyg_Mqueue( long maxmsgs, lo // set the last entry in the chain to the start to make the list circular qtmp->next = NULL; + qtmp->busy = false; callback = NULL; q = NULL; free_fn = qfree;
--- a/packages/kernel/current/include/smp.hxx +++ b/packages/kernel/current/include/smp.hxx @@ -338,7 +338,7 @@ HAL_SMP_SCHEDLOCK_DATA_TYPE Cyg_Schedule class Cyg_SpinLock { - cyg_atomic lock; + volatile cyg_uint32 lock; public:
--- a/packages/kernel/current/include/thread.hxx +++ b/packages/kernel/current/include/thread.hxx @@ -427,16 +427,39 @@ private: public: - static CYG_ADDRWORD get_data( cyg_ucount32 index ); + typedef cyg_count32 cyg_data_index; + + static CYG_ADDRWORD get_data( cyg_data_index index ); + + static CYG_ADDRWORD *get_data_ptr( cyg_data_index index ); + + void set_data( cyg_data_index index, CYG_ADDRWORD data ); - static CYG_ADDRWORD *get_data_ptr( cyg_ucount32 index ); + // returns -1 if no more indexes available + static cyg_data_index new_data_index(); + + static void free_data_index( cyg_data_index index ); + +#endif + +#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS - void set_data( cyg_ucount32 index, CYG_ADDRWORD data ); - - static cyg_ucount32 new_data_index(); - - static void free_data_index( cyg_ucount32 index ); - + // thread destructors, called on thread exit. +private: + typedef void (*destructor_fn)(CYG_ADDRWORD); + struct Cyg_Destructor_Entry { + destructor_fn fn; + CYG_ADDRWORD data; + }; +#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD + static +#endif + Cyg_Destructor_Entry destructors[ CYGNUM_KERNEL_THREADS_DESTRUCTORS ]; +public: + + // Add and remove destructors. Returns true on success, false on failure. + static cyg_bool add_destructor( destructor_fn fn, CYG_ADDRWORD data ); + static cyg_bool rem_destructor( destructor_fn fn, CYG_ADDRWORD data ); #endif #ifdef CYGVAR_KERNEL_THREADS_NAME
--- a/packages/kernel/current/include/thread.inl +++ b/packages/kernel/current/include/thread.inl @@ -453,7 +453,7 @@ inline void Cyg_Thread::clear_timer() #ifdef CYGVAR_KERNEL_THREADS_DATA -inline CYG_ADDRWORD Cyg_Thread::get_data( cyg_ucount32 index ) +inline CYG_ADDRWORD Cyg_Thread::get_data( Cyg_Thread::cyg_data_index index ) { CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX, "Per thread data index out of bounds"); @@ -463,7 +463,7 @@ inline CYG_ADDRWORD Cyg_Thread::get_data return self()->thread_data[index]; } -inline CYG_ADDRWORD *Cyg_Thread::get_data_ptr( cyg_ucount32 index ) +inline CYG_ADDRWORD *Cyg_Thread::get_data_ptr( Cyg_Thread::cyg_data_index index ) { CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX, "Per thread data index out of bounds"); @@ -473,7 +473,8 @@ inline CYG_ADDRWORD *Cyg_Thread::get_dat return &(self()->thread_data[index]); } -inline void Cyg_Thread::set_data( cyg_ucount32 index, CYG_ADDRWORD data ) +inline void Cyg_Thread::set_data( Cyg_Thread::cyg_data_index index, + CYG_ADDRWORD data ) { CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX, "Per thread data index out of bounds"); @@ -487,6 +488,46 @@ inline void Cyg_Thread::set_data( cyg_uc // ------------------------------------------------------------------------- +#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS + + // Add and remove destructors. Returns true on success, false on failure. +inline cyg_bool +Cyg_Thread::add_destructor( destructor_fn fn, CYG_ADDRWORD data ) +{ + cyg_ucount16 i; + Cyg_Scheduler::lock(); + for (i=0; i<CYGNUM_KERNEL_THREADS_DESTRUCTORS; i++) { + if (NULL == destructors[i].fn) { + destructors[i].data = data; + destructors[i].fn = fn; + Cyg_Scheduler::unlock(); + return true; + } + } + Cyg_Scheduler::unlock(); + return false; +} + +inline cyg_bool +Cyg_Thread::rem_destructor( destructor_fn fn, CYG_ADDRWORD data ) +{ + cyg_ucount16 i; + Cyg_Scheduler::lock(); + for (i=0; i<CYGNUM_KERNEL_THREADS_DESTRUCTORS; i++) { + if (destructors[i].fn == fn && destructors[i].data == data) { + destructors[i].fn = NULL; + Cyg_Scheduler::unlock(); + return true; + } + } + Cyg_Scheduler::unlock(); + return false; +} + +#endif + +// ------------------------------------------------------------------------- + #ifdef CYGVAR_KERNEL_THREADS_NAME inline char *Cyg_Thread::get_name()
--- a/packages/kernel/current/src/common/kapi.cxx +++ b/packages/kernel/current/src/common/kapi.cxx @@ -306,28 +306,30 @@ externC cyg_uint32 cyg_thread_measure_st externC cyg_ucount32 cyg_thread_new_data_index() { - return Cyg_Thread::new_data_index(); + Cyg_Thread::cyg_data_index index = Cyg_Thread::new_data_index(); + CYG_ASSERT(index >= 0, "failed to allocate data index" ); + return index; } externC void cyg_thread_free_data_index(cyg_ucount32 index) { - Cyg_Thread::free_data_index(index); + Cyg_Thread::free_data_index(index); } externC CYG_ADDRWORD cyg_thread_get_data(cyg_ucount32 index) { - return Cyg_Thread::get_data(index); + return Cyg_Thread::get_data(index); } externC CYG_ADDRWORD *cyg_thread_get_data_ptr(cyg_ucount32 index) { - return Cyg_Thread::get_data_ptr(index); + return Cyg_Thread::get_data_ptr(index); } externC void cyg_thread_set_data(cyg_ucount32 index, CYG_ADDRWORD data) { - Cyg_Thread::self()->set_data(index, data); + Cyg_Thread::self()->set_data(index, data); } #endif
--- a/packages/kernel/current/src/common/thread.cxx +++ b/packages/kernel/current/src/common/thread.cxx @@ -209,6 +209,11 @@ Cyg_Thread::Cyg_Thread( for( int i = 0; i < CYGNUM_KERNEL_THREADS_DATA_MAX; i++ ) thread_data[i] = 0; #endif +#ifdef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD + for (int j=0; j<CYGNUM_KERNEL_THREADS_DESTRUCTORS; j++) { + destructors[j].fn = NULL; + } +#endif #ifdef CYGVAR_KERNEL_THREADS_NAME name = name_arg; #endif @@ -720,6 +725,13 @@ Cyg_Thread::release() // ------------------------------------------------------------------------- // Exit thread. This puts the thread into EXITED state. +#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS +#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD +Cyg_Thread::Cyg_Destructor_Entry +Cyg_Thread::destructors[ CYGNUM_KERNEL_THREADS_DESTRUCTORS ]; +#endif +#endif + void Cyg_Thread::exit() { @@ -729,6 +741,20 @@ Cyg_Thread::exit() Cyg_Thread *self = Cyg_Thread::self(); +#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS + cyg_ucount16 i; + Cyg_Scheduler::lock(); + for (i=0; i<CYGNUM_KERNEL_THREADS_DESTRUCTORS; i++) { + if (NULL != self->destructors[i].fn) { + destructor_fn fn = self->destructors[i].fn; + CYG_ADDRWORD data = self->destructors[i].data; + Cyg_Scheduler::unlock(); + fn(data); + Cyg_Scheduler::lock(); + } + } + Cyg_Scheduler::unlock(); +#endif #ifdef CYGDBG_KERNEL_THREADS_STACK_MEASUREMENT_VERBOSE_EXIT diag_printf( "Stack usage for thread %08x: %d\n", self, self->measure_stack_usage() ); @@ -1023,14 +1049,15 @@ Cyg_Thread::deliver_exception( cyg_ucount32 Cyg_Thread::thread_data_map = (~CYGNUM_KERNEL_THREADS_DATA_ALL) & ((1<<CYGNUM_KERNEL_THREADS_DATA_MAX)-1); -cyg_ucount32 +Cyg_Thread::cyg_data_index Cyg_Thread::new_data_index() { Cyg_Scheduler::lock(); - cyg_ucount32 index; + Cyg_Thread::cyg_data_index index; - CYG_ASSERT( thread_data_map != 0 , "No more thread data indexes"); + if (0 == thread_data_map) + return -1; // find ls set bit HAL_LSBIT_INDEX( index, thread_data_map ); @@ -1043,7 +1070,7 @@ Cyg_Thread::new_data_index() return index; } -void Cyg_Thread::free_data_index( cyg_ucount32 index ) +void Cyg_Thread::free_data_index( Cyg_Thread::cyg_data_index index ) { Cyg_Scheduler::lock();
--- a/packages/kernel/current/src/instrmnt/meminst.cxx +++ b/packages/kernel/current/src/instrmnt/meminst.cxx @@ -23,7 +23,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // @@ -32,7 +32,7 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): nickg -// Contributors: nickg +// Contributors: nickg, andrew.lunn@ascom.ch // Date: 1997-10-27 // Purpose: Instrumentation functions // Description: The functions in this file are implementations of the @@ -209,6 +209,38 @@ externC void cyg_instrument_disable( cyg // ------------------------------------------------------------------------- +#ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS +#include <cyg/kernel/instrument_desc.h> +#define NELEM(x) (sizeof(x)/sizeof*(x)) +externC char * cyg_instrument_msg(CYG_WORD16 type) { + + struct instrument_desc_s *record; + struct instrument_desc_s *end_record; + CYG_WORD cl, event; + + record = instrument_desc; + end_record = &instrument_desc[NELEM(instrument_desc)]; + cl = type & 0xff00; + event = type & 0x00ff; + + while ((record != end_record) && (record->num != cl)) { + record++; + } + + if (record->num == cl) { + record++; + while ((record != end_record) && (record->num != event) && + (record->num < 0xff)) { + record++; + } + + if (record->num == event) { + return (record->msg); + } + } + return("Unknown event"); +} +#endif // CYGDBG_KERNEL_INSTRUMENT_MSGS #endif // CYGPKG_KERNEL_INSTRUMENT -// EOF instrmnt/null.cxx +// EOF instrmnt/meminst.cxx
deleted file mode 100644 --- a/packages/kernel/current/src/instrmnt/nullinst.cxx +++ /dev/null @@ -1,66 +0,0 @@ -//========================================================================== -// -// instrmnt/null.cxx -// -// Null instrumentation functions -// -//========================================================================== -//####COPYRIGHTBEGIN#### -// -// ------------------------------------------- -// The contents of this file are subject to the Red Hat eCos Public License -// Version 1.1 (the "License"); you may not use this file except in -// compliance with the License. You may obtain a copy of the License at -// http://www.redhat.com/ -// -// Software distributed under the License is distributed on an "AS IS" -// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -// License for the specific language governing rights and limitations under -// the License. -// -// The Original Code is eCos - Embedded Configurable Operating System, -// released September 30, 1998. -// -// The Initial Developer of the Original Code is Red Hat. -// Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): nickg -// Contributors: nickg -// Date: 1997-10-24 -// Purpose: Instrumentation functions -// Description: The functions in this file are null implementations of the -// standard instrumentation functions. These can be used to -// eliminate all instrumentation without recompiling. -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include <pkgconf/kernel.h> - -#include <cyg/kernel/ktypes.h> // base kernel types -#include <cyg/infra/cyg_trac.h> // tracing macros -#include <cyg/infra/cyg_ass.h> // assertion macros -#include <cyg/kernel/instrmnt.h> // instrumentation - -#ifdef CYGPKG_KERNEL_INSTRUMENT - -// ------------------------------------------------------------------------- - -void cyg_instrument( cyg_uint32 type, CYG_ADDRWORD arg1, CYG_ADDRWORD arg2 ) -{ - return; -} - -// ------------------------------------------------------------------------- - -#endif //CYGPKG_KERNEL_INSTRUMENT - -// EOF instrmnt/null.cxx
--- a/packages/kernel/current/src/intr/intr.cxx +++ b/packages/kernel/current/src/intr/intr.cxx @@ -85,7 +85,7 @@ Cyg_Interrupt::Cyg_Interrupt( data = d; #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST - + dsr_count = 0; next_dsr = NULL; @@ -116,17 +116,17 @@ Cyg_Interrupt::~Cyg_Interrupt() #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE Cyg_Interrupt * -Cyg_Interrupt::dsr_table[CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE]; +Cyg_Interrupt::dsr_table[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE]; -cyg_ucount32 Cyg_Interrupt::dsr_table_head = 0; +cyg_ucount32 Cyg_Interrupt::dsr_table_head[CYGNUM_KERNEL_CPU_MAX]; -volatile cyg_ucount32 Cyg_Interrupt::dsr_table_tail = 0; +volatile cyg_ucount32 Cyg_Interrupt::dsr_table_tail[CYGNUM_KERNEL_CPU_MAX]; #endif #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST -Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list = NULL; +Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list[CYGNUM_KERNEL_CPU_MAX]; #endif @@ -138,15 +138,17 @@ Cyg_Interrupt::call_pending_DSRs_inner(v { // CYG_REPORT_FUNCTION(); + HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS(); + #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE - while( dsr_table_head != dsr_table_tail ) + while( dsr_table_head[cpu] != dsr_table_tail[cpu] ) { - Cyg_Interrupt *intr = dsr_table[dsr_table_head]; + Cyg_Interrupt *intr = dsr_table[cpu][dsr_table_head[cpu]]; - dsr_table_head++; - if( dsr_table_head >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE ) - dsr_table_head = 0; + dsr_table_head[cpu]++; + if( dsr_table_head[cpu] >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE ) + dsr_table_head[cpu] = 0; CYG_INSTRUMENT_INTR(CALL_DSR, intr->vector, 0); @@ -159,7 +161,7 @@ Cyg_Interrupt::call_pending_DSRs_inner(v #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST - while( dsr_list != NULL ) + while( dsr_list[cpu] != NULL ) { Cyg_Interrupt* intr; cyg_uint32 old_intr; @@ -167,8 +169,8 @@ Cyg_Interrupt::call_pending_DSRs_inner(v HAL_DISABLE_INTERRUPTS(old_intr); - intr = dsr_list; - dsr_list = intr->next_dsr; + intr = dsr_list[cpu]; + dsr_list[cpu] = intr->next_dsr; count = intr->dsr_count; intr->dsr_count = 0; @@ -211,7 +213,8 @@ void Cyg_Interrupt::post_dsr(void) { // CYG_REPORT_FUNCTION(); - + HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS(); + CYG_INSTRUMENT_INTR(POST_DSR, vector, 0); cyg_uint32 old_intr; @@ -223,9 +226,9 @@ Cyg_Interrupt::post_dsr(void) #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE - dsr_table[dsr_table_tail++] = this; - if( dsr_table_tail >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE ) - dsr_table_tail = 0; + dsr_table[cpu][dsr_table_tail[cpu]++] = this; + if( dsr_table_tail[cpu] >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE ) + dsr_table_tail[cpu] = 0; #endif @@ -239,8 +242,8 @@ Cyg_Interrupt::post_dsr(void) if( dsr_count++ == 0 ) { - next_dsr = dsr_list; - dsr_list = this; + next_dsr = dsr_list[cpu]; + dsr_list[cpu] = this; } #endif @@ -271,7 +274,7 @@ interrupt_end( { // CYG_REPORT_FUNCTION(); -#ifdef CYGPKG_KERNEL_SMP_SUPPORT +#ifdef CYGPKG_KERNEL_SMP_SUPPORT Cyg_Scheduler::lock(); #endif @@ -708,7 +711,7 @@ Cyg_Interrupt::get_cpu( CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector"); CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector"); - HAL_SMP_CPU_TYPE cpu; + HAL_SMP_CPU_TYPE cpu = 0; HAL_INTERRUPT_GET_CPU( vector, cpu );
--- a/packages/kernel/current/src/sched/mlqueue.cxx +++ b/packages/kernel/current/src/sched/mlqueue.cxx @@ -106,7 +106,9 @@ Cyg_Scheduler_Implementation::Cyg_Schedu for( int i = 0; i < CYGNUM_KERNEL_CPU_MAX; i++ ) { +#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE timeslice_count[i] = CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS; +#endif need_reschedule[i] = true; } @@ -350,20 +352,18 @@ void Cyg_Scheduler_Implementation::set_n // Start with current CPU. If we can do the job locally then // that is most efficient. Only go on to other CPUs if that is // not possible. - - HAL_SMP_CPU_TYPE cpu = cpu_this; - HAL_SMP_CPU_TYPE cpu_last = (cpu + cpu_count - 1) % cpu_count; - for(;;) + for(int i = 0; i < cpu_count; i++) { - + HAL_SMP_CPU_TYPE cpu = (i + cpu_this) % cpu_count; + // If a CPU is not already marked for rescheduling, and its // current thread is of lower priority than _thread_, then // set its need_reschedule flag. Cyg_Thread *cur = current_thread[cpu]; - - if( !need_reschedule[cpu] && + + if( (!need_reschedule[cpu]) && (cur->priority > thread->priority) ) { @@ -371,6 +371,9 @@ void Cyg_Scheduler_Implementation::set_n if( cpu != cpu_this ) { + // All processors other than this one need to be sent + // a reschedule interrupt. + CYG_INSTRUMENT_SMP( RESCHED_SEND, cpu, 0 ); CYG_KERNEL_CPU_RESCHEDULE_INTERRUPT( cpu, 0 ); } @@ -380,17 +383,7 @@ void Cyg_Scheduler_Implementation::set_n // that CPU onto another. thread = cur; - cpu = (cpu + 1) % cpu_count; - cpu_last = (cpu + cpu_count - 1) % cpu_count; - continue; } - - // If that was the last CPU in the circle, stop here. - if( cpu == cpu_last ) - break; - - // Otherwise go on to the next. - cpu = (cpu + 1) % cpu_count; } #endif @@ -723,7 +716,18 @@ Cyg_SchedThread_Implementation::to_queue CYG_ASSERTCLASS( thread, "Bad current thread"); Cyg_ThreadQueue *q = thread->get_current_queue(); - q->to_head( thread ); + if( q != NULL ) + q->to_head( thread ); + else if( thread->in_list() ) + { + // If the queue pointer is NULL then it is on a run + // queue. Move the thread to the head of it's priority list + // and force a reschedule. + + Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler; + sched->run_queue[thread->priority].to_head( thread ); + sched->set_need_reschedule( thread ); + } // Unlock the scheduler and switch threads Cyg_Scheduler::unlock();
--- a/packages/kernel/current/src/sync/mutex.cxx +++ b/packages/kernel/current/src/sync/mutex.cxx @@ -95,9 +95,26 @@ Cyg_Mutex::Cyg_Mutex() #endif #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_NONE protocol = NONE; -#endif +#endif + +#else // not (DYNAMIC and DEFAULT defined) + +#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING +#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY + // if there is a default priority ceiling defined, use that to initialize + // the ceiling. + ceiling = CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DEFAULT_PRIORITY; + +#else + + // Otherwise set it to zero. + ceiling = 0; + #endif +#endif + +#endif // DYNAMIC and DEFAULT defined CYG_REPORT_RETURN(); }
--- a/packages/kernel/current/tests/intr0.cxx +++ b/packages/kernel/current/tests/intr0.cxx @@ -133,8 +133,8 @@ void intr0_main( void ) intr1 = new((void *)&intr1_obj[0]) Cyg_Interrupt( lvl2, 1, 888, isr1, dsr1 ); // Check these functions at least exist + Cyg_Interrupt::disable_interrupts(); Cyg_Interrupt::enable_interrupts(); - Cyg_Interrupt::disable_interrupts(); if (intr0) intr0->attach();
--- a/packages/kernel/current/tests/kintr0.c +++ b/packages/kernel/current/tests/kintr0.c @@ -156,8 +156,8 @@ void kintr0_main( void ) // Check these functions at least exist + cyg_interrupt_disable(); cyg_interrupt_enable(); - cyg_interrupt_disable(); if (intr0) cyg_interrupt_attach(intr0);
--- a/packages/kernel/current/tests/smp.cxx +++ b/packages/kernel/current/tests/smp.cxx @@ -86,7 +86,7 @@ static cyg_handle_t threads[NTHREADS_MAX static volatile cyg_uint32 cpu_run[CYGNUM_KERNEL_CPU_MAX]; static volatile int failed = false; -static volatile cyg_handle_t cpu_thread[CYGNUM_KERNEL_CPU_MAX]; +static volatile cyg_uint32 cpu_thread[CYGNUM_KERNEL_CPU_MAX]; static volatile cyg_uint32 slicerun[NTHREADS_MAX][CYGNUM_KERNEL_CPU_MAX]; @@ -141,7 +141,7 @@ void run_smp_test_cpus() } // Just wait a while, until the threads have all run for a bit. - cyg_thread_delay( 1 ); + cyg_thread_delay( 10 ); // Delete all the threads for (i = 0; i < ncpus; i++) { @@ -150,9 +150,12 @@ void run_smp_test_cpus() // And check that a thread ran on each CPU for (i = 0; i < ncpus; i++) { - CYG_TEST_CHECK( cpu_run[i], "CPU didn't run"); +// CYG_TEST_CHECK( cpu_run[i], "CPU didn't run"); if( !cpu_run[i] ) + { + CYG_TEST_INFO( "CPU didn't run" ); failed++; + } } CYG_TEST_INFO( "CPU Test: done"); @@ -166,7 +169,7 @@ test_thread_pri(CYG_ADDRESS id) { for(;;) { - cpu_thread[CYG_KERNEL_CPU_THIS()] = cyg_thread_self(); + cpu_thread[CYG_KERNEL_CPU_THIS()] = id; } } @@ -174,6 +177,7 @@ test_thread_pri(CYG_ADDRESS id) // Second test: Run a thread on each CPU and then by manipulating the // priorities, get the current thread to migrate to each CPU in turn. + void run_smp_test_pri() { int i; @@ -183,7 +187,7 @@ void run_smp_test_pri() // Init flags. for (i = 0; i < ncpus; i++) cpu_run[i] = false; - + // Set my priority higher than any I plan to creat cyg_thread_set_priority(cyg_thread_self(), 2); @@ -200,13 +204,15 @@ void run_smp_test_pri() cyg_thread_resume( threads[i]); } + cyg_thread_delay( 2 ); + cyg_handle_t cthread = threads[0]; cyg_thread_set_priority(cthread, 25); // Just wait a while, until the threads have all run for a bit. - cyg_thread_delay( 1 ); + cyg_thread_delay( 2 ); - for (i = 0; i < ncpus*5; i++) + for (i = 0; i < ncpus*500; i++) { HAL_SMP_CPU_TYPE cpu = i % CYG_KERNEL_CPU_COUNT(); @@ -218,12 +224,17 @@ void run_smp_test_pri() // priority 25. // Pick a thread on a different CPU - cyg_handle_t dthread = cpu_thread[cpu]; + cyg_handle_t dthread; + + do + { + dthread = threads[cpu_thread[cpu]]; + } while( dthread == cthread ); // Change the priority of the victim thread to 20. It is // still higher priority than cthread so it will continue // running. - + cyg_thread_set_priority(dthread, 20); // Now change our priority to 15. We are still higher @@ -248,7 +259,7 @@ void run_smp_test_pri() // Spin here a while until the scheduler sorts itself out. - for( int j = 0; j < 1000; j++ ); + for( int j = 0; j < 100000; j++ ); // Indicate that we have run on this CPU cpu_run[CYG_KERNEL_CPU_THIS()]++; @@ -270,9 +281,12 @@ void run_smp_test_pri() // And check that a thread ran on each CPU for (i = 0; i < ncpus; i++) { - CYG_TEST_CHECK( cpu_run[i], "CPU didn't run"); +// CYG_TEST_CHECK( cpu_run[i], "CPU didn't run"); if( !cpu_run[i] ) + { + CYG_TEST_INFO( "CPU didn't run" ); failed++; + } } CYG_TEST_INFO( "PRI Test: done"); @@ -319,7 +333,7 @@ void run_smp_test_timeslice() } // Just wait a while, until the threads have all run for a bit. - cyg_thread_delay( 20 ); + cyg_thread_delay( 200 ); // Delete all the threads for (i = 0; i < nthread; i++) { @@ -384,7 +398,7 @@ run_smp_tests(CYG_ADDRESS id) { cyg_mutex_init( &mx ); - for( int i = 0; i < 10; i++ ) + for( int i = 0; i < 100; i++ ) { run_smp_test_cpus(); run_smp_test_pri();
new file mode 100644 --- /dev/null +++ b/packages/kernel/current/tests/timeslice.c @@ -0,0 +1,272 @@ +//========================================================================== +// +// timeslice.c +// +// Timeslice test +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): nickg +// Contributors: nickg +// Date: 2001-06-18 +// Description: A basic timeslicing test. +// +//####DESCRIPTIONEND#### +//========================================================================== + +#include <pkgconf/kernel.h> +#include <pkgconf/hal.h> + +#include <cyg/hal/hal_arch.h> + +#include <cyg/kernel/smp.hxx> + +#include <cyg/kernel/kapi.h> + +#include <cyg/infra/testcase.h> +#include <cyg/infra/diag.h> + +//========================================================================== + +#if defined(CYGSEM_KERNEL_SCHED_TIMESLICE) && \ + defined(CYGFUN_KERNEL_API_C) && \ + defined(CYGSEM_KERNEL_SCHED_MLQUEUE) && \ + defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \ + !defined(CYGDBG_INFRA_DIAG_USE_DEVICE) && \ + (CYGNUM_KERNEL_SCHED_PRIORITIES > 12) + +//========================================================================== + +#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL*5 + +#define NTHREADS_MAX (CYGNUM_KERNEL_CPU_MAX*6) + +static int ncpus = CYGNUM_KERNEL_CPU_MAX; + +static char test_stack[STACK_SIZE]; +static cyg_thread test_thread; +static cyg_handle_t main_thread; + +static char stacks[NTHREADS_MAX][STACK_SIZE]; +static cyg_thread test_threads[NTHREADS_MAX]; +static cyg_handle_t threads[NTHREADS_MAX]; + +static volatile int failed = false; + +static volatile cyg_uint32 slicerun[NTHREADS_MAX][CYGNUM_KERNEL_CPU_MAX]; + +//========================================================================== + +void +test_thread_timeslice(CYG_ADDRESS id) +{ + for(;;) + slicerun[id][CYG_KERNEL_CPU_THIS()]++; +} + +//========================================================================== + +void run_test_timeslice(int nthread) +{ + int i,j; + cyg_uint32 cpu_total[CYGNUM_KERNEL_CPU_MAX]; + cyg_uint32 cpu_threads[CYGNUM_KERNEL_CPU_MAX]; + cyg_uint32 thread_total[NTHREADS_MAX]; + + CYG_TEST_INFO( "Timeslice Test: Check timeslicing works"); + + // Init flags. + for (i = 0; i < nthread; i++) + for( j = 0; j < ncpus; j++ ) + slicerun[i][j] = 0; + + // Set my priority higher than any I plan to create + cyg_thread_set_priority(cyg_thread_self(), 2); + + for (i = 0; i < nthread; i++) { + cyg_thread_create(10, // Priority - just a number + test_thread_timeslice, // entry + i, // index + "test_thread", // Name + &stacks[i][0], // Stack + STACK_SIZE, // Size + &threads[i], // Handle + &test_threads[i] // Thread data structure + ); + cyg_thread_resume( threads[i]); + } + + // Just wait a while, until the threads have all run for a bit. + cyg_thread_delay( CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS*100 ); + + // Suspend all the threads + for (i = 0; i < nthread; i++) { + cyg_thread_suspend(threads[i]); + } + + + // And check that a thread ran on each CPU, and that each thread + // ran. + + + diag_printf(" Thread "); + for( j = 0; j < ncpus; j++ ) + { + cpu_total[j] = 0; + cpu_threads[j] = 0; + // " %11d" __123456789ab" + diag_printf(" CPU %2d",j); + } + // " %11d" __123456789ab" + diag_printf(" Total\n"); + for (i = 0; i < nthread; i++) + { + thread_total[i] = 0; + diag_printf(" %2d ",i); + for( j = 0; j < ncpus; j++ ) + { + thread_total[i] += slicerun[i][j]; + cpu_total[j] += slicerun[i][j]; + if( slicerun[i][j] > 0 ) + cpu_threads[j]++; + diag_printf(" %11d",slicerun[i][j]); + } + diag_printf(" %11d\n",thread_total[i]); + if( thread_total[i] == 0 ) + failed++; + } + + diag_printf(" Total "); + for( j = 0; j < ncpus; j++ ) + diag_printf(" %11d",cpu_total[j]); + diag_printf("\n"); + diag_printf("Threads "); + for( j = 0; j < ncpus; j++ ) + { + diag_printf(" %11d",cpu_threads[j]); + if( cpu_threads[j] < 2 ) + failed++; + } + diag_printf("\n"); + + // Delete all the threads + for (i = 0; i < nthread; i++) { + cyg_thread_delete(threads[i]); + } + + CYG_TEST_INFO( "Timeslice Test: done"); +} + + +//========================================================================== + +void +run_tests(CYG_ADDRESS id) +{ + int step; + int nthread; + + // Try to run about 10 times in total, with varying numbers of threads + // from only one extra up to the full set: + + step = (NTHREADS_MAX - (1 + CYG_KERNEL_CPU_COUNT()))/10; + if( step == 0 ) step = 1; + + for( nthread = 1 + CYG_KERNEL_CPU_COUNT() ; + nthread <= NTHREADS_MAX ; + nthread += step ) + run_test_timeslice(nthread); + + if( failed ) + CYG_TEST_FAIL_FINISH("Timeslice test failed\n"); + + CYG_TEST_PASS_FINISH("Timeslice test OK"); +} + +//========================================================================== + +void timeslice_main( void ) +{ + CYG_TEST_INIT(); + + // Work out how many CPUs we actually have. + ncpus = CYG_KERNEL_CPU_COUNT(); + + cyg_thread_create(0, // Priority - just a number + run_tests, // entry + 0, // index + "run_tests", // Name + test_stack, // Stack + STACK_SIZE, // Size + &main_thread, // Handle + &test_thread // Thread data structure + ); + cyg_thread_resume( main_thread); + + cyg_scheduler_start(); +} + +//========================================================================== + +#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG +externC void +cyg_hal_invoke_constructors(); +#endif + +externC void +cyg_start( void ) +{ +#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG + cyg_hal_invoke_constructors(); +#endif + timeslice_main(); +} + +//========================================================================== + +#else // CYGSEM_KERNEL_SCHED_TIMESLICE etc + +externC void +cyg_start( void ) +{ + CYG_TEST_INIT(); + CYG_TEST_NA("SMP test requires:\n" + "CYGSEM_KERNEL_SCHED_TIMESLICE &&\n" + "CYGPKG_KERNEL_SMP_SUPPORT &&\n" + "CYGFUN_KERNEL_API_C && \n" + "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n" + "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n" + "!CYGPKG_HAL_I386_LINUX &&\n" + "!CYGDBG_INFRA_DIAG_USE_DEVICE &&\n" + "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n"); +} + +#endif // CYGSEM_KERNEL_SCHED_TIMESLICE etc. + +//========================================================================== +// EOF timeslice.c
--- a/packages/redboot/current/ChangeLog +++ b/packages/redboot/current/ChangeLog @@ -1,3 +1,68 @@ +2001-09-06 Jonathan Larmour <jlarmour@redhat.com> + + * include/redboot.h: Include string function prototype header. + +2001-09-06 Jesper Skov <jskov@redhat.com> + + * src/fs/ide.c (ide_read_sectors): Use diag_(s)printf. + * src/fs/disk.c (do_disks): Same. + +2001-08-27 Mark Salter <msalter@redhat.com> + + * src/syscall.c (HZ): Should be 60 for ARM, also. + +2001-08-24 Tim Smith <tsmith@redhat.com> + * src/xyzModem.c + * src/xyzModem.h + Provide xyzModem_stream_terminate() function to abort/clean up + XYZmodem download on normal termination or after errors. + + * src/load.c + Use aforementioned function to abort downloads on SREC errors, + stop load_srec_image() from injecting stuff into the XYZmodem + stream and confusing things. + +2001-08-24 Mark Salter <msalter@redhat.com> + + * src/net/net_io.c: Don't close connections if there is + data left to read or write. + + * src/syscall.c: Add support for utimes syscall. + +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * src/net/udp.c: + + * src/net/pktbuf.c: + + * src/net/ping.c: + + * src/net/net_io.c: + + * src/net/inet_addr.c: + + * src/net/enet.c: + + * src/fs/e2fs.c: + + * src/xyzModem.c: + * src/parse.c: + * src/misc_funs.c: + * src/main.c: + * src/load.c: + * src/io.c: + * src/flash.c: + * include/net/net.h: + * include/redboot.h: + printf() is no longer a part of RedBoot. Thus all programs + must use diag_printf() and related functions instead. Also + renamed the non-standard function gets() to be _rb_gets() + since there was some confusion about it because of it's + rather standard name. + + * cdl/redboot.cdl: Lots of changes based on moving all printf() + functionality into "infra" and only using it as diag_XXX(). + 2001-08-17 Gary Thomas <gthomas@redhat.com> * src/version.c: Augment version information with startup mode.
--- a/packages/redboot/current/cdl/redboot.cdl +++ b/packages/redboot/current/cdl/redboot.cdl @@ -68,6 +68,9 @@ cdl_package CYGPKG_REDBOOT { requires ! CYGDBG_HAL_COMMON_CONTEXT_SAVE_MINIMUM requires CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT + requires CYGINT_ISO_STRING_MEMFUNCS + requires CYGINT_ISO_STRING_STRFUNCS + cdl_option CYGBLD_BUILD_REDBOOT_WITH_THREADS { display "Threads debugging support" no_define @@ -98,7 +101,7 @@ cdl_package CYGPKG_REDBOOT { This is handled by a rule in the target CDL." compile main.c crc.c - compile printf.c misc_funs.c io.c parse.c ticks.c xyzModem.c syscall.c + compile misc_funs.c io.c parse.c ticks.c xyzModem.c syscall.c compile decompress.c compile -library=libextras.a load.c
--- a/packages/redboot/current/include/net/net.h +++ b/packages/redboot/current/include/net/net.h @@ -578,7 +578,7 @@ extern char *inet_ntoa(in_addr_t *); #ifdef BSP_LOG #define BSPLOG(x) { int old_console = start_console(); x; end_console(old_console); } -#define bsp_log printf +#define bsp_log diag_printf #else #define BSPLOG(x) #endif
--- a/packages/redboot/current/include/redboot.h +++ b/packages/redboot/current/include/redboot.h @@ -50,6 +50,8 @@ #include <pkgconf/hal.h> #include <cyg/hal/hal_if.h> #include <cyg/hal/hal_tables.h> +#include <cyg/infra/diag.h> +#include <string.h> #ifdef CYGPKG_REDBOOT_NETWORKING #include <net/net.h> @@ -96,27 +98,18 @@ EXTERN int console_baud_rate; #endif // Prototypes -typedef int _printf_fun(char *fmt, ...); -_printf_fun printf; -int vprintf(char *fmt, va_list ap); -int sprintf(char *buf, char *fmt, ...); -int vsprintf(char *buf, char *fmt, va_list ap); -int strlen(const char *str); -int strcmp(const char *s1, const char *s2); -int strncmp(const char *s1, const char *s2, int len); -int strcmpci(const char *s1, const char *s2); -int strncmpci(const char *s1, const char *s2, int len); -char *strcpy(char *s1, const char *s2); -char *strncpy(char *s1, const char *s2, unsigned long n); +typedef int _printf_fun(const char *fmt, ...); +externC int strcasecmp(const char *s1, const char *s2); +externC int strncasecmp(const char *s1, const char *s2, size_t len); -void mon_write_char(char c); -bool verify_action(char *fmt, ...); -void dump_buf(void *, CYG_ADDRWORD); -void dump_buf_with_offset(void *, CYG_ADDRWORD, void *); -void vdump_buf_with_offset(_printf_fun *pf, void *, CYG_ADDRWORD, void *); +externC void mon_write_char(char c); +externC bool verify_action(char *fmt, ...); +//void dump_buf(void *, CYG_ADDRWORD); +//void dump_buf_with_offset(void *, CYG_ADDRWORD, void *); +//void vdump_buf_with_offset(_printf_fun *pf, void *, CYG_ADDRWORD, void *); // Read a single line of input from the console, possibly with timeout -int gets(char *line, int len, int timeout); +externC int _rb_gets(char *line, int len, int timeout); // Result codes from 'gets()' #define _GETS_TIMEOUT -1 #define _GETS_CTRLC -2 @@ -124,8 +117,8 @@ int gets(char *line, int len, int timeo #define _GETS_OK 1 // "console" selection -int start_console(void); -void end_console(int old_console); +externC int start_console(void); +externC void end_console(int old_console); // CRC support unsigned short crc16(unsigned char *buf, int len); @@ -152,8 +145,8 @@ externC _decompress_fun_close* _dc_close #endif // CYGPKG_COMPRESS_ZLIB // CLI support functions -bool parse_num(char *s, unsigned long *val, char **es, char *delim); -bool parse_bool(char *s, bool *val); +externC bool parse_num(char *s, unsigned long *val, char **es, char *delim); +externC bool parse_bool(char *s, bool *val); typedef void cmd_fun(int argc, char *argv[]); struct cmd { @@ -162,8 +155,8 @@ struct cmd { char *usage; cmd_fun *fun; } CYG_HAL_TABLE_TYPE; -extern struct cmd *cmd_search(struct cmd *tab, struct cmd *tabend, char *arg); -extern void cmd_usage(struct cmd *tab, struct cmd *tabend, char *prefix); +externC struct cmd *cmd_search(struct cmd *tab, struct cmd *tabend, char *arg); +externC void cmd_usage(struct cmd *tab, struct cmd *tabend, char *prefix); #define RedBoot_cmd(_s_,_h_,_u_,_f_) cmd_entry(_s_,_h_,_u_,_f_,RedBoot_commands) #define _cmd_entry(_s_,_h_,_u_,_f_,_n_) \ cmd_fun _f_; \ @@ -224,17 +217,17 @@ struct option_info { #define OPTION_ARG_TYPE_FLG 2 // Flag only // Command line parsing -struct cmd *parse(char *line, int *argc, char **argv); +externC struct cmd *parse(char *line, int *argc, char **argv); -extern void init_opts(struct option_info *opts, char flag, bool takes_arg, - int arg_type, void **arg, bool *arg_set, char *name); -extern bool scan_opts(int argc, char *argv[], int first, - struct option_info *opts, int num_opts, - void **def_arg, int def_arg_type, char *def_descr); +externC void init_opts(struct option_info *opts, char flag, bool takes_arg, + int arg_type, void **arg, bool *arg_set, char *name); +externC bool scan_opts(int argc, char *argv[], int first, + struct option_info *opts, int num_opts, + void **def_arg, int def_arg_type, char *def_descr); -extern int redboot_getc(void); -extern void redboot_getc_init(int (*fun)(char *, int, int *), int verbose); -extern void redboot_getc_rewind(void); +externC int redboot_getc(void); +externC void redboot_getc_init(int (*fun)(char *, int, int *), int verbose); +externC void redboot_getc_rewind(void); #define BUF_SIZE 256 typedef struct { @@ -283,11 +276,12 @@ typedef struct { return ret; } + // // Convert a character to lower case // __inline__ static char -tolower(char c) +_tolower(char c) { if ((c >= 'A') && (c <= 'Z')) { c = (c - 'A') + 'a';
--- a/packages/redboot/current/src/flash.c +++ b/packages/redboot/current/src/flash.c @@ -155,7 +155,7 @@ static int cfg_size; // Length of co static void fis_usage(char *why) { - printf("*** invalid 'fis' command: %s\n", why); + diag_printf("*** invalid 'fis' command: %s\n", why); cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis "); } @@ -196,10 +196,10 @@ fis_init(int argc, char *argv[]) } if (!verify_action("About to initialize [format] FLASH image system")) { - printf("** Aborted\n"); + diag_printf("** Aborted\n"); return; } - printf("*** Initialize FLASH Image System\n"); + diag_printf("*** Initialize FLASH Image System\n"); #define MIN_REDBOOT_IMAGE_SIZE CYGBLD_REDBOOT_MIN_IMAGE_SIZE redboot_image_size = block_size > MIN_REDBOOT_IMAGE_SIZE ? block_size : MIN_REDBOOT_IMAGE_SIZE; @@ -280,8 +280,8 @@ fis_init(int argc, char *argv[]) erase_size -= erase_start; if ((stat = flash_erase((void *)erase_start, erase_size, (void **)&err_addr)) != 0) { - printf(" initialization failed at %p: %s\n", - err_addr, flash_errmsg(stat)); + diag_printf(" initialization failed at %p: %s\n", + err_addr, flash_errmsg(stat)); } } // second deal with the larger part in the main: @@ -293,11 +293,11 @@ fis_init(int argc, char *argv[]) #endif if ((stat = flash_erase((void *)erase_start, erase_size, (void **)&err_addr)) != 0) { - printf(" initialization failed at %p: %s\n", - err_addr, flash_errmsg(stat)); + diag_printf(" initialization failed at %p: %s\n", + err_addr, flash_errmsg(stat)); } } else { - printf(" Warning: device contents not erased, some blocks may not be usable\n"); + diag_printf(" Warning: device contents not erased, some blocks may not be usable\n"); } #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL @@ -305,13 +305,13 @@ fis_init(int argc, char *argv[]) flash_unlock((void *)fis_base, block_size, (void **)&err_addr); #endif if ((stat = flash_erase(fis_base, block_size, (void **)&err_addr)) != 0) { - printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); } else { if ((stat = flash_program(fis_base, fis_work_block, (unsigned long)img - (unsigned long)fis_work_block, (void **)&err_addr)) != 0) { - printf("Error writing image descriptors at %p: %s\n", - err_addr, flash_errmsg(stat)); + diag_printf("Error writing image descriptors at %p: %s\n", + err_addr, flash_errmsg(stat)); } } #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL @@ -344,25 +344,25 @@ fis_list(int argc, char *argv[]) } img = (struct fis_image_desc *)((unsigned long)flash_end - block_size); - // Let printf do the formatting in both cases, rather than cnouting + // Let diag_printf do the formatting in both cases, rather than cnouting // cols by hand.... - printf("%-16s %-10s %-10s %-10s %-s\n", - "Name","FLASH addr", - show_cksums ? "Checksum" : "Mem addr", - show_datalen ? "Datalen" : "Length", - "Entry point" ); + diag_printf("%-16s %-10s %-10s %-10s %-s\n", + "Name","FLASH addr", + show_cksums ? "Checksum" : "Mem addr", + show_datalen ? "Datalen" : "Length", + "Entry point" ); for (i = 0; i < block_size/sizeof(*img); i++, img++) { if (img->name[0] != (unsigned char)0xFF) { - printf("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", img->name, - img->flash_base, + diag_printf("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", img->name, + img->flash_base, #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK - show_cksums ? img->file_cksum : img->mem_base, - show_datalen ? img->data_length : img->size, + show_cksums ? img->file_cksum : img->mem_base, + show_datalen ? img->data_length : img->size, #else - img->mem_base, - img->size, + img->mem_base, + img->size, #endif - img->entry_point); + img->entry_point); } } } @@ -381,8 +381,8 @@ fis_free(int argc, char *argv[]) if (*fis_ptr != (unsigned long)0xFFFFFFFF) { if (area_start != fis_ptr) { // Assume that this is something - printf(" 0x%08lX .. 0x%08lX\n", - (unsigned long)area_start, (unsigned long)fis_ptr); + diag_printf(" 0x%08lX .. 0x%08lX\n", + (unsigned long)area_start, (unsigned long)fis_ptr); } // Find next blank block area_start = fis_ptr; @@ -398,8 +398,8 @@ fis_free(int argc, char *argv[]) } } if (area_start != fis_ptr) { - printf(" 0x%08lX .. 0x%08lX\n", - (unsigned long)area_start, (unsigned long)fis_ptr); + diag_printf(" 0x%08lX .. 0x%08lX\n", + (unsigned long)area_start, (unsigned long)fis_ptr); } } @@ -526,34 +526,34 @@ fis_create(int argc, char *argv[]) #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken length = ((length + block_size - 1) / block_size) * block_size; if (length < img_size) { - printf("Invalid FLASH image size/length combination\n"); + diag_printf("Invalid FLASH image size/length combination\n"); return; } #endif if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) { - printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); - printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); + diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } if (flash_addr_set && flash_addr & (block_size-1)) { - printf("Invalid FLASH address: %p\n", (void *)flash_addr); - printf(" must be 0x%x aligned\n", block_size); + diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); + diag_printf(" must be 0x%x aligned\n", block_size); return; } if (strlen(name) >= sizeof(img->name)) { - printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); + diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); return; } if (!no_copy) { if ((mem_addr < (unsigned long)ram_start) || ((mem_addr+img_size) >= (unsigned long)ram_end)) { - printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); - printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); + diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); + diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); } if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { - printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length); + diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length); return; } } @@ -566,11 +566,11 @@ fis_create(int argc, char *argv[]) for (i = 0; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { if (flash_addr_set && (img->flash_base != flash_addr)) { - printf("Image found, but FLASH address incorrect\n"); + diag_printf("Image found, but FLASH address incorrect\n"); return; } if (img->size != length) { - printf("Image found, but LENGTH is incorrect (0x%lx != 0x%lx)\n", img->size, length); + diag_printf("Image found, but LENGTH is incorrect (0x%lx != 0x%lx)\n", img->size, length); return; } if (!verify_action("An image named '%s' exists", name)) { @@ -601,21 +601,21 @@ fis_create(int argc, char *argv[]) if (!no_copy) { // Safety check - make sure the address range is not within the code we're running if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) { - printf("Can't program this region - contains code in use!\n"); + diag_printf("Can't program this region - contains code in use!\n"); return; } prog_ok = true; if (prog_ok) { // Erase area to be programmed if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { - printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } } if (prog_ok) { // Now program it if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) { - printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } } @@ -637,12 +637,12 @@ fis_create(int argc, char *argv[]) flash_unlock((void *)fis_addr, block_size, (void **)&err_addr); #endif if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) { - printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); // Don't try to program if the erase failed } else { // Now program it if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) { - printf("Error programming at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Error programming at %p: %s\n", err_addr, flash_errmsg(stat)); } } #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL @@ -703,12 +703,12 @@ fis_delete(int argc, char *argv[]) } } if (!slot_found) { - printf("No image '%s' found\n", name); + diag_printf("No image '%s' found\n", name); return; } // Erase Data blocks (free space) if ((stat = flash_erase((void *)img->flash_base, img->size, (void **)&err_addr)) != 0) { - printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); } else { #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL // Insure [quietly] that the directory is unlocked before trying to update @@ -717,12 +717,12 @@ fis_delete(int argc, char *argv[]) // Update directory memset(img, 0xFF, sizeof(*img)); if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) { - printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); // Don't try to program if the erase failed } else { // Now program it if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) { - printf("Error programming at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Error programming at %p: %s\n", err_addr, flash_errmsg(stat)); } } #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL @@ -766,7 +766,7 @@ fis_load(int argc, char *argv[]) return; } if ((img = fis_lookup(name)) == (struct fis_image_desc *)0) { - printf("No image '%s' found\n", name); + diag_printf("No image '%s' found\n", name); return; } if (!mem_addr_set) { @@ -775,7 +775,7 @@ fis_load(int argc, char *argv[]) // Load image from FLASH into RAM if ((mem_addr < (unsigned long)user_ram_start) || ((mem_addr+img->size) >= (unsigned long)user_ram_end)) { - printf("Not a loadable image\n"); + diag_printf("Not a loadable image\n"); return; } #ifdef CYGPKG_COMPRESS_ZLIB @@ -798,9 +798,9 @@ fis_load(int argc, char *argv[]) err = (*_dc_close)(p, err); if (0 != err && p->msg) { - printf("decompression error: %s\n", p->msg); + diag_printf("decompression error: %s\n", p->msg); } else { - printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf); + diag_printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf); } } else // dangling block @@ -812,13 +812,13 @@ fis_load(int argc, char *argv[]) #ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK cksum = crc32((unsigned char *)mem_addr, img->data_length); if (show_cksum) { - printf("Checksum: 0x%08lx\n", cksum); + diag_printf("Checksum: 0x%08lx\n", cksum); } // When decompressing, leave CRC checking to decompressor if (!decompress && img->file_cksum) { if (cksum != img->file_cksum) { - printf("** Warning - checksum failure. stored: 0x%08lx, computed: 0x%08lx\n", - img->file_cksum, cksum); + diag_printf("** Warning - checksum failure. stored: 0x%08lx, computed: 0x%08lx\n", + img->file_cksum, cksum); } } #endif @@ -861,23 +861,23 @@ fis_write(int argc, char *argv[]) if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - printf("Invalid FLASH address %p: (%s)\n", (void *)flash_addr, flash_errmsg(stat)); - printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + diag_printf("Invalid FLASH address %p: (%s)\n", (void *)flash_addr, flash_errmsg(stat)); + diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } if (flash_addr_set && flash_addr & (block_size-1)) { - printf("Invalid FLASH address: %p\n", (void *)flash_addr); - printf(" must be 0x%x aligned\n", block_size); + diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); + diag_printf(" must be 0x%x aligned\n", block_size); return; } if ((mem_addr < (unsigned long)ram_start) || ((mem_addr+length) >= (unsigned long)ram_end)) { - printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); - printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); + diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); + diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); } // Safety check - make sure the address range is not within the code we're running if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { - printf("Can't program this region - contains code in use!\n"); + diag_printf("Can't program this region - contains code in use!\n"); return; } if (!verify_action("* CAUTION * about to program FLASH\n at %p..%p from %p", @@ -889,14 +889,14 @@ fis_write(int argc, char *argv[]) if (prog_ok) { // Erase area to be programmed if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { - printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } } if (prog_ok) { // Now program it if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) { - printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); prog_ok = false; } } @@ -929,22 +929,22 @@ fis_erase(int argc, char *argv[]) if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); - printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); + diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } if (flash_addr_set && flash_addr & (block_size-1)) { - printf("Invalid FLASH address: %p\n", (void *)flash_addr); - printf(" must be 0x%x aligned\n", block_size); + diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); + diag_printf(" must be 0x%x aligned\n", block_size); return; } // Safety check - make sure the address range is not within the code we're running if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { - printf("Can't erase this region - contains code in use!\n"); + diag_printf("Can't erase this region - contains code in use!\n"); return; } if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { - printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); } } @@ -977,12 +977,12 @@ fis_lock(int argc, char *argv[]) if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); - printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); + diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) { - printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat)); } } @@ -1013,12 +1013,12 @@ fis_unlock(int argc, char *argv[]) if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { - printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); - printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); + diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); + diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) { - printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat)); } } #endif @@ -1029,7 +1029,7 @@ void _flash_info(void) { if (!__flash_init) return; - printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", + diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", flash_start, flash_end, blocks, (void *)block_size); } @@ -1041,8 +1041,8 @@ do_flash_init(void) if (!__flash_init) { __flash_init = 1; if ((stat = flash_init((void *)(workspace_end-FLASH_MIN_WORKSPACE), - FLASH_MIN_WORKSPACE, printf)) != 0) { - printf("FLASH: driver init failed: %s\n", flash_errmsg(stat)); + FLASH_MIN_WORKSPACE, diag_printf)) != 0) { + diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat)); return false; } flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); @@ -1198,52 +1198,52 @@ get_config(unsigned char *dp, char *titl } val_ptr = (void *)CONFIG_OBJECT_VALUE(dp); if (LIST_OPT_NICKNAMES & list_opt) - printf("%s: ", CONFIG_OBJECT_KEY(dp)); + diag_printf("%s: ", CONFIG_OBJECT_KEY(dp)); if (LIST_OPT_FULLNAMES & list_opt) { if (title != (char *)NULL) { - printf("%s: ", title); + diag_printf("%s: ", title); } else { - printf("%s: ", CONFIG_OBJECT_KEY(dp)); + diag_printf("%s: ", CONFIG_OBJECT_KEY(dp)); } } switch (type = CONFIG_OBJECT_TYPE(dp)) { case CONFIG_BOOL: memcpy(&hold_bool_val, val_ptr, sizeof(bool)); - printf("%s ", hold_bool_val ? "true" : "false"); + diag_printf("%s ", hold_bool_val ? "true" : "false"); break; case CONFIG_INT: memcpy(&hold_int_val, val_ptr, sizeof(unsigned long)); - printf("%ld ", hold_int_val); + diag_printf("%ld ", hold_int_val); break; #ifdef CYGPKG_REDBOOT_NETWORKING case CONFIG_IP: - printf("%s ", inet_ntoa((in_addr_t *)val_ptr)); + diag_printf("%s ", inet_ntoa((in_addr_t *)val_ptr)); break; case CONFIG_ESA: for (esa_ptr = 0; esa_ptr < sizeof(enet_addr_t); esa_ptr++) { - printf("0x%02X", ((unsigned char *)val_ptr)[esa_ptr]); - if (esa_ptr < (sizeof(enet_addr_t)-1)) printf(":"); + diag_printf("0x%02X", ((unsigned char *)val_ptr)[esa_ptr]); + if (esa_ptr < (sizeof(enet_addr_t)-1)) diag_printf(":"); } - printf(" "); + diag_printf(" "); break; #endif case CONFIG_STRING: - printf("%s ", (unsigned char *)val_ptr); + diag_printf("%s ", (unsigned char *)val_ptr); break; case CONFIG_SCRIPT: - printf("\n"); + diag_printf("\n"); sp = lp = (unsigned char *)val_ptr; while (*sp) { while (*lp != '\n') lp++; *lp = '\0'; - printf(".. %s\n", sp); + diag_printf(".. %s\n", sp); *lp++ = '\n'; sp = lp; } break; } if (LIST_OPT_LIST_ONLY & list_opt) { - printf("\n"); + diag_printf("\n"); return CONFIG_OK; } if (type != CONFIG_SCRIPT) { @@ -1252,10 +1252,10 @@ get_config(unsigned char *dp, char *titl if (ret > sizeof(line)) return CONFIG_BAD; strcpy(line, newvalue); - printf("Setting to %s\n", newvalue); + diag_printf("Setting to %s\n", newvalue); } else // read from terminal - ret = gets(line, sizeof(line), 0); + ret = _rb_gets(line, sizeof(line), 0); if (ret < 0) return CONFIG_ABORT; if (strlen(line) == 0) return CONFIG_OK; // Just a CR - leave value untouched if (line[0] == '.') return CONFIG_DONE; @@ -1316,11 +1316,11 @@ get_config(unsigned char *dp, char *titl case CONFIG_SCRIPT: // Assume it always changes sp = (unsigned char *)val_ptr; - printf("Enter script, terminate with empty line\n"); + diag_printf("Enter script, terminate with empty line\n"); while (true) { *sp = '\0'; - printf(">> "); - ret = gets(line, sizeof(line), 0); + diag_printf(">> "); + ret = _rb_gets(line, sizeof(line), 0); if (ret < 0) return CONFIG_ABORT; if (strlen(line) == 0) break; lp = line; @@ -1332,7 +1332,7 @@ get_config(unsigned char *dp, char *titl break; case CONFIG_STRING: if (strlen(line) >= MAX_STRING_LENGTH) { - printf("Sorry, value is too long\n"); + diag_printf("Sorry, value is too long\n"); return CONFIG_BAD; } strcpy((unsigned char *)val_ptr, line); @@ -1470,7 +1470,7 @@ do_flash_config(int argc, char *argv[]) continue; case CONFIG_BAD: // Nothing - make him do it again - printf ("** invalid entry\n"); + diag_printf ("** invalid entry\n"); } } @@ -1479,10 +1479,10 @@ do_flash_config(int argc, char *argv[]) #ifdef CYGSEM_REDBOOT_ALLOW_DYNAMIC_FLASH_CONFIG_DATA if (verify_action("** entry '%s' not found - add", onlyone)) { struct config_option opt; - printf("Trying to add value\n"); + diag_printf("Trying to add value\n"); } #else - printf("** entry '%s' not found", onlyone); + diag_printf("** entry '%s' not found", onlyone); #endif } if (!need_update) @@ -1502,7 +1502,7 @@ RedBoot_cmd("alias", static void make_alias(char *alias, char *name) { - sprintf(alias, "alias/%s", name); + diag_sprintf(alias, "alias/%s", name); } static void @@ -1516,14 +1516,14 @@ do_alias(int argc, char *argv[]) case 2: make_alias(name, argv[1]); if (flash_get_config(name, &val, CONFIG_STRING)) { - printf("'%s' = '%s'\n", argv[1], val); + diag_printf("'%s' = '%s'\n", argv[1], val); } else { - printf("'%s' not found\n", argv[1]); + diag_printf("'%s' not found\n", argv[1]); } break; case 3: if (strlen(argv[2]) >= MAX_STRING_LENGTH) { - printf("Sorry, value is too long\n"); + diag_printf("Sorry, value is too long\n"); break; } make_alias(name, argv[1]); @@ -1535,7 +1535,7 @@ do_alias(int argc, char *argv[]) flash_add_config(&opt, true); break; default: - printf("usage: alias name [value]\n"); + diag_printf("usage: alias name [value]\n"); } } @@ -1572,7 +1572,7 @@ bool lp += 2; while (*lp && (*lp != '}')) lp++; if (!*lp) { - printf("Invalid macro/alias '%s'\n", ms); + diag_printf("Invalid macro/alias '%s'\n", ms); line[0] = '\0'; // Destroy line return false; } @@ -1599,12 +1599,12 @@ bool } line_len = strlen(line); } else { - printf("No room to expand '%s'\n", ms); + diag_printf("No room to expand '%s'\n", ms); line[0] = '\0'; // Destroy line return false; } } else { - printf("Alias '%s' not defined\n", ms); + diag_printf("Alias '%s' not defined\n", ms); *me = '|'; } } else if (c == '"') { @@ -1642,12 +1642,12 @@ flash_write_config(void) flash_unlock((void *)cfg_base, cfg_size, (void **)&err_addr); #endif if ((stat = flash_erase(cfg_base, cfg_size, (void **)&err_addr)) != 0) { - printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); + diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); } else { if ((stat = flash_program(cfg_base, (void *)&config, sizeof(config), (void **)&err_addr)) != 0) { - printf("Error writing config data at %p: %s\n", - err_addr, flash_errmsg(stat)); + diag_printf("Error writing config data at %p: %s\n", + err_addr, flash_errmsg(stat)); } } #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL @@ -1677,7 +1677,7 @@ flash_lookup_config(char *key) } dp += len; } -// printf("Can't find config data for '%s'\n", key); +// diag_printf("Can't find config data for '%s'\n", key); return false; } @@ -1718,7 +1718,7 @@ flash_get_config(char *key, void *val, i break; } } else { - printf("Request for config value '%s' - wrong type\n", key); + diag_printf("Request for config value '%s' - wrong type\n", key); } return true; } @@ -1814,7 +1814,7 @@ flash_add_config(struct config_option *o size += len; } } - printf("No space to add '%s'\n", opt->key); + diag_printf("No space to add '%s'\n", opt->key); return false; } @@ -1858,7 +1858,7 @@ load_flash_config(void) memcpy(&config, cfg_base, sizeof(config)); if ((crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)) != config.cksum) || (config.key1 != CONFIG_KEY1)|| (config.key2 != CONFIG_KEY2)) { - printf("FLASH configuration checksum error or invalid key\n"); + diag_printf("FLASH configuration checksum error or invalid key\n"); config_init(); return; }
--- a/packages/redboot/current/src/fs/disk.c +++ b/packages/redboot/current/src/fs/disk.c @@ -310,20 +310,22 @@ do_disks(int argc, char *argv[]) char name[16]; for (i = 0, d = disk_table; i < disk_count; i++, d++) { - switch (d->kind) { - case DISK_IDE_HD: - for (j = 0, p = d->partitions; j < CYGNUM_REDBOOT_MAX_PARTITIONS; j++, p++) { - if (p->systype) { - sprintf(name, "hd%c%d", 'a' + d->index, j+1); - printf("%-8s %s\n", name, systype_name(p->systype)); - } - } - break; - case DISK_IDE_CDROM: - sprintf(name, "cd%d", d->index); - printf("%-8s ISO9660\n", name); - break; - } + switch (d->kind) { + case DISK_IDE_HD: + for (j = 0, p = d->partitions; + j < CYGNUM_REDBOOT_MAX_PARTITIONS; + j++, p++) { + if (p->systype) { + diag_sprintf(name, "hd%c%d", 'a' + d->index, j+1); + diag_printf("%-8s %s\n", name, systype_name(p->systype)); + } + } + break; + case DISK_IDE_CDROM: + diag_sprintf(name, "cd%d", d->index); + diag_printf("%-8s ISO9660\n", name); + break; + } } }
--- a/packages/redboot/current/src/fs/e2fs.c +++ b/packages/redboot/current/src/fs/e2fs.c @@ -88,8 +88,8 @@ e2fs_get_gdesc(e2fs_desc_t *e2fs, cyg_ui sec_nr += (group_nr / E2FS_GDESC_PER_SECTOR); #if DEBUG_E2FS > 2 - printf("%s: group[%d] cache miss, sec_nr[%d]\n", - __FUNCTION__, group_nr, sec_nr); + diag_printf("%s: group[%d] cache miss, sec_nr[%d]\n", + __FUNCTION__, group_nr, sec_nr); #endif if (!PARTITION_READ(e2fs->part, sec_nr, (cyg_uint32 *)e2fs->gdesc_cache, sizeof(e2fs->gdesc_cache)/SECTOR_SIZE)) @@ -125,8 +125,8 @@ e2fs_get_inode(e2fs_desc_t *e2fs, int in offset %= SECTOR_SIZE; #if DEBUG_E2FS > 0 - printf("%s: ino[%d], sec_nr[%d] offset[%d]\n", __FUNCTION__, - ino, sec_nr, offset); + diag_printf("%s: ino[%d], sec_nr[%d] offset[%d]\n", __FUNCTION__, + ino, sec_nr, offset); #endif if (!PARTITION_READ(e2fs->part, sec_nr, buf, 1)) @@ -135,7 +135,7 @@ e2fs_get_inode(e2fs_desc_t *e2fs, int in *ip = *(e2fs_inode_t *)((char *)buf + offset); #if DEBUG_E2FS > 0 - printf("%s: inode size[%d]\n", __FUNCTION__, SWAB_LE32(ip->size)); + diag_printf("%s: inode size[%d]\n", __FUNCTION__, SWAB_LE32(ip->size)); #endif return 1; @@ -158,7 +158,7 @@ e2fs_mount(partition_t *part, e2fs_desc_ return -1; if (SWAB_LE16(sb->magic) != E2FS_SUPER_MAGIC) { - printf("ext2_mount: bad magic 0x%x\n", SWAB_LE16(sb->magic)); + diag_printf("ext2_mount: bad magic 0x%x\n", SWAB_LE16(sb->magic)); return -1; } @@ -181,12 +181,12 @@ e2fs_mount(partition_t *part, e2fs_desc_ return -1; #if DEBUG_E2FS > 1 - printf("E2FS superblock:\n"); - printf(" [%d] inodes\n", SWAB_LE32(sb->inodes_count)); - printf(" [%d] blocks\n", SWAB_LE32(sb->blocks_count)); - printf(" [%d] blocksize\n", e2fs->blocksize); - printf(" [%d] blocks per group\n", e2fs->blocks_per_group); - printf(" [%d] ngroups\n", e2fs->ngroups); + diag_printf("E2FS superblock:\n"); + diag_printf(" [%d] inodes\n", SWAB_LE32(sb->inodes_count)); + diag_printf(" [%d] blocks\n", SWAB_LE32(sb->blocks_count)); + diag_printf(" [%d] blocksize\n", e2fs->blocksize); + diag_printf(" [%d] blocks per group\n", e2fs->blocks_per_group); + diag_printf(" [%d] ngroups\n", e2fs->ngroups); #endif #if DEBUG_E2FS > 4 @@ -289,13 +289,13 @@ e2fs_dir_lookup(e2fs_desc_t *e2fs, cyg_u cyg_uint32 nblocks, last_block_size, i, block_nr, nbytes; #if DEBUG_E2FS > 0 - printf("%s: looking for %s [%d] in ino[%d]\n", - __FUNCTION__, name, namelen, dir_ino); + diag_printf("%s: looking for %s [%d] in ino[%d]\n", + __FUNCTION__, name, namelen, dir_ino); #endif if (!e2fs_get_inode(e2fs, dir_ino, &inode)) { #if DEBUG_E2FS > 0 - printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, dir_ino); + diag_printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, dir_ino); #endif return NULL; } @@ -349,7 +349,7 @@ e2fs_follow_symlink(e2fs_desc_t *e2fs, c if (!e2fs_get_inode(e2fs, sym_ino, &inode)) { #if DEBUG_E2FS > 0 - printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, *ino); + diag_printf("%s: e2fs_get_inode [%d] failed\n", __FUNCTION__, *ino); #endif return 0; } @@ -472,19 +472,19 @@ e2fs_open(partition_t *p, const char *fi // mount partition if (e2fs_mount(p, &rinfo.e2fs_desc) != 0) { - printf("mount failed.\n"); + diag_printf("mount failed.\n"); return NULL; } // find file inode if (!e2fs_inode_lookup(&rinfo.e2fs_desc, E2FS_ROOT_INO, filepath, &ino_info)) { - printf("%s: e2fs_inode_lookup failed\n", __FUNCTION__); + diag_printf("%s: e2fs_inode_lookup failed\n", __FUNCTION__); return NULL; } // read inode if (!e2fs_get_inode(&rinfo.e2fs_desc, ino_info.ino, &rinfo.inode)) { - printf("%s: e2fs_get_inode failed for ino[%d]\n", __FUNCTION__, ino_info.ino); + diag_printf("%s: e2fs_get_inode failed for ino[%d]\n", __FUNCTION__, ino_info.ino); return NULL; } @@ -552,46 +552,46 @@ e2fs_read(void *fp, char *buf, cyg_uint3 #if DEBUG_E2FS > 4 static void dump_sb(struct e2fs_super_block *s) { - printf("inode_count: %d\n", SWAB_LE32(s->inodes_count)); - printf("blocks_count: %d\n", SWAB_LE32(s->blocks_count)); - printf("r_blocks_count: %d\n", SWAB_LE32(s->r_blocks_count)); - printf("free_blocks_count: %d\n", SWAB_LE32(s->free_blocks_count)); - printf("free_inodes_count: %d\n", SWAB_LE32(s->free_inodes_count)); - printf("first_data_block: %d\n", SWAB_LE32(s->first_data_block)); - printf("log_block_size: %d\n", SWAB_LE32(s->log_block_size)); - printf("log_frag_size: %d\n", SWAB_LE32(s->log_frag_size)); - printf("blocks_per_group: %d\n", SWAB_LE32(s->blocks_per_group)); - printf("frags_per_group: %d\n", SWAB_LE32(s->frags_per_group)); - printf("inodes_per_group: %d\n", SWAB_LE32(s->inodes_per_group)); - printf("mnt_count: %d\n", SWAB_LE16(s->mnt_count)); - printf("max_mnt_count: %d\n", SWAB_LE16(s->max_mnt_count)); - printf("magic: %d\n", SWAB_LE16(s->magic)); - printf("state: %d\n", SWAB_LE16(s->state)); - printf("errors: %d\n", SWAB_LE16(s->errors)); - printf("minor_rev_level: %d\n", SWAB_LE16(s->minor_rev_level)); - printf("lastcheck: %d\n", SWAB_LE32(s->lastcheck)); - printf("checkinterval: %d\n", SWAB_LE32(s->checkinterval)); - printf("creator_os: %d\n", SWAB_LE32(s->creator_os)); - printf("rev_level: %d\n", SWAB_LE32(s->rev_level)); + diag_printf("inode_count: %d\n", SWAB_LE32(s->inodes_count)); + diag_printf("blocks_count: %d\n", SWAB_LE32(s->blocks_count)); + diag_printf("r_blocks_count: %d\n", SWAB_LE32(s->r_blocks_count)); + diag_printf("free_blocks_count: %d\n", SWAB_LE32(s->free_blocks_count)); + diag_printf("free_inodes_count: %d\n", SWAB_LE32(s->free_inodes_count)); + diag_printf("first_data_block: %d\n", SWAB_LE32(s->first_data_block)); + diag_printf("log_block_size: %d\n", SWAB_LE32(s->log_block_size)); + diag_printf("log_frag_size: %d\n", SWAB_LE32(s->log_frag_size)); + diag_printf("blocks_per_group: %d\n", SWAB_LE32(s->blocks_per_group)); + diag_printf("frags_per_group: %d\n", SWAB_LE32(s->frags_per_group)); + diag_printf("inodes_per_group: %d\n", SWAB_LE32(s->inodes_per_group)); + diag_printf("mnt_count: %d\n", SWAB_LE16(s->mnt_count)); + diag_printf("max_mnt_count: %d\n", SWAB_LE16(s->max_mnt_count)); + diag_printf("magic: %d\n", SWAB_LE16(s->magic)); + diag_printf("state: %d\n", SWAB_LE16(s->state)); + diag_printf("errors: %d\n", SWAB_LE16(s->errors)); + diag_printf("minor_rev_level: %d\n", SWAB_LE16(s->minor_rev_level)); + diag_printf("lastcheck: %d\n", SWAB_LE32(s->lastcheck)); + diag_printf("checkinterval: %d\n", SWAB_LE32(s->checkinterval)); + diag_printf("creator_os: %d\n", SWAB_LE32(s->creator_os)); + diag_printf("rev_level: %d\n", SWAB_LE32(s->rev_level)); } static void dump_inode(struct e2fs_inode *i) { int j, n; - printf("mode: %o\n", SWAB_LE16(i->mode)); - printf("uid: %o\n", SWAB_LE16(i->uid)); - printf("size: %d\n", SWAB_LE32(i->size)); - printf("gid: %o\n", SWAB_LE16(i->gid)); - printf("links: %d\n", SWAB_LE16(i->links_count)); - printf("blocks: %d\n", SWAB_LE32(i->blocks)); + diag_printf("mode: %o\n", SWAB_LE16(i->mode)); + diag_printf("uid: %o\n", SWAB_LE16(i->uid)); + diag_printf("size: %d\n", SWAB_LE32(i->size)); + diag_printf("gid: %o\n", SWAB_LE16(i->gid)); + diag_printf("links: %d\n", SWAB_LE16(i->links_count)); + diag_printf("blocks: %d\n", SWAB_LE32(i->blocks)); n = i->blocks; if (n > E2FS_N_BLOCKS) n = E2FS_N_BLOCKS; for (j = 0; j < n; j++) - printf(" block: %d\n", SWAB_LE32(i->block[j])); + diag_printf(" block: %d\n", SWAB_LE32(i->block[j])); } #endif
--- a/packages/redboot/current/src/fs/ide.c +++ b/packages/redboot/current/src/fs/ide.c @@ -139,14 +139,14 @@ ide_read_sectors(int ctlr, int dev, cyg_ for(p = buf, i = 0; i < count; i++) { - if (!__wait_for_drq(ctlr)) { - printf("%s: NO DRQ for ide%d, device %d.\n", - __FUNCTION__, ctlr, dev); - return 0; - } + if (!__wait_for_drq(ctlr)) { + diag_printf("%s: NO DRQ for ide%d, device %d.\n", + __FUNCTION__, ctlr, dev); + return 0; + } - for (j = 0; j < (SECTOR_SIZE / sizeof(cyg_uint16)); j++, p++) - HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *p); + for (j = 0; j < (SECTOR_SIZE / sizeof(cyg_uint16)); j++, p++) + HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *p); } return 1; }
--- a/packages/redboot/current/src/io.c +++ b/packages/redboot/current/src/io.c @@ -82,7 +82,7 @@ do_channel(int argc, char *argv[]) { unsigned long chan; if ( !parse_num( argv[1], &chan, NULL, NULL) ) { - printf("** Error: invalid channel '%s'\n", argv[1]); + diag_printf("** Error: invalid channel '%s'\n", argv[1]); } else { if (chan < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS) { CYGACC_CALL_IF_SET_CONSOLE_COMM(chan); @@ -91,20 +91,20 @@ do_channel(int argc, char *argv[]) console_echo = true; } else { - printf("**Error: bad channel number '%s'\n", argv[1]); + diag_printf("**Error: bad channel number '%s'\n", argv[1]); } } } } /* else display */ else { - printf("Current console channel id: "); + diag_printf("Current console channel id: "); #ifdef CYGPKG_REDBOOT_ANY_CONSOLE if (!console_selected) - printf("-1\n"); + diag_printf("-1\n"); else #endif - printf("%d\n", cur); + diag_printf("%d\n", cur); } } @@ -283,7 +283,7 @@ getc_script(char *cp) // -2: ^C typed // int -gets(char *buf, int buflen, int timeout) +_rb_gets(char *buf, int buflen, int timeout) { char *ptr = buf; char c; @@ -318,7 +318,7 @@ gets(char *buf, int buflen, int timeout) switch (c) { case 0x03: // ^C if (ptr == buf) { - printf("^C\n"); + diag_printf("^C\n"); return _GETS_CTRLC; } *ptr++ = c; @@ -349,7 +349,6 @@ gets(char *buf, int buflen, int timeout) ptr--; } break; -#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS case '\\': // escape character if (console_echo) { mon_write_char(c); @@ -359,6 +358,7 @@ gets(char *buf, int buflen, int timeout) *ptr++ = c; c = '\0'; // cheat so that the "shift" state resets break; +#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS case '+': // fall through case '$': if (ptr == buf || last_ch != '\\') @@ -381,59 +381,6 @@ gets(char *buf, int buflen, int timeout) } } -void -vdump_buf_with_offset(_printf_fun *pf, void *_p, CYG_ADDRWORD s, void *_base) -{ - int i, c; - cyg_uint8 *p = (cyg_uint8 *)_p; - cyg_uint8 *base = (cyg_uint8 *)_base; - - if ((CYG_ADDRWORD)s > (CYG_ADDRWORD)p) { - s = (CYG_ADDRWORD)s - (CYG_ADDRWORD)p; - } - while ((int)s > 0) { - if (base) { - (*pf)("0x%08X: ", (CYG_ADDRWORD)p - (CYG_ADDRWORD)base); - } else { - (*pf)("0x%08X: ", (CYG_ADDRWORD)p); - } - for (i = 0; i < 16; i++) { - if (i < (int)s) { - (*pf)("%02X", p[i] & 0xFF); - } else { - (*pf)(" "); - } - if ((i % 2) == 1) (*pf)(" "); - if ((i % 8) == 7) (*pf)(" "); - } - (*pf)(" |"); - for (i = 0; i < 16; i++) { - if (i < (int)s) { - c = p[i] & 0xFF; - if ((c < 0x20) || (c >= 0x7F)) c = '.'; - } else { - c = ' '; - } - (*pf)("%c", c); - } - (*pf)("|\n"); - s -= 16; - p += 16; - } -} - -void -dump_buf_with_offset(void *p, CYG_ADDRWORD s, void *base) -{ - vdump_buf_with_offset(printf, p, s, base); -} - -void -dump_buf(void *p, CYG_ADDRWORD s) -{ - dump_buf_with_offset((cyg_uint8 *)p, s, 0); -} - bool verify_action(char *fmt, ...) { @@ -446,8 +393,8 @@ verify_action(char *fmt, ...) #endif va_start(ap, fmt); - vprintf(fmt, ap); - printf(" - are you sure (y/n)? "); - gets(ans, sizeof(ans), 0); + diag_vprintf(fmt, ap); + diag_printf(" - are you sure (y/n)? "); + _rb_gets(ans, sizeof(ans), 0); return ((ans[0] == 'y') || (ans[0] == 'Y')); }
--- a/packages/redboot/current/src/load.c +++ b/packages/redboot/current/src/load.c @@ -32,7 +32,7 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): gthomas -// Contributors: gthomas +// Contributors: gthomas, tsmith // Date: 2000-07-14 // Purpose: // Description: @@ -49,6 +49,7 @@ #include <fs/disk.h> #endif + // Buffer used by redboot_getc getc_info_t getc_info; @@ -72,7 +73,7 @@ RedBoot_cmd("load", static unsigned long load_elf_image(int (*getc)(void)) { - printf("ELF images not supported\n"); + diag_printf("ELF images not supported\n"); return 0; } @@ -114,7 +115,7 @@ static long // #define MAX_LINE 80 static unsigned long -load_srec_image(int (*getc)(void), unsigned long base) +load_srec_image(int (*getc)(void), void (*terminate)(int method,int (*getc)(void)), unsigned long base) { char line[MAX_LINE]; char *lp; @@ -131,7 +132,8 @@ load_srec_image(int (*getc)(void), unsig lp = line; len = 0; // Start of line if (c != 'S') { - printf("Invalid S-record at offset %p, input: %c\n", + if (terminate) (*terminate)(xyzModem_abort, getc); + diag_printf("Invalid S-record at offset %p, input: %c\n", (void *)offset, c); return 0; } @@ -139,7 +141,8 @@ load_srec_image(int (*getc)(void), unsig offset += 2; sum = 0; if ((count = _hex2(getc, 1, &sum)) < 0) { - printf("Bad S-record count at offset %p\n", (void *)offset); + if (terminate) (*terminate)(xyzModem_abort, getc); + diag_printf("Bad S-record count at offset %p\n", (void *)offset); return 0; } offset += 1; @@ -154,7 +157,6 @@ load_srec_image(int (*getc)(void), unsig if (first_addr) { if (base) { addr_offset = (unsigned long)base - (unsigned long)addr; - printf("Address offset = %p\n", (void *)addr_offset); } else { addr_offset = 0; } @@ -166,9 +168,16 @@ load_srec_image(int (*getc)(void), unsig } #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS if ((addr < user_ram_start) || (addr > user_ram_end)) { + // Only if there is no need to stop the download before printing + // output can we ask confirmation questions. + if (terminate) { + (*terminate)(xyzModem_abort, getc); + diag_printf("*** Warning! Attempt to load S-record to address: %p\nRedBoot does not believe this is in RAM\nUse TFTP for a chance to override this.\n",(void*)addr); + } else { if (!verify_action("Attempt to load S-record data to address: %p\n" "RedBoot does not believe this is in RAM", (void*)addr)) return 0; + } } #endif count -= ((type-'1'+2)+1); @@ -182,7 +191,8 @@ load_srec_image(int (*getc)(void), unsig sum = sum & 0xFF; cksum = (~cksum & 0xFF); if (cksum != sum) { - printf("*** Warning! Checksum failure - Addr: %lx, %02lX <> %02lX\n", + if (terminate) (*terminate)(xyzModem_abort, getc); + diag_printf("*** Warning! Checksum failure - Addr: %lx, %02lX <> %02lX\n", (unsigned long)base_addr, sum, cksum); return 0; } @@ -196,12 +206,14 @@ load_srec_image(int (*getc)(void), unsig addr = (unsigned char *)_hex2(getc, ('9'-type+2), &sum); offset += ('9'-type+2); entry_address = (unsigned long *)addr; - printf("Entry point: %p, address range: %p-%p\n", + if (terminate) (*terminate)(xyzModem_close, getc); + if (addr_offset) diag_printf("Address offset = %p\n", (void *)addr_offset); + diag_printf("Entry point: %p, address range: %p-%p\n", (void*)entry_address, (void *)lowest_address, (void *)highest_address); - while ((c = (*getc)()) > 0) ; // Swallow rest of data return highest_address; default: - printf("Invalid S-record at offset 0x%lx, type: %x\n", + if (terminate) (*terminate)(xyzModem_abort, getc); + diag_printf("Invalid S-record at offset 0x%lx, type: %x\n", (unsigned long)offset, type); return 0; } @@ -220,20 +232,20 @@ redboot_getc(void) } if (getc_info.avail == 0) { if (getc_info.verbose) { - printf("%c\b", spin[getc_info.tick++]); + diag_printf("%c\b", spin[getc_info.tick++]); if (getc_info.tick >= sizeof(spin)) { getc_info.tick = 0; } } if (getc_info.len < BUF_SIZE) { // No more data available - if (getc_info.verbose) printf("\n"); + if (getc_info.verbose) diag_printf("\n"); return -1; } getc_info.bufp = getc_info.buf; getc_info.len = (*getc_info.fun)(getc_info.bufp, BUF_SIZE, &getc_info.err); if ((getc_info.avail = getc_info.len) <= 0) { - if (getc_info.verbose) printf("\n"); + if (getc_info.verbose) diag_printf("\n"); return -1; } } @@ -326,14 +338,14 @@ do_load(int argc, char *argv[]) #ifdef CYGPKG_REDBOOT_NETWORKING if (hostname_set) { if (!inet_aton(hostname, (in_addr_t *)&host)) { - printf("Invalid IP address: %s\n", hostname); + diag_printf("Invalid IP address: %s\n", hostname); return; } } #endif if (mode_str_set) { - if (strncmpci(&mode_str[1], "modem", strlen(&mode_str[1])) == 0) { - switch (tolower(mode_str[0])) { + if (strncasecmp(&mode_str[1], "modem", strlen(&mode_str[1])) == 0) { + switch (_tolower(mode_str[0])) { case 'x': mode = MODE_XMODEM; break; @@ -344,33 +356,33 @@ do_load(int argc, char *argv[]) mode = MODE_ZMODEM; break; default: - printf("Invalid 'mode': %s\n", mode_str); + diag_printf("Invalid 'mode': %s\n", mode_str); return; } // When using a serial download type, override verbose // setting: spinner interferes with the protocol. verbose = false; #ifdef CYGPKG_REDBOOT_DISK - } else if (strcmpci(mode_str, "disk") == 0) { + } else if (strcasecmp(mode_str, "disk") == 0) { mode = MODE_DISK; #endif #ifdef CYGPKG_REDBOOT_NETWORKING - } else if (strcmpci(mode_str, "tftp") == 0) { + } else if (strcasecmp(mode_str, "tftp") == 0) { mode = MODE_TFTP; if (!have_net) { - printf("TFTP mode requires a working network\n"); + diag_printf("TFTP mode requires a working network\n"); return; } #endif } else { - printf("Invalid 'mode': %s\n", mode_str); + diag_printf("Invalid 'mode': %s\n", mode_str); return; } } #if defined(CYGPKG_REDBOOT_NETWORKING) || defined(CYGPKG_REDBOOT_DISK) if ((mode == MODE_TFTP || mode == MODE_DISK) && !filename) { - printf("File name missing\n"); - printf("usage: load %s\n", usage); + diag_printf("File name missing\n"); + diag_printf("usage: load %s\n", usage); return; } #endif @@ -383,14 +395,14 @@ do_load(int argc, char *argv[]) } #endif if (raw && !base_addr_set) { - printf("Raw load requires a memory address\n"); + diag_printf("Raw load requires a memory address\n"); return; } #ifdef CYGPKG_REDBOOT_NETWORKING if (mode == MODE_TFTP) { res = tftp_stream_open(filename, &host, TFTP_OCTET, &err); if (res < 0) { - printf("Can't load '%s': %s\n", filename, tftp_error(err)); + diag_printf("Can't load '%s': %s\n", filename, tftp_error(err)); return; } redboot_getc_init(tftp_stream_read, verbose); @@ -400,7 +412,7 @@ do_load(int argc, char *argv[]) else if (mode == MODE_DISK) { res = disk_stream_open(filename, &err); if (res < 0) { - printf("Can't load '%s': %s\n", filename, disk_error(err)); + diag_printf("Can't load '%s': %s\n", filename, disk_error(err)); return; } redboot_getc_init(disk_stream_read, verbose); @@ -409,7 +421,7 @@ do_load(int argc, char *argv[]) else { res = xyzModem_stream_open(filename, mode, &err); if (res < 0) { - printf("Can't load '%s': %s\n", filename, xyzModem_error(err)); + diag_printf("Can't load '%s': %s\n", filename, xyzModem_error(err)); return; } // Suppress verbosity when using xyz modem download @@ -445,7 +457,7 @@ do_load(int argc, char *argv[]) err = (*_dc_close)(p, err); if (0 != err && p->msg) { - printf("decompression error: %s\n", p->msg); + diag_printf("decompression error: %s\n", p->msg); } end = (unsigned long) base + p->out_size; @@ -460,7 +472,7 @@ do_load(int argc, char *argv[]) end = (unsigned long) mp; } if (0 == err) - printf("Raw file loaded %p-%p\n", (void *)base, (void *)end); + diag_printf("Raw file loaded %p-%p\n", (void *)base, (void *)end); } else { // Read initial header - to determine file [image] type for (i = 0; i < sizeof(type); i++) { @@ -477,9 +489,18 @@ do_load(int argc, char *argv[]) end = load_elf_image(redboot_getc); } else if ((type[0] == 'S') && ((type[1] >= '0') && (type[1] <= '9'))) { - end = load_srec_image(redboot_getc, base); + switch (mode) { + case MODE_XMODEM: + case MODE_YMODEM: + case MODE_ZMODEM: + end = load_srec_image(redboot_getc, xyzModem_stream_terminate, base); + break; + default: + end = load_srec_image(redboot_getc, NULL, base); + break; + } } else { - printf("Unrecognized image type: 0x%lx\n", *(unsigned long *)type); + diag_printf("Unrecognized image type: 0x%lx\n", *(unsigned long *)type); } } }
--- a/packages/redboot/current/src/main.c +++ b/packages/redboot/current/src/main.c @@ -144,14 +144,14 @@ do_version(int argc, char *argv[]) externC void _flash_info(void); #endif - printf(RedBoot_version); + diag_printf(RedBoot_version); #ifdef HAL_PLATFORM_CPU - printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA); + diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA); #endif - printf("Copyright (C) 2000, 2001, Red Hat, Inc.\n\n"); - printf("RAM: %p-%p, %p-%p available\n", - (void*)ram_start, (void*)ram_end, - (void*)user_ram_start, (void *)user_ram_end); + diag_printf("Copyright (C) 2000, 2001, Red Hat, Inc.\n\n"); + diag_printf("RAM: %p-%p, %p-%p available\n", + (void*)ram_start, (void*)ram_end, + (void*)user_ram_start, (void *)user_ram_end); #ifdef CYGPKG_IO_FLASH _flash_info(); #endif @@ -168,6 +168,13 @@ do_idle(bool is_idle) } } +// Wrapper used by diag_printf() +static void +_mon_write_char(char c, void **param) +{ + mon_write_char(c); +} + // // This is the main entry point for RedBoot // @@ -182,6 +189,7 @@ cyg_start(void) struct init_tab_entry *init_entry; // Make sure the channels are properly initialized. + diag_init_putc(_mon_write_char); hal_if_diag_init(); // Force console to output raw text - but remember the old setting @@ -248,15 +256,15 @@ cyg_start(void) // Give the guy a chance to abort any boot script unsigned char *hold_script = script; int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION; - printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", - script_timeout_ms/1000, script_timeout_ms%1000); + diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", + script_timeout_ms/1000, script_timeout_ms%1000); script = (unsigned char *)0; res = _GETS_CTRLC; // Treat 0 timeout as ^C while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { - res = gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); + res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res >= _GETS_OK) { - printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", - script_timeout_ms/1000, script_timeout_ms%1000); + diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n", + script_timeout_ms/1000, script_timeout_ms%1000); continue; // Ignore anything but ^C } if (res != _GETS_TIMEOUT) break; @@ -272,10 +280,10 @@ cyg_start(void) while (true) { if (prompt) { - printf("RedBoot> "); + diag_printf("RedBoot> "); prompt = false; } - res = gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); + res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res == _GETS_TIMEOUT) { // No input arrived } else { @@ -311,7 +319,7 @@ cyg_start(void) if ((cmd = parse(line, &argc, &argv[0])) != (struct cmd *)0) { (cmd->fun)(argc, argv); } else { - printf("** Error: Illegal command: \"%s\"\n", argv[0]); + diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]); } } prompt = true; @@ -327,12 +335,12 @@ do_caches(int argc, char *argv[]) int dcache_on=0, icache_on=0; if (argc == 2) { - if (strcmpci(argv[1], "on") == 0) { + if (strcasecmp(argv[1], "on") == 0) { HAL_DISABLE_INTERRUPTS(oldints); HAL_ICACHE_ENABLE(); HAL_DCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); - } else if (strcmpci(argv[1], "off") == 0) { + } else if (strcasecmp(argv[1], "off") == 0) { HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_SYNC(); HAL_ICACHE_DISABLE(); @@ -342,7 +350,7 @@ do_caches(int argc, char *argv[]) HAL_DCACHE_INVALIDATE_ALL(); HAL_RESTORE_INTERRUPTS(oldints); } else { - printf("Invalid cache mode: %s\n", argv[1]); + diag_printf("Invalid cache mode: %s\n", argv[1]); } } else { #ifdef HAL_DCACHE_IS_ENABLED @@ -351,7 +359,8 @@ do_caches(int argc, char *argv[]) #ifdef HAL_ICACHE_IS_ENABLED HAL_ICACHE_IS_ENABLED(icache_on); #endif - printf("Data cache: %s, Instruction cache: %s\n", dcache_on?"On":"Off", icache_on?"On":"Off"); + diag_printf("Data cache: %s, Instruction cache: %s\n", + dcache_on?"On":"Off", icache_on?"On":"Off"); } } @@ -365,7 +374,7 @@ do_help(int argc, char *argv[]) int len = 0; if (!scan_opts(argc, argv, 1, 0, 0, (void **)&which, OPTION_ARG_TYPE_STR, "<topic>")) { - printf("Invalid argument\n"); + diag_printf("Invalid argument\n"); return; } if (which) { @@ -374,11 +383,11 @@ do_help(int argc, char *argv[]) cmd = __RedBoot_CMD_TAB__; while (cmd != &__RedBoot_CMD_TAB_END__) { show = true; - if (which && (strncmpci(which, cmd->str, len) != 0)) { + if (which && (strncasecmp(which, cmd->str, len) != 0)) { show = false; } if (show) { - printf("%s\n %s %s\n", cmd->help, cmd->str, cmd->usage); + diag_printf("%s\n %s %s\n", cmd->help, cmd->str, cmd->usage); } cmd++; } @@ -402,7 +411,7 @@ do_dump(int argc, char *argv[]) } if (!base_set) { if (_base == 0) { - printf("Dump what [location]?\n"); + diag_printf("Dump what [location]?\n"); return; } base = _base; @@ -414,7 +423,7 @@ do_dump(int argc, char *argv[]) if (!len_set) { len = 32; } - dump_buf((void *)base, len); + diag_dump_buf((void *)base, len); _base = base + len; _len = len; } @@ -438,11 +447,11 @@ do_cksum(int argc, char *argv[]) return; } if (!base_set || !len_set) { - printf("usage: cksum -b <addr> -l <length>\n"); + diag_printf("usage: cksum -b <addr> -l <length>\n"); return; } crc = posix_crc32((unsigned char *)base, len); - printf("POSIX cksum = 0x%08lx (%lu)\n", crc, crc); + diag_printf("POSIX cksum = 0x%08lx (%lu)\n", crc, crc); } void @@ -470,10 +479,10 @@ do_go(int argc, char *argv[]) unsigned char *hold_script = script; script = (unsigned char *)0; #endif - printf("About to start execution at %p - abort with ^C within %d seconds\n", - (void *)entry, wait_time); + diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", + (void *)entry, wait_time); while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { - res = gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); + res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res == _GETS_CTRLC) { #ifdef CYGSEM_REDBOOT_FLASH_CONFIG script = hold_script; // Re-enable script @@ -502,11 +511,11 @@ do_go(int argc, char *argv[]) void do_reset(int argc, char *argv[]) { - printf("... Resetting."); + diag_printf("... Resetting."); CYGACC_CALL_IF_DELAY_US(2*100000); - printf("\n"); + diag_printf("\n"); CYGACC_CALL_IF_RESET(); - printf("!! oops, RESET not working on this platform\n"); + diag_printf("!! oops, RESET not working on this platform\n"); } #endif @@ -526,7 +535,7 @@ set_console_baud_rate(int rate) __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SETBAUD, rate); if (ret <= 0) { - printf("Failed\n"); + diag_printf("Failed\n"); } current_rate = rate; } @@ -561,11 +570,11 @@ do_baud_rate(int argc, char *argv[]) set_console_baud_rate(new_rate); } else { ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD); - printf("Baud rate = "); + diag_printf("Baud rate = "); if (ret <= 0) { - printf("unknown\n"); + diag_printf("unknown\n"); } else { - printf("%d\n", ret); + diag_printf("%d\n", ret); } } }
--- a/packages/redboot/current/src/misc_funs.c +++ b/packages/redboot/current/src/misc_funs.c @@ -23,7 +23,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // @@ -46,109 +46,27 @@ #include <redboot.h> int -strlen(const char *s) -{ - int len = 0; - if (s) - while (*s++) len++; - return len; -} - -int -strcmp(const char *s1, const char *s2) +strcasecmp(const char *s1, const char *s2) { char c1, c2; - - while ((c1 = *s1++) == (c2 = *s2++)) - if (c1 == 0) - return (0); - return ((unsigned char)c1 - (unsigned char)c2); -} - -char * -strncpy(char *s1, const char *s2, unsigned long n) -{ - char c; - char *_s1 = s1; - - if (n) { - n--; // leave space for terminator - while (n != 0 && (c = *s2++) != '\0') { - *s1++ = c; - n--; - } - *s1 = '\0'; - while (n != 0) { // fill remainder with zero - *s1++ = 0; - n--; - } - } - return _s1; -} - -char * -strcpy(char *s1, const char *s2) -{ - char c; - char *_s1 = s1; - - while ((c = *s2++) != '\0') - *s1++ = c; - *s1 = '\0'; - return _s1; -} - -int -strcmpci(const char *s1, const char *s2) -{ - char c1, c2; - while ((c1 = tolower(*s1++)) == (c2 = tolower(*s2++))) + while ((c1 = _tolower(*s1++)) == (c2 = _tolower(*s2++))) if (c1 == 0) return (0); return ((unsigned char)c1 - (unsigned char)c2); } int -strncmp(const char *s1, const char *s2, int len) +strncasecmp(const char *s1, const char *s2, size_t len) { char c1, c2; if (len == 0) return 0; do { - if ((c1 = *s1++) != (c2 = *s2++)) + if ((c1 = _tolower(*s1++)) != (c2 = _tolower(*s2++))) return ((unsigned char)c1 - (unsigned char)c2); if (c1 == 0) break; } while (--len != 0); return 0; } - -int -strncmpci(const char *s1, const char *s2, int len) -{ - char c1, c2; - - if (len == 0) - return 0; - do { - if ((c1 = tolower(*s1++)) != (c2 = tolower(*s2++))) - return ((unsigned char)c1 - (unsigned char)c2); - if (c1 == 0) - break; - } while (--len != 0); - return 0; -} - -int -memcmp(const void *_dst, const void *_src, size_t len) -{ - unsigned char *dst = (unsigned char *)_dst; - unsigned char *src = (unsigned char *)_src; - while (len-- > 0) { - if (*dst++ != *src++) { - return (*--dst - *--src); - } - } - return 0; -}
--- a/packages/redboot/current/src/net/enet.c +++ b/packages/redboot/current/src/net/enet.c @@ -95,7 +95,7 @@ pkt_handler_t return (pkt_handler_t)0; } } - printf("** Warning: can't install listener for ethernet type 0x%02x\n", eth_type); + diag_printf("** Warning: can't install listener for ethernet type 0x%02x\n", eth_type); return (pkt_handler_t)0; } @@ -131,7 +131,7 @@ void if ((pkt = __pktbuf_alloc(ETH_MAX_PKTLEN)) == NULL) { if (!was_exhausted) { int old = start_console(); // Force output to standard port - printf("__enet_poll: no more buffers\n"); + diag_printf("__enet_poll: no more buffers\n"); __pktbuf_dump(); was_exhausted = true; end_console(old);
--- a/packages/redboot/current/src/net/inet_addr.c +++ b/packages/redboot/current/src/net/inet_addr.c @@ -60,7 +60,7 @@ inet_aton(char *s, in_addr_t *addr) val = 0; radix = 10; while ((c = *s++) != '\0') { - if (first && (c == '0') && (tolower(*s) == 'x')) { + if (first && (c == '0') && (_tolower(*s) == 'x')) { radix = 16; s++; // Skip over 0x c = *s++; @@ -94,6 +94,6 @@ inet_ntoa(in_addr_t *addr) unsigned char *ap; ap = (unsigned char *)addr; - sprintf(str, "%d.%d.%d.%d", ap[0], ap[1], ap[2], ap[3]); + diag_sprintf(str, "%d.%d.%d.%d", ap[0], ap[1], ap[2], ap[3]); return str; }
--- a/packages/redboot/current/src/net/net_io.c +++ b/packages/redboot/current/src/net/net_io.c @@ -130,10 +130,10 @@ static cyg_bool __tcp_poll(); if (tcp_sock.state == _CLOSE_WAIT) { // This connection is breaking - if (tcp_sock.data_bytes == 0) { + if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) { __tcp_close(&tcp_sock); + return false; } - return false; } if (tcp_sock.state == _CLOSED) { // The connection is gone @@ -147,8 +147,8 @@ static cyg_bool if (show_tcp && (in_buflen > 0)) { int old_console; old_console = start_console(); - printf("%s:%d\n", __FUNCTION__, __LINE__); - dump_buf(in_buf, in_buflen); + diag_printf("%s:%d\n", __FUNCTION__, __LINE__); + diag_dump_buf(in_buf, in_buflen); end_console(old_console); } #endif // DEBUG_TCP @@ -231,7 +231,9 @@ net_io_flush(void) while (out_buflen) { if (tcp_sock.state == _CLOSE_WAIT) { // This connection is tring to close - __tcp_close(&tcp_sock); + // This connection is breaking + if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) + __tcp_close(&tcp_sock); } if (tcp_sock.state == _CLOSED) { // The connection is gone! @@ -242,8 +244,8 @@ net_io_flush(void) if (show_tcp) { int old_console; old_console = start_console(); - printf("%s.%d\n", __FUNCTION__, __LINE__); - dump_buf(out_buf, out_buflen); + diag_printf("%s.%d\n", __FUNCTION__, __LINE__); + diag_dump_buf(out_buf, out_buflen); end_console(old_console); } #endif // SHOW_TCP @@ -290,7 +292,7 @@ net_io_write(void* __ch_data, const cyg_ int old_console; old_console = start_console(); - printf("%s.%d\n", __FUNCTION__, __LINE__); + diag_printf("%s.%d\n", __FUNCTION__, __LINE__); end_console(old_console); #if 0 CYGARC_HAL_SAVE_GP(); @@ -308,7 +310,7 @@ net_io_read(void* __ch_data, cyg_uint8* int old_console; old_console = start_console(); - printf("%s.%d\n", __FUNCTION__, __LINE__); + diag_printf("%s.%d\n", __FUNCTION__, __LINE__); end_console(old_console); #if 0 CYGARC_HAL_SAVE_GP(); @@ -380,11 +382,11 @@ net_io_control(void *__ch_data, __comm_c _timeout = va_arg(ap, cyg_uint32); va_end(ap); - break; + break; } case __COMMCTL_FLUSH_OUTPUT: net_io_flush(); - break; + break; default: break; } @@ -485,7 +487,7 @@ net_io_init(void) __tcp_listen(&tcp_sock, gdb_port); state = tcp_sock.state; #ifdef DEBUG_TCP - printf("show tcp = %p\n", (void *)&show_tcp); + diag_printf("show tcp = %p\n", (void *)&show_tcp); #endif } @@ -546,7 +548,7 @@ net_init(void) if (!use_bootp) { ip_addr_t bootp_my_ip; - char i; + int i; flash_get_config("bootp_my_ip", &bootp_my_ip, CONFIG_IP); if (bootp_my_ip[0] != 0 || bootp_my_ip[1] != 0 || bootp_my_ip[2] != 0 || bootp_my_ip[3] != 0) { @@ -572,7 +574,7 @@ net_init(void) } } if (!__local_enet_sc) { - printf("No network interfaces found\n"); + diag_printf("No network interfaces found\n"); return; } // Initialize the network [if present] @@ -583,9 +585,9 @@ net_init(void) // Is it an unset address, or has it been set to a static addr if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 && __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) { - printf("Can't get BOOTP info - network disabled!\n"); + diag_printf("Can't get BOOTP info - network disabled!\n"); } else { - printf("Can't get BOOTP info, using default IP address\n"); + diag_printf("Can't get BOOTP info, using default IP address\n"); have_net = true; } } @@ -593,17 +595,17 @@ net_init(void) have_net = true; // Assume values in FLASH were OK } if (have_net) { - printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", - __local_enet_sc->dev_name, - __local_enet_addr[0], - __local_enet_addr[1], - __local_enet_addr[2], - __local_enet_addr[3], - __local_enet_addr[4], - __local_enet_addr[5]); + diag_printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", + __local_enet_sc->dev_name, + __local_enet_addr[0], + __local_enet_addr[1], + __local_enet_addr[2], + __local_enet_addr[3], + __local_enet_addr[4], + __local_enet_addr[5]); - printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr)); - printf(", Default server: %s\n", inet_ntoa(&my_bootp_info.bp_siaddr)); + diag_printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr)); + diag_printf(", Default server: %s\n", inet_ntoa(&my_bootp_info.bp_siaddr)); net_io_init(); } }
--- a/packages/redboot/current/src/net/ping.c +++ b/packages/redboot/current/src/net/ping.c @@ -102,14 +102,14 @@ do_ping(int argc, char *argv[]) init_opts(&opts[6], 'r', true, OPTION_ARG_TYPE_NUM, (void **)&rate, (bool *)&rate_set, "<rate> - time between packets"); if (!scan_opts(argc, argv, 1, opts, 7, (void **)0, 0, "")) { - printf("PING - Invalid option specified\n"); + diag_printf("PING - Invalid option specified\n"); return; } // Set defaults; this has to be done _after_ the scan, since it will // have destroyed all values not explicitly set. if (local_ip_addr_set) { if (!inet_aton(local_ip_addr, (in_addr_t *)&local_addr)) { - printf("PING - Invalid IP address: %s\n", local_ip_addr); + diag_printf("PING - Invalid IP address: %s\n", local_ip_addr); return; } } else { @@ -117,15 +117,15 @@ do_ping(int argc, char *argv[]) } if (host_ip_addr_set) { if (!inet_aton(host_ip_addr, (in_addr_t *)&host_addr)) { - printf("PING - Invalid IP address: %s\n", host_ip_addr); + diag_printf("PING - Invalid IP address: %s\n", host_ip_addr); return; } if (__arp_lookup((ip_addr_t *)&host_addr.sin_addr, &dest_ip) < 0) { - printf("PING: Can't find address of server '%s'\n", host_ip_addr); + diag_printf("PING: Can't find address of server '%s'\n", host_ip_addr); return; } } else { - printf("PING - host IP address required\n"); + diag_printf("PING - host IP address required\n"); return; } #define DEFAULT_LENGTH 64 @@ -139,7 +139,7 @@ do_ping(int argc, char *argv[]) length = DEFAULT_LENGTH; } if ((length < 64) || (length > 1400)) { - printf("Invalid length specified: %ld\n", length); + diag_printf("Invalid length specified: %ld\n", length); return; } if (!count_set) { @@ -149,10 +149,10 @@ do_ping(int argc, char *argv[]) timeout = DEFAULT_TIMEOUT; } // Note: two prints here because 'inet_ntoa' returns a static pointer - printf("Network PING - from %s", - inet_ntoa((in_addr_t *)&local_addr)); - printf(" to %s\n", - inet_ntoa((in_addr_t *)&host_addr)); + diag_printf("Network PING - from %s", + inet_ntoa((in_addr_t *)&local_addr)); + diag_printf(" to %s\n", + inet_ntoa((in_addr_t *)&host_addr)); received = 0; __icmp_install_listener(handle_icmp); for (tries = 0; tries < count; tries++) { @@ -203,14 +203,14 @@ do_ping(int argc, char *argv[]) if (icmp_received) { received++; if (verbose) { - printf(" seq: %ld, time: %ld (ticks)\n", - ntohs(hold_hdr.seqnum), end_time-start_time); + diag_printf(" seq: %ld, time: %ld (ticks)\n", + ntohs(hold_hdr.seqnum), end_time-start_time); } } } __icmp_remove_listener(); // Report - printf("PING - received %ld of %ld expected\n", received, count); + diag_printf("PING - received %ld of %ld expected\n", received, count); } #endif //CYGPKG_REDBOOT_NETWORKING
--- a/packages/redboot/current/src/net/pktbuf.c +++ b/packages/redboot/current/src/net/pktbuf.c @@ -90,15 +90,15 @@ void { int i; for (i = 0; i < MAX_PKTBUF; i++) { - printf("Buf[%d]/%p: buf: %p, len: %d/%d, next: %p\n", - i, - (void*)&pktbuf_list[i], - (void*)pktbuf_list[i].buf, - pktbuf_list[i].bufsize, - pktbuf_list[i].pkt_bytes, - (void*)pktbuf_list[i].next); + diag_printf("Buf[%d]/%p: buf: %p, len: %d/%d, next: %p\n", + i, + (void*)&pktbuf_list[i], + (void*)pktbuf_list[i].buf, + pktbuf_list[i].bufsize, + pktbuf_list[i].pkt_bytes, + (void*)pktbuf_list[i].next); } - printf("Free list = %p\n", (void*)free_list); + diag_printf("Free list = %p\n", (void*)free_list); } /*
--- a/packages/redboot/current/src/net/udp.c +++ b/packages/redboot/current/src/net/udp.c @@ -193,7 +193,7 @@ int ip_route_t rt; if (__arp_lookup((ip_addr_t *)&server->sin_addr, &rt) < 0) { - printf("%s: Can't find address of server\n", __FUNCTION__); + diag_printf("%s: Can't find address of server\n", __FUNCTION__); return -1; } else { __udp_send(data, len, &rt, ntohs(server->sin_port), ntohs(local->sin_port)); @@ -223,7 +223,7 @@ static void memcpy(&recvfrom_server->sin_addr, &src_route->ip_addr, sizeof(src_route->ip_addr)); recvfrom_buf = (char *)0; // Tell reader we got a packet } else { - printf("udp_recvfrom - dropped packet of %d bytes\n", len); + diag_printf("udp_recvfrom - dropped packet of %d bytes\n", len); } }
--- a/packages/redboot/current/src/parse.c +++ b/packages/redboot/current/src/parse.c @@ -76,7 +76,7 @@ parse(char *line, int *argc, char **argv if (indx < MAX_ARGV) { argv[indx++] = cp; } else { - printf("Too many arguments - stopped at: '%s'\n", cp); + diag_printf("Too many arguments - stopped at: '%s'\n", cp); } while (*cp) { if (*cp == ' ') { @@ -97,7 +97,7 @@ parse(char *line, int *argc, char **argv *pp++ = *cp++; } if (!*cp) { - printf("Unbalanced string!\n"); + diag_printf("Unbalanced string!\n"); } else { if (pp != cp) *pp = '\0'; *cp++ = '\0'; @@ -124,7 +124,7 @@ cmd_search(struct cmd *tab, struct cmd * cmd_len = strlen(arg); cmd = tab; while (cmd != tabend) { - if (strncmpci(arg, cmd->str, cmd_len) == 0) { + if (strncasecmp(arg, cmd->str, cmd_len) == 0) { if (strlen(cmd->str) > cmd_len) { // Check for ambiguous commands here // Note: If there are commands which are not length-unique @@ -133,18 +133,19 @@ cmd_search(struct cmd *tab, struct cmd * cmd2 = tab; while (cmd2 != tabend) { if ((cmd != cmd2) && - (strncmpci(arg, cmd2->str, cmd_len) == 0)) { + (strncasecmp(arg, cmd2->str, cmd_len) == 0)) { if (first) { - printf("Ambiguous command '%s', choices are: %s", arg, cmd->str); + diag_printf("Ambiguous command '%s', choices are: %s", + arg, cmd->str); first = false; } - printf(" %s", cmd2->str); + diag_printf(" %s", cmd2->str); } cmd2++; } if (!first) { // At least one ambiguity found - fail the lookup - printf("\n"); + diag_printf("\n"); return (struct cmd *)0; } } @@ -159,8 +160,10 @@ void cmd_usage(struct cmd *tab, struct cmd *tabend, char *prefix) { struct cmd *cmd; - printf("Usage:\n"); for (cmd = tab; cmd != tabend; cmd++) { - printf(" %s%s %s\n", prefix, cmd->str, cmd->usage); + + diag_printf("Usage:\n"); + for (cmd = tab; cmd != tabend; cmd++) { + diag_printf(" %s%s %s\n", prefix, cmd->str, cmd->usage); } } @@ -223,7 +226,7 @@ scan_opts(int argc, char *argv[], int fi for (j = 0; j < num_opts; j++, opt++) { if (c == opt->flag) { if (opt->arg_set && *opt->arg_set) { - printf("** Error: %s already specified\n", opt->name); + diag_printf("** Error: %s already specified\n", opt->name); ret = false; } if (opt->takes_arg) { @@ -236,7 +239,8 @@ scan_opts(int argc, char *argv[], int fi switch (opt->arg_type) { case OPTION_ARG_TYPE_NUM: if (!parse_num(s, (unsigned long *)opt->arg, 0, 0)) { - printf("** Error: invalid number '%s' for %s\n", s, opt->name); + diag_printf("** Error: invalid number '%s' for %s\n", + s, opt->name); ret = false; } break; @@ -260,19 +264,20 @@ scan_opts(int argc, char *argv[], int fi } } if (!flag_ok) { - printf("** Error: invalid flag '%c'\n", c); + diag_printf("** Error: invalid flag '%c'\n", c); ret = false; } } else { if (def_arg) { if (def_arg_set) { - printf("** Error: %s already specified\n", def_descr); + diag_printf("** Error: %s already specified\n", def_descr); ret = false; } switch (def_arg_type) { case OPTION_ARG_TYPE_NUM: if (!parse_num(argv[i], (unsigned long *)def_arg, 0, 0)) { - printf("** Error: invalid number '%s' for %s\n", argv[i], def_descr); + diag_printf("** Error: invalid number '%s' for %s\n", + argv[i], def_descr); ret = false; } break; @@ -282,7 +287,7 @@ scan_opts(int argc, char *argv[], int fi } def_arg_set = true; } else { - printf("** Error: no default/non-flag arguments supported\n"); + diag_printf("** Error: no default/non-flag arguments supported\n"); ret = false; } } @@ -304,7 +309,7 @@ parse_num(char *s, unsigned long *val, c while (*s == ' ') s++; while (*s) { - if (first && (s[0] == '0') && (tolower(s[1]) == 'x')) { + if (first && (s[0] == '0') && (_tolower(s[1]) == 'x')) { radix = 16; s += 2; }
deleted file mode 100644 --- a/packages/redboot/current/src/printf.c +++ /dev/null @@ -1,277 +0,0 @@ -//========================================================================== -// -// printf.c -// -// Stand-alone minimal printf support for RedBoot -// -//========================================================================== -//####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, 2001 Red Hat, Inc. -// All Rights Reserved. -// ------------------------------------------- -// -//####COPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas -// Date: 2000-07-14 -// Purpose: -// Description: -// -// This code is part of RedBoot (tm). -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include <stdarg.h> -#include <limits.h> -#include <redboot.h> - -static int -_cvt(unsigned long val, char *buf, long radix, char *digits) -{ - char temp[80]; - char *cp = temp; - int length = 0; - if (val == 0) { - /* Special case */ - *cp++ = '0'; - } else { - while (val) { - *cp++ = digits[val % radix]; - val /= radix; - } - } - while (cp != temp) { - *buf++ = *--cp; - length++; - } - *buf = '\0'; - return (length); -} - -#define is_digit(c) ((c >= '0') && (c <= '9')) - -static int -_vprintf(void (*putc)(char c), char *fmt0, va_list ap) -{ - char buf[32]; - char c, sign, *cp=buf; - int left_prec, right_prec, zero_fill, pad, pad_on_right, islong; - long val; - int res = 0, length = 0; - while ((c = *fmt0++) != '\0') { - if (c == '%') { - c = *fmt0++; - left_prec = right_prec = pad_on_right = islong = 0; - if (c == '-') { - c = *fmt0++; - pad_on_right++; - } - if (c == '0') { - zero_fill = true; - c = *fmt0++; - } else { - zero_fill = false; - } - while (is_digit(c)) { - left_prec = (left_prec * 10) + (c - '0'); - c = *fmt0++; - } - if (c == '.') { - c = *fmt0++; - zero_fill++; - while (is_digit(c)) { - right_prec = (right_prec * 10) + (c - '0'); - c = *fmt0++; - } - } else { - right_prec = left_prec; - } - sign = '\0'; - if (c == 'l') { - // 'long' qualifier - c = *fmt0++; - islong = 1; - } - switch (c) { - case 'p': // Pointer - islong = 1; - (*putc)('0'); - (*putc)('x'); - zero_fill = true; - left_prec = sizeof(unsigned long)*2; - case 'd': - case 'u': - case 'x': - case 'X': - if (islong) - val = va_arg(ap, long); - else - val = va_arg(ap, int); - switch (c) { - case 'd': - if (val < 0) { - sign = '-'; - val = -val; - } - case 'u': - length = _cvt(val, buf, 10, "0123456789"); - break; - case 'p': - case 'x': -#if INT_MAX < LONG_MAX - if (!islong) - val &= (1L << (sizeof(int) * 8)) - 1; -#endif - length = _cvt(val, buf, 16, "0123456789abcdef"); - break; - case 'X': -#if INT_MAX < LONG_MAX - if (!islong) - val &= (1L << (sizeof(int) * 8)) - 1; -#endif - length = _cvt(val, buf, 16, "0123456789ABCDEF"); - break; - } - cp = buf; - break; - case 's': - cp = va_arg(ap, char *); - length = strlen(cp); - break; - case 'c': - c = va_arg(ap, int /*char*/); - (*putc)(c); - res++; - continue; - default: - (*putc)('?'); - res++; - } - pad = left_prec - length; - if (sign != '\0') { - pad--; - } - if (zero_fill) { - c = '0'; - if (sign != '\0') { - (*putc)(sign); - res++; - sign = '\0'; - } - } else { - c = ' '; - } - if (!pad_on_right) { - while (pad-- > 0) { - (*putc)(c); - res++; - } - } - if (sign != '\0') { - (*putc)(sign); - res++; - } - while (length-- > 0) { - c = *cp++; - if (c == '\n') { - (*putc)('\r'); - res++; - } - (*putc)(c); - res++; - } - if (pad_on_right) { - while (pad-- > 0) { - (*putc)(' '); - res++; - } - } - } else { - if (c == '\n') { - (*putc)('\r'); - res++; - } - (*putc)(c); - res++; - } - } - return (res); -} - -static char *_sprintf_ptr; - -static void -_sputc(char c) -{ - *_sprintf_ptr++ = c; - *_sprintf_ptr = '\0'; -} - -int -sprintf(char *buf, char *fmt, ...) -{ - int ret; - va_list ap; - - va_start(ap, fmt); - _sprintf_ptr = buf; - ret = _vprintf(_sputc, fmt, ap); - va_end(ap); - return (ret); -} - -int -vsprintf(char *buf, char *fmt, va_list ap) -{ - int ret; - - _sprintf_ptr = buf; - ret = _vprintf(_sputc, fmt, ap); - return (ret); -} - -extern void mon_write_char(char); - -int -printf(char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = _vprintf(mon_write_char, fmt, ap); - va_end(ap); - return (ret); -} - -int -vprintf(char *fmt, va_list ap) -{ - int ret; - - ret = _vprintf(mon_write_char, fmt, ap); - return (ret); -} -
--- a/packages/redboot/current/src/syscall.c +++ b/packages/redboot/current/src/syscall.c @@ -23,7 +23,7 @@ // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 2000 Red Hat, Inc. +// Copyright (C) 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // @@ -41,35 +41,37 @@ //=========================================================================*/ #include <redboot.h> +#include <cyg/hal/hal_intr.h> +#include <cyg/hal/drv_api.h> #ifdef CYGSEM_REDBOOT_BSP_SYSCALLS -#define EIO 5 /* I/O error */ +#define EIO 5 /* I/O error */ // These are required by the ANSI C part of newlib (excluding system() of // course). -#define SYS_exit 1 -#define SYS_open 2 -#define SYS_close 3 -#define SYS_read 4 -#define SYS_write 5 -#define SYS_lseek 6 -#define SYS_unlink 7 -#define SYS_getpid 8 -#define SYS_kill 9 +#define SYS_exit 1 +#define SYS_open 2 +#define SYS_close 3 +#define SYS_read 4 +#define SYS_write 5 +#define SYS_lseek 6 +#define SYS_unlink 7 +#define SYS_getpid 8 +#define SYS_kill 9 #define SYS_fstat 10 -//#define SYS_sbrk 11 - not currently a system call, but reserved. +//#define SYS_sbrk 11 - not currently a system call, but reserved. // ARGV support. -#define SYS_argvlen 12 -#define SYS_argv 13 +#define SYS_argvlen 12 +#define SYS_argv 13 // These are extras added for one reason or another. -#define SYS_chdir 14 -#define SYS_stat 15 -#define SYS_chmod 16 -#define SYS_utime 17 -#define SYS_time 18 +#define SYS_chdir 14 +#define SYS_stat 15 +#define SYS_chmod 16 +#define SYS_utime 17 +#define SYS_time 18 #define SYS_interrupt 1000 #define SYS_meminfo 1001 @@ -84,7 +86,7 @@ * is made automatically from within the crt0.o file. */ typedef struct { - int version; /* version number for future expansion */ + int version; /* version number for future expansion */ const void **__ictrl_table; void **__exc_table; void *__dbg_vector; @@ -96,8 +98,8 @@ typedef struct { void *__cpu_data; void *__board_data; void *__sysinfo; - int (*__set_debug_comm)(int __comm_id); - int (*__set_console_comm)(int __comm_id); + int (*__set_debug_comm)(int __comm_id); + int (*__set_console_comm)(int __comm_id); int (*__set_serial_baud)(int __comm_id, int baud); void *__dbg_data; void (*__reset)(void); @@ -124,14 +126,59 @@ static inline void __putc(char c) { hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); if (__chan) - CYGACC_COMM_IF_PUTC(*__chan, c); + CYGACC_COMM_IF_PUTC(*__chan, c); else { - __chan = CYGACC_CALL_IF_DEBUG_PROCS(); - CYGACC_COMM_IF_PUTC(*__chan, c); + __chan = CYGACC_CALL_IF_DEBUG_PROCS(); + CYGACC_COMM_IF_PUTC(*__chan, c); } } +// Timer support + +static cyg_handle_t sys_timer_handle; +static cyg_interrupt sys_timer_interrupt; +static cyg_uint32 sys_timer_ticks; + +static void +sys_timer_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + // do nothing +} + + +static cyg_uint32 +sys_timer_isr(cyg_vector_t vector, cyg_addrword_t data) +{ + ++sys_timer_ticks; + + HAL_CLOCK_RESET(CYGNUM_HAL_INTERRUPT_RTC, CYGNUM_HAL_RTC_PERIOD); + + cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_RTC); + + return 0; +} + + +static void sys_timer_init(void) +{ + HAL_CLOCK_INITIALIZE(CYGNUM_HAL_RTC_PERIOD); + + cyg_drv_interrupt_create( + CYGNUM_HAL_INTERRUPT_RTC, + 0, // Priority - unused + (CYG_ADDRWORD)0, // Data item passed to ISR & DSR + sys_timer_isr, // ISR + sys_timer_dsr, // DSR + &sys_timer_handle, // handle to intr obj + &sys_timer_interrupt ); // space for int obj + + cyg_drv_interrupt_attach(sys_timer_handle); + + cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_RTC); +} + + // // read -- read bytes from the serial port. Ignore fd, since // we only have stdin. @@ -141,11 +188,11 @@ sys_read(int fd, char *buf, int nbytes) int i = 0; for (i = 0; i < nbytes; i++) { - *(buf + i) = __getc(); - if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { - (*(buf + i + 1)) = 0; - break; - } + *(buf + i) = __getc(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + (*(buf + i + 1)) = 0; + break; + } } return (i); } @@ -165,10 +212,10 @@ sys_write(int fd, char *buf, int nbytes) tosend = nbytes; while (tosend > 0) { - if (*buf == '\n') - __putc('\r'); - __putc(*buf++); - tosend--; + if (*buf == '\n') + __putc('\r'); + __putc(*buf++); + tosend--; } return (nbytes); @@ -205,24 +252,29 @@ sys_lseek(int fd, int offset, int whenc return (-EIO); } +#define NS_PER_TICK (CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR) +#define TICKS_PER_SEC (1000000000L / NS_PER_TICK) + +// This needs to match newlib HZ which is normally 60. +#define HZ 60 static int sys_utime(unsigned long *p) { -#ifdef HAVE_SYS_CLOCK - extern unsigned long __clock; + static int inited = 0; + + if (!inited) { + inited = 1; + sys_timer_init(); + } /* target clock runs at CLOCKS_PER_SEC. Convert to HZ */ if (p) - *p = (__clock * HZ) / CLOCKS_PER_SEC; -#else - if (p) - *p = 0; -#endif + *p = (sys_timer_ticks * HZ) / TICKS_PER_SEC; + return 0; } - // // Generic syscall handler. // @@ -231,38 +283,38 @@ sys_utime(unsigned long *p) // extend the syscall handler by using exception chaining. // CYG_ADDRWORD -__do_syscall(CYG_ADDRWORD func, // syscall function number - CYG_ADDRWORD arg1, CYG_ADDRWORD arg2, // up to four args. - CYG_ADDRWORD arg3, CYG_ADDRWORD arg4, - CYG_ADDRWORD *retval) // syscall return value +__do_syscall(CYG_ADDRWORD func, // syscall function number + CYG_ADDRWORD arg1, CYG_ADDRWORD arg2, // up to four args. + CYG_ADDRWORD arg3, CYG_ADDRWORD arg4, + CYG_ADDRWORD *retval) // syscall return value { int err = 0; switch (func) { case SYS_read: - err = sys_read((int)arg1, (char *)arg2, (int)arg3); - break; + err = sys_read((int)arg1, (char *)arg2, (int)arg3); + break; case SYS_write: - err = sys_write((int)arg1, (char *)arg2, (int)arg3); - break; + err = sys_write((int)arg1, (char *)arg2, (int)arg3); + break; case SYS_open: - err = sys_open((const char *)arg1, (int)arg2, (int)arg3); - break; + err = sys_open((const char *)arg1, (int)arg2, (int)arg3); + break; case SYS_close: - err = sys_close((int)arg1); - break; + err = sys_close((int)arg1); + break; case SYS_lseek: - err = sys_lseek((int)arg1, (int)arg2, (int)arg3); - break; + err = sys_lseek((int)arg1, (int)arg2, (int)arg3); + break; case SYS_utime: - err = sys_utime((unsigned long *)arg1); - break; + err = sys_utime((unsigned long *)arg1); + break; case SYS_meminfo: err = 1; @@ -271,11 +323,11 @@ CYG_ADDRWORD break; case __GET_SHARED: - *(__shared_t **)arg1 = &__shared_data; - break; + *(__shared_t **)arg1 = &__shared_data; + break; default: - return 0; + return 0; } *retval = err;
--- a/packages/redboot/current/src/xyzModem.c +++ b/packages/redboot/current/src/xyzModem.c @@ -32,7 +32,7 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): gthomas -// Contributors: gthomas +// Contributors: gthomas, tsmith // Date: 2000-07-14 // Purpose: // Description: @@ -53,6 +53,7 @@ #define STX 0x02 #define EOT 0x04 #define ACK 0x06 +#define BSP 0x08 #define NAK 0x15 #define CAN 0x18 @@ -88,7 +89,7 @@ zm_dprintf(char *fmt, ...) va_start(args, fmt); cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); CYGACC_CALL_IF_SET_CONSOLE_COMM(1); - vprintf(fmt, args); + diag_vprintf(fmt, args); CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console); } @@ -111,7 +112,7 @@ zm_dprintf(char *fmt, ...) va_list args; va_start(args, fmt); - len = vsprintf(zm_out, fmt, args); + len = diag_vsprintf(zm_out, fmt, args); zm_out += len; return len; } @@ -300,7 +301,7 @@ xyzModem_stream_open(char *filename, int int retries = xyzModem_MAX_RETRIES; int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; - ZM_DEBUG(zm_out = zm_out_start); +// ZM_DEBUG(zm_out = zm_out_start); if (mode == xyzModem_zmodem) { *err = xyzModem_noZmodem; return -1; @@ -385,9 +386,10 @@ xyzModem_stream_read(char *buf, int size if (xyz.mode == xyzModem_ymodem) { CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); xyz.total_retries++; + ZM_DEBUG(zm_dprintf("Reading Final Header\n")); stat = xyzModem_get_hdr(); CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK); - ZM_DEBUG(zm_dprintf("ACK (%d)\n", __LINE__)); + ZM_DEBUG(zm_dprintf("FINAL ACK (%d)\n", __LINE__)); } xyz.at_eof = true; break; @@ -417,13 +419,61 @@ xyzModem_stream_read(char *buf, int size void xyzModem_stream_close(int *err) { - printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", - xyz.crc_mode ? "CRC" : "Cksum", - xyz.total_SOH, xyz.total_STX, xyz.total_CAN, - xyz.total_retries); + diag_printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n", + xyz.crc_mode ? "CRC" : "Cksum", + xyz.total_SOH, xyz.total_STX, xyz.total_CAN, + xyz.total_retries); // ZM_DEBUG(zm_flush()); } +// Need to be able to clean out the input buffer, so have to take the +// getc +void xyzModem_stream_terminate(int method, int (*getc)(void)) +{ + int c; + + switch (method) { + case xyzModem_abort: + ZM_DEBUG(zm_dprintf("!!!! TRANSFER ABORT !!!!\n")); + switch (xyz.mode) { + case xyzModem_xmodem: + case xyzModem_ymodem: + // The X/YMODEM Spec seems to suggest that multiple CAN followed by an equal + // number of Backspaces is a friendly way to get the other end to abort. + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN); + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP); + // Now consume the rest of what's waiting on the line. + ZM_DEBUG(zm_dprintf("Flushing serial line.\n")); + xyzModem_flush(); + xyz.at_eof = true; + break; + case xyzModem_zmodem: + // Might support it some day I suppose. + break; + } + default: + ZM_DEBUG(zm_dprintf("Engaging cleanup mode...\n")); + // Consume any trailing crap left in the inbuffer from + // previous recieved blocks. Since very few files are an exact multiple + // of the transfer block size, there will almost always be some gunk here. + // If we don't eat it now, RedBoot will think the user typed it. + ZM_DEBUG(zm_dprintf("Trailing gunk:\n")); + while ((c = (*getc)()) > -1) ; + ZM_DEBUG(zm_dprintf("\n")); + // Make a small delay to give terminal programs like minicom + // time to get control again after their file transfer program + // exits. + CYGACC_CALL_IF_DELAY_US((cyg_int32)100000); + break; + } +} + char * xyzModem_error(int err) {
--- a/packages/redboot/current/src/xyzModem.h +++ b/packages/redboot/current/src/xyzModem.h @@ -59,8 +59,12 @@ #define xyzModem_cksum -7 #define xyzModem_sequence -8 +#define xyzModem_close 1 +#define xyzModem_abort 2 + int xyzModem_stream_open(char *filename, int mode, int *err); void xyzModem_stream_close(int *err); +void xyzModem_stream_terminate(int method, int (*getc)(void)); int xyzModem_stream_read(char *buf, int size, int *err); char *xyzModem_error(int err);
--- a/packages/templates/redboot/ChangeLog +++ b/packages/templates/redboot/ChangeLog @@ -1,3 +1,11 @@ +2001-09-04 Jonathan Larmour <jlarmour@redhat.com> + + * current.ect: Silence warnings when selecting redboot template. + +2001-08-22 Gary Thomas <gthomas@redhat.com> + + * current.ect: Include STDC string functions. + 2001-06-25 Jonathan Larmour <jlarmour@redhat.com> * current.ect: Increase default interrupt stack size up to 6K @@ -43,7 +51,7 @@ 2000-07-12 Gary Thomas <gthomas@redhat // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are -// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- //
--- a/packages/templates/redboot/current.ect +++ b/packages/templates/redboot/current.ect @@ -13,6 +13,8 @@ This is the RedBoot configuration, used package CYGPKG_HAL current ; package CYGPKG_INFRA current ; package CYGPKG_REDBOOT current ; + package CYGPKG_ISOINFRA current ; + package CYGPKG_LIBC_STRING current ; }; cdl_option CYGBLD_BUILD_REDBOOT { @@ -26,3 +28,20 @@ cdl_option CYGDBG_HAL_COMMON_INTERRUPTS_ cdl_option CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE { user_value 6144 }; + +cdl_option CYGBLD_ISO_STRTOK_R_HEADER { + inferred_value 1 <cyg/libc/string/string.h> +}; + +cdl_option CYGBLD_ISO_STRING_LOCALE_FUNCS_HEADER { + inferred_value 1 <cyg/libc/string/string.h> +}; + +cdl_option CYGBLD_ISO_STRING_MEMFUNCS_HEADER { + inferred_value 1 <cyg/libc/string/string.h> +}; + +cdl_option CYGBLD_ISO_STRING_STRFUNCS_HEADER { + inferred_value 1 <cyg/libc/string/string.h> +}; +
