Commit 2801106b authored by Aurelio Colosimo's avatar Aurelio Colosimo

code fromt ptp-proposal version 56d97349

code was pruned from specific "ptp-proposal" protocol and the
skeleton of IEEE-1588 states was made. Next step is to insert,
step by step, the structs defined in ptpd. Still something needs
to be removed or renamed, but this should be a fair starting point.
parents
*.map*
*.o
*.a
pproto.bin
*.patch
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes a de-facto standard. To achieve this, non-free programs must
be allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least
three years, to give the same user the materials specified in
Subsection 6a, above, for a charge no more than the cost of
performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).
To apply these terms, attach the following notices to the library.
It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the library,
if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James
Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
#!/bin/sh
# This trivially compiles all known-good configurations
function build_one () {
make -s clean
echo "####################"
echo "Build for " "$1"
make -s -k $2
test -f pproto.o && size pproto.o
test -f pproto && size pproto
}
function build_diags () {
build_one "arch \"$ARCH\", ext \"$PROTO_EXT\", no diag"
build_one "arch \"$ARCH\", ext \"$PROTO_EXT\", mini diag" HAS_DIAG=y
build_one "arch \"$ARCH\", ext \"$PROTO_EXT\", full diag" HAS_FULL_DIAG=y
}
function build_ext () {
unset PROTO_EXT
build_diags
#export PROTO_EXT=one
#build_diags
}
for var in HAS_DIAG HAS_FULL_DIAG CROSS_COMPILE ARCH; do
unset $var
done
# Build for default ARCH first
unset ARCH
build_ext
# Finally, loop over all archs, using our local names for compilers
PREFIX_bare_linux=""
PREFIX_spec="/opt/gcc-lm32/bin/lm32-elf-"
for a in bare-linux spec; do
export ARCH=$a
ARCH_=""
eval export CROSS_COMPILE="\${PREFIX_$(echo $ARCH | sed 's/-/_/g')}"
build_ext
done
#
# Alessandro Rubini for CERN, 2011 -- public domain
#
# classic cross-compilation tool-set
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
# Instead of repeating "proto-daemon" over and over, bless it TARGET
TARGET = pproto
# The main target is the big object file.
all: $(TARGET).o
# CFLAGS to use. Both this Makefile (later) and app-makefile may grow CFLAGS
CFLAGS += -Wall -O2 -ggdb -Iinclude
# to avoid ifdef as much as possible, I use the kernel trick for OBJ variables
OBJ-y := state-machine.o
# include diagnostic objects
include diag/Makefile
# proto-standard is always included
include proto-standard/Makefile
# including the extension Makefile, if an extension is there
ifdef PROTO_EXT
include proto-ext-$(PROTO_EXT)/Makefile
endif
# Include arch code, the default is hosted GNU/Linux stuff
# we need this -I so <arch/endianness.h> can be found
ARCH ?= gnu-linux
CFLAGS += -Iarch-$(ARCH)/include
include arch-$(ARCH)/Makefile
# And this is the rule to build our target.o file. The architecture may
# build more stuff. Please note that ./MAKEALL looks for $(TARGET)
# (i.e., the ELF which is either the output or the input to objcopy -O binary)
#
# The object only depends on OBJ-y because each subdirs added needed
# libraries: see proto-standard/Makefile as an example.
$(TARGET).o: $(OBJ-y)
$(LD) -Map $(TARGET).map1 -r -o $@ $(OBJ-y) $(LIBS)
# Finally, "make clean" is expected to work
clean:
rm -f $$(find . -name '*.[oa]') *.bin $(TARGET) *~ $(TARGET).map*
# Alessandro Rubini for CERN, 2011 -- public domain
CFLAGS += -ffreestanding -Os
ARCH_LDFLAGS = -nostdlib -static -T $(ARCH).lds
# All files are under A (short for ARCH): I'm lazy
A := arch-$(ARCH)
LIBARCH := $A/libarch.a
OBJ-libarch := $A/bare-startup.o \
$A/main-loop.o \
$A/bare-socket.o \
$A/bare-io.o \
$A/syscalls.o
$(LIBARCH): $(OBJ-libarch)
$(AR) r $@ $^
all: $(TARGET)
# to build the target, we need -lstd again, in case we call functions that
# were not selected yet (e.g., pp_open_instance() ).
$(TARGET): $(TARGET).o $A/crt0.o $(LIBARCH)
$(CC) -Wl,-Map,$(TARGET).map2 $(ARCH_LDFLAGS) -o $@ $A/crt0.o \
$(TARGET).o -L$A -larch -L$D -lstd
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
#include <pproto/pproto.h>
#include "bare-linux.h"
void pp_puts(const char *s)
{
sys_write(0, s, pp_strnlen(s, 300));
}
int pp_strnlen(const char *s, int maxlen)
{
int len = 0;
while (*(s++)) len++;
return len;
}
void *pp_memcpy(void * dest, const void *src, int count)
{
/* from u-boot-1.1.2 */
char *tmp = (char *) dest, *s = (char *) src;
while (count--)
*tmp++ = *s++;
return dest;
}
void pp_get_stamp(uint32_t *sptr)
{
*sptr = htonl(sys_time(0));
}
/* What follows has no prefix because it's only used by arch code */
char *strcpy(char *dest, const char *src)
{
/* from u-boot-1.1.2 */
char *tmp = dest;
while ((*dest++ = *src++) != '\0')
/* nothing */;
return tmp;
}
void *memset(void *s, int c, int count)
{
/* from u-boot-1.1.2 */
char *xs = (char *) s;
while (count--)
*xs++ = c;
return s;
}
void *memcpy(void *dest, const void *src, int count)
{
/* from u-boot-1.1.2 */
char *tmp = (char *) dest, *s = (char *) src;
while (count--)
*tmp++ = *s++;
return dest;
}
/*
* Alessandro Rubini for CERN, 2011 -- GNU LGPL v2.1 or later
*/
/*
* These are the functions provided by the various bare files
*/
extern int bare_open_ch(struct pp_instance *ppi, char *name);
extern int bare_recv_packet(struct pp_instance *ppi, void *pkt, int len);
extern int bare_send_packet(struct pp_instance *ppi, void *pkt, int len);
extern void bare_main_loop(struct pp_instance *ppi);
/* basics */
extern void *memset(void *s, int c, int count);
extern char *strcpy(char *dest, const char *src);
extern void *memcpy(void *dest, const void *src, int count);
/* syscalls */
struct bare_sockaddr;
extern int sys_write(int fd, const void *buf, int count);
extern void sys_exit(int exitval);
extern int sys_time(int tz);
extern int sys_select(int max, void *in, void *out, void *exc, void *tout);
extern int sys_ioctl(int fd, int cmd, void *arg);
extern int sys_socket(int domain, int type, int proto);
extern int sys_bind(int fd, const struct bare_sockaddr *addr, int addrlen);
extern int sys_recv(int fd, void *pkt, int plen, int flags);
extern int sys_send(int fd, void *pkt, int plen, int flags);
extern int bare_errno;
/* structures passed to syscalls */
#define IFNAMSIZ 16
struct bare_sockaddr {
uint16_t sa_family; /* address family, AF_xxx */
char sa_data[14]; /* 14 bytes of protocol address */
};
struct bare_ifreq {
union
{
char ifrn_name[IFNAMSIZ];
} ifr_ifrn;
union {
struct bare_sockaddr ifru_hwaddr;
int index;
} ifr_ifru;
};
struct bare_sockaddr_ll {
unsigned short int sll_family;
unsigned short int sll_protocol;
int sll_ifindex;
unsigned short int sll_hatype;
unsigned char sll_pkttype;
unsigned char sll_halen;
unsigned char sll_addr[8];
};
#define SIOCGIFINDEX 0x8933
#define SIOCGIFHWADDR 0x8927
/* other network stuff, bah.... */
struct bare_ethhdr {
unsigned char h_dest[6];
unsigned char h_source[6];
uint16_t h_proto;
} __attribute__((packed));
OUTPUT_FORMAT("elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_pproto_start)
SECTIONS
{
. = 0x10000000; /* A random address, non-standard by choice*/
_pproto_start = .;
.text : {
*(.boot)
*(.text)
}
.rodata : { *(.rodata) }
.data : { *(.data) }
.bss : {
. = ALIGN(16);
__bss_start = .;
*(.bss);
. = ALIGN(16);
__bss_end = .;
}
}
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
/* Socket interface for bare Linux */
#include <pproto/pproto.h>
#include "bare-linux.h"
/* Receive and send is trivial */
int bare_recv_packet(struct pp_instance *ppi, void *pkt, int len)
{
return sys_recv(ppi->ch.fd, pkt, len, 0);
}
int bare_send_packet(struct pp_instance *ppi, void *pkt, int len)
{
return sys_send(ppi->ch.fd, pkt, len, 0);
}
int pp_recv_packet(struct pp_instance *ppi, void *pkt, int len)
__attribute__((alias("bare_recv_packet")));
int pp_send_packet(struct pp_instance *ppi, void *pkt, int len)
__attribute__((alias("bare_send_packet")));
#define PF_PACKET 17
#define SOCK_RAW 3
/* To open a channel we must bind to an interface and so on */
int bare_open_ch(struct pp_instance *ppi, char *ifname)
{
int sock, iindex;
struct bare_ifreq ifr;
struct bare_sockaddr_ll addr;
/* open socket */
sock = sys_socket(PF_PACKET, SOCK_RAW, PP_PROTO_NR);
if (sock < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "socket()", "");
}
/* hw interface information */
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_ifrn.ifrn_name, ifname);
if (sys_ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "ioctl(GIFINDEX)", "");
}
iindex = ifr.ifr_ifru.index;
if (sys_ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "ioctl(GIFHWADDR)", "");
}
memcpy(ppi->ch.addr, ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
/* bind and setsockopt */
memset(&addr, 0, sizeof(addr));
addr.sll_family = PF_PACKET;
addr.sll_protocol = htons(PP_PROTO_NR);
addr.sll_ifindex = iindex;
if (sys_bind(sock, (struct bare_sockaddr *)&addr, sizeof(addr)) < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "bind", "");
}
ppi->ch.fd = sock;
return 0;
}
/*
* Alessandro Rubini for CERN, 2011 -- GNU LGPL v2.1 or later
*/
/*
* This is the startup thing for "freestanding" stuff under Linux.
* It must also clear the BSS as I'm too lazy to do that in asm
*/
#include <pproto/pproto.h>
#include "bare-linux.h"
extern int __bss_start, __bss_end;
void pproto_clear_bss(void)
{
int *ptr;
for (ptr = &__bss_start; ptr < &__bss_end; ptr++)
*ptr = 0;
}
static struct pp_instance ppi_static;
void pproto_main(void)
{
struct pp_instance *ppi = &ppi_static; /* no malloc, one instance */
pp_puts("bare: starting. Compiled on " __DATE__ "\n");
if (bare_open_ch(ppi, "eth0")) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "open_ch", "");
}
pp_open_instance(ppi,0);
bare_main_loop(ppi);
}
/*
* A stupid crt0.S for "freestanding" stuff on gnu/linux
* Alessandro Rubini for CERN, 2011 -- GNU GPL v2 or later
*/
.section .boot, "ax"
.extern pproto_main
call pproto_clear_bss /* In C, lazy me */
call pproto_main
.end
\ No newline at end of file
#ifndef __ARCH_H__
#define __ARCH_H__
/* Architecture-specific defines, included by top-level stuff */
/* please note that these have multiple evaluation of the argument */
#define htons(x) __bswap_16(x)
#define __bswap_16(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
#define htonl(x) __bswap_32(x)
#define __bswap_32(x) ( \
(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
(((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24))
#define ntohs htons
#define ntohl htonl
#endif /* __ARCH_H__ */
/*
* Alessandro Rubini for CERN, 2011 -- GNU LGPL v2.1 or later
*/
/*
* This is the main loop for "freestanding" stuff under Linux.
*/
#include <pproto/pproto.h>
#include "bare-linux.h"
/* Define other hackish stuff */
typedef struct {unsigned long bits[1024/32];} bare_fd_set;
#define FD_ZERO(p) memset(p, 0, sizeof(p))
#define FD_SET(bit, p) ((p)->bits[0] |= (1 << (bit)))
struct bare_timeval {unsigned long tv_sec; unsigned long tv_usec;};
#define NULL 0
void bare_main_loop(struct pp_instance *ppi)
{
int delay_ms;
/*
* The main loop here is based on select. While we are not
* doing anything else but the protocol, this allows extra stuff
* to fit.
*/
delay_ms = pp_state_machine(ppi, NULL, 0);
while (1) {
bare_fd_set set;
int i;
struct bare_timeval tv;
unsigned char packet[1500];
/* Wait for a packet or for the timeout */
tv.tv_sec = delay_ms / 1000;
tv.tv_usec = (delay_ms % 1000) * 1000;
again:
FD_ZERO(&set);
FD_SET(ppi->ch.fd, &set);
i = sys_select(ppi->ch.fd + 1, &set, NULL, NULL, &tv);
if (i < 0 && bare_errno != 4 /* EINTR */)
sys_exit(__LINE__);
if (i < 0)
continue;
if (i == 0) {
delay_ms = pp_state_machine(ppi, NULL, 0);
continue;
}
/*
* We got a packet. If it's not ours, continue consuming
* the pending timeout
*/
i = bare_recv_packet(ppi, packet, sizeof(packet));
/* FIXME
if (i < sizeof(struct pp_packet))
goto again;
*/
/* Warning: PP_PROTO_NR is endian-agnostic by design */
if ( ((struct bare_ethhdr *)packet)->h_proto
!= htons(PP_PROTO_NR))
goto again;
delay_ms = pp_state_machine(ppi, packet, i);
}
}
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
#include <asm/unistd.h>
#include <pproto/pproto.h>
#include "bare-linux.h"
#include "syscalls.h"
int bare_errno;
struct sel_arg_struct {
unsigned long n;
void *inp, *outp, *exp;
void *tvp;
};
/*
* The following lines use defines from Torvalds (linux-2.4.0: see syscalls.h)
*/
_syscall3(int, write, int, fd, const void *, buf, int, count)
_syscall1(int, exit, int, exitcode)
_syscall1(int, time, void *, tz)
_syscall3(int, ioctl, int, fd, int, cmd, void *, arg)
_syscall1(int, select, struct sel_arg_struct *, as)
static _syscall2(int, socketcall, int, call, unsigned long *, args)
/*
* In the bare arch I'd better use sys_ prefixed names
*/
int sys_write(int fd, const void *buf, int count)
__attribute__((alias("write")));
void sys_exit(int exitval)
__attribute__((alias("exit")));
int sys_time(int tz)
__attribute__((alias("time")));
int sys_ioctl(int fd, int cmd, void *arg)
__attribute__((alias("ioctl")));
static struct sel_arg_struct as; /* declared as local, it won't work */
int sys_select(int max, void *in, void *out, void *exc, void *tout)
{
as.n = max;
as.inp = in;
as.outp = out;
as.exp = exc;
as.tvp = tout;
return select(&as);
}
/* i386 has the socketcall thing. Bah! */
#define SYS_SOCKET 1 /* sys_socket(2) */
#define SYS_BIND 2 /* sys_bind(2) */
#define SYS_CONNECT 3 /* sys_connect(2) */
#define SYS_LISTEN 4 /* sys_listen(2) */
#define SYS_ACCEPT 5 /* sys_accept(2) */
#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */
#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */
#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */
#define SYS_SEND 9 /* sys_send(2) */
#define SYS_RECV 10 /* sys_recv(2) */
#define SYS_SENDTO 11 /* sys_sendto(2) */
#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
#define SYS_PACCEPT 18 /* sys_paccept(2) */
static unsigned long args[4];
int sys_socket(int domain, int type, int proto)
{
/*
* Strangely, this is not working for me:
* unsigned long args[3] = {domain, type, proto};
* So let's use an external thing. Who knows why...
*/
args[0] = domain;
args[1] = type;
args[2] = proto;
return socketcall(SYS_SOCKET, args);
}
int sys_bind(int fd, const struct bare_sockaddr *addr, int addrlen)
{
args[0] = fd;
args[1] = (unsigned long)addr;
args[2] = addrlen;
return socketcall(SYS_BIND, args);
}
int sys_recv(int fd, void *pkt, int plen, int flags)
{
args[0] = fd;
args[1] = (unsigned long)pkt;
args[2] = plen;
args[3] = flags;
return socketcall(SYS_RECV, args);
}
int sys_send(int fd, void *pkt, int plen, int flags)
{
args[0] = fd;
args[1] = (unsigned long)pkt;
args[2] = plen;
args[3] = flags;
return socketcall(SYS_SEND, args);
}
/*
* From: linux-2.4.0::include/asm-i386/unistd.h
*/
extern int bare_errno;
/*
* user-visible error numbers are in the range -1 - -4096
*/
#define __syscall_return(type, res) \
do { \
if ((unsigned long)(res) >= (unsigned long)(-4096)) { \
bare_errno = -(res); \
res = -1; \
} \
return (type) (res); \
} while (0)
/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name)); \
__syscall_return(type,__res); \
}
#define _syscall1(type,name,type1,arg1) \
type name(type1 arg1) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(arg1))); \
__syscall_return(type,__res); \
}
#define _syscall2(type,name,type1,arg1,type2,arg2) \
type name(type1 arg1,type2 arg2) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
__syscall_return(type,__res); \
}
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
type name(type1 arg1,type2 arg2,type3 arg3) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
"d" ((long)(arg3))); \
__syscall_return(type,__res); \
}
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
"d" ((long)(arg3)),"S" ((long)(arg4))); \
__syscall_return(type,__res); \
}
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
type5,arg5) \
type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
: "=a" (__res) \
: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
"d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
__syscall_return(type,__res); \
}
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
type5,arg5,type6,arg6) \
type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
{ \
long __res; \
__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" \
: "=a" (__res) \
: "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
"d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
"0" ((long)(arg6))); \
__syscall_return(type,__res); \
}
# Alessandro Rubini for CERN, 2011 -- public domain
# All files are under A (short for ARCH): I'm lazy
A := arch-$(ARCH)
LIBARCH := $A/libarch.a
OBJ-libarch := $A/posix-startup.o \
$A/main-loop.o \
$A/posix-socket.o \
$A/posix-io.o
$(LIBARCH): $(OBJ-libarch)
$(AR) r $@ $^
all: $(TARGET)
# to build the target, we need -lstd again, in case we call functions that
# were not selected yet (e.g., pp_open_instance() ).
$(TARGET): $(TARGET).o $(LIBARCH)
$(CC) -Wl,-Map,$(TARGET).map2 -o $@ $(TARGET).o \
-L$A -larch -L$D -lstd
#ifndef __ARCH_H__
#define __ARCH_H__
/* Architecture-specific defines, included by top-level stuff */
#include <arpa/inet.h> /* ntohs etc */
#endif /* __ARCH_H__ */
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
/*
* This is the main loop for posix stuff.
*/
#include <stdlib.h>
#include <errno.h>
#include <sys/select.h>
#include <linux/if_ether.h>
#include <pproto/pproto.h>
#include <pproto/diag.h>
#include "posix.h"
void posix_main_loop(struct pp_instance *ppi)
{
int delay_ms;
/*
* The main loop here is based on select. While we are not
* doing anything else but the protocol, this allows extra stuff
* to fit.
*/
delay_ms = pp_state_machine(ppi, NULL, 0);
while (1) {
fd_set set;
int i;
struct timeval tv;
unsigned char packet[1500];
/* Wait for a packet or for the timeout */
tv.tv_sec = delay_ms / 1000;
tv.tv_usec = (delay_ms % 1000) * 1000;
again:
FD_ZERO(&set);
FD_SET(ppi->ch.fd, &set);
i = select(ppi->ch.fd + 1, &set, NULL, NULL, &tv);
if (i < 0 && errno != EINTR)
exit(__LINE__);
if (i < 0)
continue;
if (i == 0) {
delay_ms = pp_state_machine(ppi, NULL, 0);
continue;
}
/*
* We got a packet. If it's not ours, continue consuming
* the pending timeout
*/
i = posix_recv_packet(ppi, packet, sizeof(packet));
/* FIXME
if (i < sizeof(struct pp_packet))
goto again;
*/
/* Warning: PP_PROTO_NR is endian-agnostic by design */
if ( ((struct ethhdr *)packet)->h_proto != htons(PP_PROTO_NR))
goto again;
delay_ms = pp_state_machine(ppi, packet, i);
}
}
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
#define _GNU_SOURCE /* for strnlen */
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <pproto/pproto.h>
void pp_puts(const char *s)
{
fputs(s, stdout);
}
int pp_strnlen(const char *s, int maxlen)
{
return strnlen(s, maxlen);
}
void *pp_memcpy(void *d, const void *s, int count)
{
return memcpy(d, s, count);
}
void pp_get_stamp(uint32_t *sptr)
{
*sptr = htonl(time(NULL));
}
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
/* Socket interface for GNU/Linux (and most likely other posix systems */
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netpacket/packet.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <pproto/pproto.h>
#include <pproto/diag.h>
#include "posix.h"
/* Receive and send is trivial */
int posix_recv_packet(struct pp_instance *ppi, void *pkt, int len)
{
return recv(ppi->ch.fd, pkt, len, 0);
}
int posix_send_packet(struct pp_instance *ppi, void *pkt, int len)
{
return send(ppi->ch.fd, pkt, len, 0);
}
int pp_recv_packet(struct pp_instance *ppi, void *pkt, int len)
__attribute__((alias("posix_recv_packet")));
int pp_send_packet(struct pp_instance *ppi, void *pkt, int len)
__attribute__((alias("posix_send_packet")));
/* To open a channel we must bind to an interface and so on */
int posix_open_ch(struct pp_instance *ppi, char *ifname)
{
int sock, iindex;
struct ifreq ifr;
struct sockaddr_ll addr;
/* open socket */
sock = socket(PF_PACKET, SOCK_RAW, PP_PROTO_NR);
if (sock < 0) {
pp_diag_error_str2(ppi, "socket()", strerror(errno));
return -1;
}
/* hw interface information */
memset (&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, ifname);
if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
pp_diag_error_str2(ppi, "SIOCGIFINDEX", strerror(errno));
close(sock);
return -1;
}
iindex = ifr.ifr_ifindex;
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
pp_diag_error_str2(ppi, "SIOCGIFHWADDR", strerror(errno));
close(sock);
return -1;
}
memcpy(ppi->ch.addr, ifr.ifr_hwaddr.sa_data, 6);
/* bind and setsockopt */
memset(&addr, 0, sizeof(addr));
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(PP_PROTO_NR);
addr.sll_ifindex = iindex;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
pp_diag_error_str2(ppi, "bind", strerror(errno));
close(sock);
return -1;
}
ppi->ch.fd = sock;
return 0;
}
/*
* Inits all the network stuff
* TODO: check with the posix_open_ch, maybe it's the same
*/
int posix_net_init(struct pp_instance *ppi)
{
return 0;
}
int pp_net_init(struct pp_instance *ppi)
__attribute__((alias("posix_net_init")));
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
/*
* This is the startup thing for hosted environments. It
* defines main and then calls the main loop.
*/
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pproto/pproto.h>
#include <pproto/diag.h>
#include "posix.h"
int main(int argc, char **argv)
{
struct pp_instance *ppi;
char *ifname;
/*
* Here, we may fork or whatever for each interface.
* To keep things simple, just run one thing for one interface.
*/
ifname = getenv("PPROTO_IF");
if (!ifname) ifname = "eth0";
/* We are hosted, so we can allocate */
ppi = calloc(1, sizeof(*ppi));
if (!ppi)
exit(__LINE__);
if (posix_open_ch(ppi, ifname)) {
pp_diag_fatal(ppi, "open_ch", strerror(errno));
}
pp_open_instance(ppi, NULL);
pp_parse_cmdline(ppi,argc,argv);
posix_main_loop(ppi);
return 0; /* never reached */
}
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
/*
* These are the functions provided by the various posix files
*/
extern int posix_net_init(struct pp_instance *ppi);
extern int posix_open_ch(struct pp_instance *ppi, char *name);
extern int posix_recv_packet(struct pp_instance *ppi, void *pkt, int len);
extern int posix_send_packet(struct pp_instance *ppi, void *pkt, int len);
extern void posix_main_loop(struct pp_instance *ppi);
# Alessandro Rubini for CERN, 2011 -- public domain
CFLAGS += -ffreestanding -Os \
-ffunction-sections -fdata-sections \
-mmultiply-enabled -mbarrel-shift-enabled
ARCH_LDFLAGS = -nostdlib -static -T $(ARCH).lds
# All files are under A (short for ARCH): I'm lazy
A := arch-$(ARCH)
LIBARCH := $A/libarch.a
OBJ-libarch := $A/spec-startup.o \
$A/main-loop.o \
$A/spec-socket.o \
$A/spec-io.o \
$A/dev/uart.o \
$A/dev/timer.o \
$A/dev/endpoint.o \
$A/dev/minic.o
$(LIBARCH): $(OBJ-libarch)
$(AR) r $@ $^
all: $(TARGET) $(TARGET).bin
# to build the target, we need -lstd again, in case we call functions that
# were not selected yet (e.g., pp_open_instance() ).
$(TARGET): $(TARGET).o $A/crt0.o $(LIBARCH)
$(CC) -Wl,-Map,$(TARGET).map2 $(ARCH_LDFLAGS) -o $@ $A/crt0.o \
$(TARGET).o -L$A -larch -L$D -lstd
$(TARGET).bin: $(TARGET)
$(OBJCOPY) -O binary $^ $@
/****************************************************************************
**
** Name: crt0ram.S
**
** Description:
** Implements boot-code that calls LatticeDDInit (that calls main())
** Implements exception handlers (actually, redirectors)
**
** $Revision: $
**
** Disclaimer:
**
** This source code is intended as a design reference which
** illustrates how these types of functions can be implemented. It
** is the user's responsibility to verify their design for
** consistency and functionality through the use of formal
** verification methods. Lattice Semiconductor provides no warranty
** regarding the use or functionality of this code.
**
** --------------------------------------------------------------------
**
** Lattice Semiconductor Corporation
** 5555 NE Moore Court
** Hillsboro, OR 97214
** U.S.A
**
** TEL: 1-800-Lattice (USA and Canada)
** (503)268-8001 (other locations)
**
** web: http://www.latticesemi.com
** email: techsupport@latticesemi.com
**
** --------------------------------------------------------------------------
**
** Change History (Latest changes on top)
**
** Ver Date Description
** --------------------------------------------------------------------------
** 3.8 Apr-15-2011 Added __MICO_USER_<handler>_HANDLER__ preprocessor to
** allow customers to implement their own handlers for:
** DATA_ABORT, INST_ABORT
**
** 3.1 Jun-18-2008 Added __MICO_NO_INTERRUPTS__ preprocessor
** option to exclude invoking MicoISRHandler
** to reduce code-size in apps that don't use
** interrupts
**
** 3.0 Mar-25-2008 Added Header
**
**---------------------------------------------------------------------------
*****************************************************************************/
/*
* LatticeMico32 C startup code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* From include/sys/signal.h */
#define SIGINT 2 /* interrupt */
#define SIGTRAP 5 /* trace trap */
#define SIGFPE 8 /* arithmetic exception */
#define SIGSEGV 11 /* segmentation violation */
//#define MICO32_FULL_CONTEXT_SAVE_RESTORE
/* Exception handlers - Must be 32 bytes long. */
.section .boot, "ax", @progbits
.global _start
_start:
.global _reset_handler
.type _reset_handler, @function
_reset_handler:
xor r0, r0, r0
wcsr IE, r0
wcsr IM, r0
mvhi r1, hi(_reset_handler)
ori r1, r1, lo(_reset_handler)
wcsr EBA, r1
calli _crt0
nop
.size _reset_handler, .-_reset_handler
.extern _irq_entry
.org 0xc0
.global _interrupt_handler
.type _interrupt_handler, @function
_interrupt_handler:
sw (sp+0), ra
calli _save_all
mvi r1, SIGINT
#ifndef __MICO_NO_INTERRUPTS__
calli _irq_entry
#else
wcsr IE, r0
#endif
bi _restore_all_and_return
nop
nop
nop
.org 0x100
.global _crt0
.type _crt0, @function
_crt0:
/* Clear r0 */
xor r0, r0, r0
/* Setup stack and global pointer */
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
mvhi gp, hi(_gp)
ori gp, gp, lo(_gp)
mvhi r1, hi(_fbss)
ori r1, r1, lo(_fbss)
mvi r2, 0
mvhi r3, hi(_ebss)
ori r3, r3, lo(_ebss)
sub r3, r3, r1
calli memset
mvi r1, 0
mvi r2, 0
mvi r3, 0
calli main
loopf:
bi loopf
.global _save_all
.type _save_all, @function
_save_all:
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
addi sp, sp, -128
#else
addi sp, sp, -60
#endif
sw (sp+4), r1
sw (sp+8), r2
sw (sp+12), r3
sw (sp+16), r4
sw (sp+20), r5
sw (sp+24), r6
sw (sp+28), r7
sw (sp+32), r8
sw (sp+36), r9
sw (sp+40), r10
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
sw (sp+44), r11
sw (sp+48), r12
sw (sp+52), r13
sw (sp+56), r14
sw (sp+60), r15
sw (sp+64), r16
sw (sp+68), r17
sw (sp+72), r18
sw (sp+76), r19
sw (sp+80), r20
sw (sp+84), r21
sw (sp+88), r22
sw (sp+92), r23
sw (sp+96), r24
sw (sp+100), r25
sw (sp+104), r26
sw (sp+108), r27
sw (sp+120), ea
sw (sp+124), ba
/* ra and sp need special handling, as they have been modified */
lw r1, (sp+128)
sw (sp+116), r1
mv r1, sp
addi r1, r1, 128
sw (sp+112), r1
#else
sw (sp+52), ea
sw (sp+56), ba
/* ra and sp need special handling, as they have been modified */
lw r1, (sp+60)
sw (sp+48), r1
mv r1, sp
addi r1, r1, 60
sw (sp+44), r1
#endif
// xor r1, r1, r1
// wcsr ie, r1
ret
.size _save_all, .-_save_all
.global _restore_all_and_return
.type _restore_all_and_return, @function
/* Restore all registers and return from exception */
_restore_all_and_return:
// addi r1, r0, 2
// wcsr ie, r1
lw r1, (sp+4)
lw r2, (sp+8)
lw r3, (sp+12)
lw r4, (sp+16)
lw r5, (sp+20)
lw r6, (sp+24)
lw r7, (sp+28)
lw r8, (sp+32)
lw r9, (sp+36)
lw r10, (sp+40)
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
lw r11, (sp+44)
lw r12, (sp+48)
lw r13, (sp+52)
lw r14, (sp+56)
lw r15, (sp+60)
lw r16, (sp+64)
lw r17, (sp+68)
lw r18, (sp+72)
lw r19, (sp+76)
lw r20, (sp+80)
lw r21, (sp+84)
lw r22, (sp+88)
lw r23, (sp+92)
lw r24, (sp+96)
lw r25, (sp+100)
lw r26, (sp+104)
lw r27, (sp+108)
lw ra, (sp+116)
lw ea, (sp+120)
lw ba, (sp+124)
/* Stack pointer must be restored last, in case it has been updated */
lw sp, (sp+112)
#else
lw ra, (sp+48)
lw ea, (sp+52)
lw ba, (sp+56)
/* Stack pointer must be restored last, in case it has been updated */
lw sp, (sp+44)
#endif
nop
eret
.size _restore_all_and_return, .-_restore_all_and_return
/*
* Copyright 2011 Tomasz Wlostowski <tomasz.wlostowski@cern.ch> for CERN
* Modified by Alessandro Rubini for ptp-proposal/proto
*
* GNU LGPL 2.1 or later versions
*/
#include <pproto/pproto.h>
#include "../spec.h"
#include <hw/endpoint_regs.h>
#include <hw/endpoint_mdio.h>
#define UIS_PER_SERIAL_BIT 800
static int autoneg_enabled;
static volatile struct EP_WB *EP = (volatile struct EP_WB *) BASE_EP;
/* functions for accessing PCS registers */
static uint16_t pcs_read(int location)
{
EP->MDIO_CR = EP_MDIO_CR_ADDR_W(location >> 2);
while ((EP->MDIO_SR & EP_MDIO_SR_READY) == 0);
return EP_MDIO_SR_RDATA_R(EP->MDIO_SR) & 0xffff;
}
static void pcs_write(int location,
int value)
{
EP->MDIO_CR = EP_MDIO_CR_ADDR_W(location >> 2)
| EP_MDIO_CR_DATA_W(value)
| EP_MDIO_CR_RW;
while ((EP->MDIO_SR & EP_MDIO_SR_READY) == 0);
}
static void set_mac_addr(uint8_t dev_addr[])
{
EP->MACL = ((uint32_t)dev_addr[2] << 24)
| ((uint32_t)dev_addr[3] << 16)
| ((uint32_t)dev_addr[4] << 8)
| ((uint32_t)dev_addr[5]);
EP->MACH = ((uint32_t)dev_addr[0] << 8)
| ((uint32_t)dev_addr[1]);
}
void get_mac_addr(uint8_t dev_addr[])
{
dev_addr[5] = (uint8_t)(EP->MACL & 0x000000ff);
dev_addr[4] = (uint8_t)(EP->MACL & 0x0000ff00) >> 8;
dev_addr[3] = (uint8_t)(EP->MACL & 0x00ff0000) >> 16;
dev_addr[2] = (uint8_t)(EP->MACL & 0xff000000) >> 24;
dev_addr[1] = (uint8_t)(EP->MACH & 0x000000ff);
dev_addr[0] = (uint8_t)(EP->MACH & 0x0000ff00) >> 8;
}
void ep_init(uint8_t mac_addr[])
{
set_mac_addr(mac_addr);
EP->ECR = 0;
EP->DMCR = EP_DMCR_EN | EP_DMCR_N_AVG_W(DMTD_AVG_SAMPLES);
EP->RFCR = 3 << EP_RFCR_QMODE_SHIFT;
EP->TSCR = EP_TSCR_EN_TXTS | EP_TSCR_EN_RXTS;
EP->FCR = 0;
}
int ep_enable(int enabled, int autoneg)
{
uint16_t mcr;
if(!enabled)
{
EP->ECR = 0;
return 0;
}
EP->ECR = EP_ECR_TX_EN_FRA | EP_ECR_RX_EN_FRA | EP_ECR_RST_CNT;
autoneg_enabled = autoneg;
#if 1
pcs_write(MDIO_REG_MCR, MDIO_MCR_PDOWN); /* reset the PHY */
spec_udelay(2000 * 1000);
pcs_write(MDIO_REG_MCR, 0); /* reset the PHY */
// pcs_write(MDIO_REG_MCR, MDIO_MCR_RESET); /* reset the PHY */
#endif
pcs_write(MDIO_REG_ADVERTISE, 0);
mcr = MDIO_MCR_SPEED1000_MASK | MDIO_MCR_FULLDPLX_MASK;
if(autoneg)
mcr |= MDIO_MCR_ANENABLE | MDIO_MCR_ANRESTART;
pcs_write(MDIO_REG_MCR, mcr);
return 0;
}
int ep_link_up()
{
uint16_t flags = MDIO_MSR_LSTATUS;
volatile uint16_t msr;
if(autoneg_enabled)
flags |= MDIO_MSR_ANEGCOMPLETE;
msr = pcs_read(MDIO_REG_MSR);
msr = pcs_read(MDIO_REG_MSR);
return (msr & flags) == flags ? 1 : 0;
}
int ep_get_deltas(uint32_t *delta_tx, uint32_t *delta_rx)
{
// mprintf("called ep_get_deltas()\n");
*delta_tx = 0;
*delta_rx = 15000 - 7000 + 195000 + 32000
+ UIS_PER_SERIAL_BIT
* MDIO_WR_SPEC_BSLIDE_R(pcs_read(MDIO_REG_WR_SPEC))
+ 2800 - 9000;
return 0;
}
void ep_show_counters()
{
int i;
for(i=0;i<16;i++)
TRACE_DEV("cntr%d = %d\n", i, (int)(EP->RMON_RAM[i]));
}
int ep_get_psval(int32_t *psval)
{
uint32_t val;
val = EP->DMSR;
if(val & EP_DMSR_PS_RDY)
*psval = EP_DMSR_PS_VAL_R(val);
else
*psval = 0;
return val & EP_DMSR_PS_RDY;
}
int ep_cal_pattern_enable()
{
uint32_t val;
val = pcs_read(MDIO_REG_WR_SPEC);
val |= MDIO_WR_SPEC_TX_CAL;
pcs_write(MDIO_REG_WR_SPEC, val);
return 0;
}
int ep_cal_pattern_disable()
{
uint32_t val;
val = pcs_read(MDIO_REG_WR_SPEC);
val &= (~MDIO_WR_SPEC_TX_CAL);
pcs_write(MDIO_REG_WR_SPEC, val);
return 0;
}
/*
* Copyright 2011 Tomasz Wlostowski <tomasz.wlostowski@cern.ch> for CERN
* Modified by Alessandro Rubini for ptp-proposal/proto
*
* GNU LGPL 2.1 or later versions
*/
#include <pproto/pproto.h>
#include "../spec.h"
//#include "pps_gen.h" /* for pps_gen_get_time() */
#include <hw/minic_regs.h>
#define MINIC_DMA_TX_BUF_SIZE 1024
#define MINIC_DMA_RX_BUF_SIZE 2048
#define MINIC_MTU 256
#define F_COUNTER_BITS 4
#define F_COUNTER_MASK ((1<<F_COUNTER_BITS)-1)
#define RX_DESC_VALID(d) ((d) & (1<<31) ? 1 : 0)
#define RX_DESC_ERROR(d) ((d) & (1<<30) ? 1 : 0)
#define RX_DESC_HAS_OOB(d) ((d) & (1<<29) ? 1 : 0)
#define RX_DESC_SIZE(d) (((d) & (1<<0) ? -1 : 0) + (d & 0xfffe))
#define TX_DESC_VALID (1<<31)
#define TX_DESC_WITH_OOB (1<<30)
#define TX_DESC_HAS_OWN_MAC (1<<28)
#define RX_OOB_SIZE 6
#define REFCLK_FREQ 125000000
#define ETH_HEADER_SIZE 14
/* extracts the values of TS rising and falling edge ctrs from desc. header */
#define EXPLODE_WR_TIMESTAMP(raw, rc, fc) \
rc = (raw) & 0xfffffff; \
fc = (raw >> 28) & 0xf;
static volatile uint32_t dma_tx_buf[MINIC_DMA_TX_BUF_SIZE / 4];
static volatile uint32_t dma_rx_buf[MINIC_DMA_RX_BUF_SIZE / 4];
struct wr_minic {
volatile uint32_t *rx_head, *rx_base;
uint32_t rx_avail, rx_size;
volatile uint32_t *tx_head, *tx_base;
uint32_t tx_avail, tx_size;
int synced;
int syncing_counters;
int iface_up;
int tx_count, rx_count;
uint32_t cur_rx_desc;
};
static struct wr_minic minic;
static inline void minic_writel(uint32_t reg,uint32_t data)
{
*(volatile uint32_t *) (BASE_MINIC + reg) = data;
}
static inline uint32_t minic_readl(uint32_t reg)
{
return *(volatile uint32_t *)(BASE_MINIC + reg);
}
static void minic_new_rx_buffer()
{
minic.rx_head = minic.rx_base;
minic_writel(MINIC_REG_MCR, 0);
minic_writel(MINIC_REG_RX_ADDR, (uint32_t) minic.rx_base);
minic_writel(MINIC_REG_RX_AVAIL, (minic.rx_size - MINIC_MTU) >> 2);
if (0) {
TRACE_DEV("Size : %d Avail: %d\n",
(int)minic.rx_size,
(int)((minic.rx_size - MINIC_MTU) >> 2));
}
minic_writel(MINIC_REG_MCR, MINIC_MCR_RX_EN);
}
static void minic_new_tx_buffer()
{
minic.tx_head = minic.tx_base;
minic.tx_avail = (minic.tx_size - MINIC_MTU) >> 2;
minic_writel(MINIC_REG_TX_ADDR, (uint32_t) minic.tx_base);
}
void minic_init()
{
minic_writel(MINIC_REG_EIC_IDR, MINIC_EIC_IDR_RX);
minic_writel(MINIC_REG_EIC_ISR, MINIC_EIC_ISR_RX);
minic.rx_base = dma_rx_buf;
minic.rx_size = sizeof(dma_rx_buf);
minic.tx_base = dma_tx_buf;
minic.tx_size = sizeof(dma_tx_buf);
minic.tx_count = 0;
minic.rx_count = 0;
minic_new_rx_buffer();
minic_writel(MINIC_REG_EIC_IER, MINIC_EIC_IER_RX);
}
void minic_disable()
{
minic_writel(MINIC_REG_MCR, 0);
}
int minic_poll_rx()
{
uint32_t isr;
isr = minic_readl(MINIC_REG_EIC_ISR);
return (isr & MINIC_EIC_ISR_RX) ? 1 : 0;//>>1;
}
int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size,
struct hw_timestamp *hwts)
{
uint32_t payload_size, num_words;
uint32_t desc_hdr;
uint32_t raw_ts;
uint32_t rx_addr_cur;
int n_recvd = 0;
if(! (minic_readl(MINIC_REG_EIC_ISR) & MINIC_EIC_ISR_RX))
return 0;
desc_hdr = *minic.rx_head;
if (0) {
TRACE_DEV("RX_FRAME_ENTER\n\nRxHead %x buffer at %x\n",
(int)minic.rx_head, (int)minic.rx_base);
}
/*
* invalid descriptor? Weird, the RX_ADDR seems to be
* saying something different. Ignore the packet and purge
* the RX buffer.
*/
if(!RX_DESC_VALID(desc_hdr))
{
/*
* invalid descriptor? Weird, the RX_ADDR seems to be
* saying something different. Ignore the packet and purge
* the RX buffer.
*/
TRACE_DEV("weird, invalid RX descriptor (%x, head %x)\n",
(int)desc_hdr, (int)minic.rx_head);
minic_new_rx_buffer();
return 0;
}
payload_size = RX_DESC_SIZE(desc_hdr);
num_words = ((payload_size + 3) >> 2) + 1;
if (0)
TRACE_DEV("NWords %d\n", (int)num_words);
/* valid packet */
if(!RX_DESC_ERROR(desc_hdr))
{
if(RX_DESC_HAS_OOB(desc_hdr) && hwts != NULL)
{
uint32_t counter_r, counter_f, counter_ppsg, utc;
int cntr_diff;
payload_size -= RX_OOB_SIZE;
/* fixme: ugly way of doing unaligned read */
memcpy(&raw_ts,
(uint8_t *)minic.rx_head + payload_size + 6,
4);
EXPLODE_WR_TIMESTAMP(raw_ts, counter_r, counter_f);
/* was pps_gen_get_time(&utc, &counter_ppsg); */
utc = counter_ppsg = 0;
if(counter_r > 3*125000000/4
&& counter_ppsg < 125000000/4)
utc--;
hwts->utc = utc & 0x7fffffff ;
cntr_diff = (counter_r & F_COUNTER_MASK) - counter_f;
if(cntr_diff == 1 || cntr_diff == (-F_COUNTER_MASK))
hwts->ahead = 1;
else
hwts->ahead = 0;
hwts->nsec = counter_r * 8;
}
n_recvd = (buf_size < payload_size ? buf_size : payload_size);
TRACE_DEV("minic_rx_frame [%d bytes] TS: %d.%d\n",
n_recvd, (int)hwts->utc, (int)hwts->nsec);
minic.rx_count++;
memcpy(hdr, (void*)minic.rx_head + 4, ETH_HEADER_SIZE);
memcpy(payload, (void*)minic.rx_head + 4 + ETH_HEADER_SIZE,
n_recvd - ETH_HEADER_SIZE);
minic.rx_head += num_words;
} else { // RX_DESC_ERROR
// TRACE_DEV("nwords_avant_err: %d\n", num_words);
minic.rx_head += num_words;
}
rx_addr_cur = minic_readl(MINIC_REG_RX_ADDR) & 0xffff;
if(rx_addr_cur < (uint32_t)minic.rx_head)
{
/* nothing new in the buffer? */
if (0) {
TRACE_DEV("MoreData? %x, head %x\n",
(int)rx_addr_cur, (int)minic.rx_head);
}
if(minic_readl(MINIC_REG_MCR) & MINIC_MCR_RX_FULL)
minic_new_rx_buffer();
minic_writel(MINIC_REG_EIC_ISR, MINIC_EIC_ISR_RX);
}
return n_recvd;
}
static uint16_t tx_oob_val = 0;
int minic_tx_frame(uint8_t *hdr, uint8_t *payload, uint32_t size,
struct hw_timestamp *hwts)
{
uint32_t d_hdr, mcr, nwords;
minic_new_tx_buffer();
TRACE_DEV("minic_tx_frame: head %x size %d\n",
(int)minic.tx_head, (int)size);
memset((void *)minic.tx_head, 0x0, size + 16);
memset((void *)minic.tx_head + 4, 0, size < 60 ? 60 : size);
memcpy((void *)minic.tx_head + 4, hdr, ETH_HEADER_SIZE);
memcpy((void *)minic.tx_head + 4 + ETH_HEADER_SIZE,
payload, size - ETH_HEADER_SIZE);
if(size < 60)
size = 60;
nwords = ((size + 1) >> 1) - 1;
if (0) { /* print the packet. We know payload follows header */
int i = size, j;
uint8_t *packet = hdr;
pp_printf("recvd: %i\n", i);
for (j = 0; j < 32 && j < i; j++)
pp_printf(" %02x", packet[j]);
pp_printf("\n");
}
if(hwts)
{
memcpy((void *) minic.tx_head + 4 + size, &tx_oob_val,
sizeof(uint16_t));
nwords++;
d_hdr = TX_DESC_WITH_OOB;
} else
d_hdr = 0;
d_hdr |= TX_DESC_VALID | nwords;
*(volatile uint32_t *)(minic.tx_head) = d_hdr;
*(volatile uint32_t *)(minic.tx_head + nwords) = 0;
mcr = minic_readl(MINIC_REG_MCR);
minic_writel(MINIC_REG_MCR, mcr | MINIC_MCR_TX_START);
if(hwts) /* wait for the timestamp */
{
uint32_t raw_ts;
uint16_t fid;
uint32_t counter_r, counter_f;
uint32_t utc;
uint32_t nsec;
uint8_t ts_tout;
ts_tout=0;
while( (minic_readl(MINIC_REG_TSFIFO_CSR)
& MINIC_TSFIFO_CSR_EMPTY ) && ts_tout<10)
ts_tout++;
raw_ts = minic_readl(MINIC_REG_TSFIFO_R0);
fid = (minic_readl(MINIC_REG_TSFIFO_R1) >> 5) & 0xffff;
if(fid != tx_oob_val)
{
TRACE_DEV("minic_tx_frame: unmatched fid %d vs %d\n",
fid, tx_oob_val);
}
EXPLODE_WR_TIMESTAMP(raw_ts, counter_r, counter_f);
utc = nsec = 0; /* was: pps_gen_get_time(&utc, &nsec); */
if(counter_r > 3*125000000/4 && nsec < 125000000/4)
utc--;
hwts->utc = utc;
hwts->ahead = 0;
hwts->nsec = counter_r * 8;
TRACE_DEV("minic_tx_frame [%d bytes] TS: %d.%d\n",
(int)size, (int)hwts->utc, (int)hwts->nsec);
minic.tx_count++;
}
tx_oob_val++;
return size;
}
void minic_get_stats(int *tx_frames, int *rx_frames)
{
*tx_frames = minic.tx_count;
*rx_frames = minic.rx_count;
}
/*
* Alessandro Rubini for CERN, 2011 -- GNU LGPL v2.1 or later
* based on code by Tomasz Wlostowski
*/
#include <pproto/pproto.h>
#include "../spec.h"
static uint32_t timer_get_tics(void)
{
return *(volatile uint32_t *)BASE_TIMER;
}
void spec_udelay(int usecs)
{
uint32_t start, end;
start = timer_get_tics();
/* It looks like the counter counts millisecs */
end = start + (usecs + 500) / 1000;
while ((signed)(end - timer_get_tics()) > 0)
;
}
/* return a seconds count from the counter above; horrible code */
int spec_time(void)
{
static uint32_t prev, secs;
static int rest; /* millisecs */
uint32_t tics = timer_get_tics();
if (!prev) {
prev = tics;
secs = 1293836400; /* jan 1st 2011 or a random number */
return secs;
}
rest += tics - prev;
secs += rest / 1000;
rest %= 1000;
prev = tics;
return secs;
}
/*
* Copyright 2011 Tomasz Wlostowski <tomasz.wlostowski@cern.ch> for CERN
* Modified by Alessandro Rubini for ptp-proposal/proto
*
* GNU LGPL 2.1 or later versions
*/
#include <stdint.h>
#include "../spec.h"
#include <hw/wb_vuart.h>
#define CALC_BAUD(baudrate) \
( ((( (unsigned long long)baudrate * 8ULL) << (16 - 7)) + \
(CPU_CLOCK >> 8)) / (CPU_CLOCK >> 7) )
static volatile struct UART_WB *uart = (volatile struct UART_WB *) BASE_UART;
void spec_uart_init(void)
{
uart->BCR = CALC_BAUD(UART_BAUDRATE);
}
void spec_putc(int c)
{
if(c == '\n')
spec_putc('\r');
while(uart->SR & UART_SR_TX_BUSY)
;
uart->TDR = c;
}
void spec_puts(const char *s)
{
while (*s)
spec_putc(*(s++));
}
int spec_testc(void)
{
return uart->SR & UART_SR_RX_RDY;
}
int spec_getc(void)
{
return uart ->RDR & 0xff;
}
#ifndef __ARCH_H__
#define __ARCH_H__
/* Architecture-specific defines, included by top-level stuff */
#define htons(x) (x)
#define htonl(x) (x)
#define ntohs htons
#define ntohl htonl
#endif /* __ARCH_H__ */
/*
* Copyright 2011 Tomasz Wlostowski <tomasz.wlostowski@cern.ch> for CERN
* Modified by Alessandro Rubini for ptp-proposal/proto
*
* GNU LGPL 2.1 or later versions
*/
#ifndef __GPIO_H
#define __GPIO_H
#include <stdint.h>
struct GPIO_WB
{
uint32_t CODR; /*Clear output register*/
uint32_t SODR; /*Set output register*/
uint32_t DDR; /*Data direction register (1 means out)*/
uint32_t PSR; /*Pin state register*/
};
static volatile struct GPIO_WB *__gpio = (volatile struct GPIO_WB *) BASE_GPIO;
static inline void gpio_out(int pin, int val)
{
if(val)
__gpio->SODR = (1<<pin);
else
__gpio->CODR = (1<<pin);
}
static inline void gpio_dir(int pin, int val)
{
if(val)
__gpio->DDR |= (1<<pin);
else
__gpio->DDR &= ~(1<<pin);
}
static inline int gpio_in(int pin)
{
return __gpio->PSR & (1<<pin) ? 1: 0;
}
#endif
/*
Register definitions for slave core: WR Endpoint 1000base-X TBI PCS register block
* File : ../../../software/include/hw/endpoint_mdio.h
* Author : auto-generated by wbgen2 from pcs_regs.wb
* Created : Tue Dec 7 17:14:23 2010
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE pcs_regs.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_PCS_REGS_WB
#define __WBGEN2_REGDEFS_PCS_REGS_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: MDIO Control Register */
/* definitions for field: Reserved in reg: MDIO Control Register */
#define MDIO_MCR_RESV_MASK WBGEN2_GEN_MASK(0, 5)
#define MDIO_MCR_RESV_SHIFT 0
#define MDIO_MCR_RESV_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define MDIO_MCR_RESV_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: Unidirectional Enable in reg: MDIO Control Register */
#define MDIO_MCR_UNI_EN WBGEN2_GEN_MASK(5, 1)
/* definitions for field: Speed Selection (MSB) in reg: MDIO Control Register */
#define MDIO_MCR_SPEED1000_MASK WBGEN2_GEN_MASK(6, 1)
#define MDIO_MCR_SPEED1000_SHIFT 6
#define MDIO_MCR_SPEED1000_W(value) WBGEN2_GEN_WRITE(value, 6, 1)
#define MDIO_MCR_SPEED1000_R(reg) WBGEN2_GEN_READ(reg, 6, 1)
/* definitions for field: Collision Test in reg: MDIO Control Register */
#define MDIO_MCR_CTST_MASK WBGEN2_GEN_MASK(7, 1)
#define MDIO_MCR_CTST_SHIFT 7
#define MDIO_MCR_CTST_W(value) WBGEN2_GEN_WRITE(value, 7, 1)
#define MDIO_MCR_CTST_R(reg) WBGEN2_GEN_READ(reg, 7, 1)
/* definitions for field: Duplex Mode in reg: MDIO Control Register */
#define MDIO_MCR_FULLDPLX_MASK WBGEN2_GEN_MASK(8, 1)
#define MDIO_MCR_FULLDPLX_SHIFT 8
#define MDIO_MCR_FULLDPLX_W(value) WBGEN2_GEN_WRITE(value, 8, 1)
#define MDIO_MCR_FULLDPLX_R(reg) WBGEN2_GEN_READ(reg, 8, 1)
/* definitions for field: Restart Auto-Negotiation in reg: MDIO Control Register */
#define MDIO_MCR_ANRESTART WBGEN2_GEN_MASK(9, 1)
/* definitions for field: Isolate in reg: MDIO Control Register */
#define MDIO_MCR_ISOLATE_MASK WBGEN2_GEN_MASK(10, 1)
#define MDIO_MCR_ISOLATE_SHIFT 10
#define MDIO_MCR_ISOLATE_W(value) WBGEN2_GEN_WRITE(value, 10, 1)
#define MDIO_MCR_ISOLATE_R(reg) WBGEN2_GEN_READ(reg, 10, 1)
/* definitions for field: Power Down in reg: MDIO Control Register */
#define MDIO_MCR_PDOWN WBGEN2_GEN_MASK(11, 1)
/* definitions for field: Auto-Negotiation Enable in reg: MDIO Control Register */
#define MDIO_MCR_ANENABLE WBGEN2_GEN_MASK(12, 1)
/* definitions for field: Speed Selection (LSB) in reg: MDIO Control Register */
#define MDIO_MCR_SPEED100_MASK WBGEN2_GEN_MASK(13, 1)
#define MDIO_MCR_SPEED100_SHIFT 13
#define MDIO_MCR_SPEED100_W(value) WBGEN2_GEN_WRITE(value, 13, 1)
#define MDIO_MCR_SPEED100_R(reg) WBGEN2_GEN_READ(reg, 13, 1)
/* definitions for field: Loopback in reg: MDIO Control Register */
#define MDIO_MCR_LOOPBACK WBGEN2_GEN_MASK(14, 1)
/* definitions for field: Reset in reg: MDIO Control Register */
#define MDIO_MCR_RESET WBGEN2_GEN_MASK(15, 1)
/* definitions for register: MDIO Status Register */
/* definitions for field: Extended Capability in reg: MDIO Status Register */
#define MDIO_MSR_ERCAP_MASK WBGEN2_GEN_MASK(0, 1)
#define MDIO_MSR_ERCAP_SHIFT 0
#define MDIO_MSR_ERCAP_W(value) WBGEN2_GEN_WRITE(value, 0, 1)
#define MDIO_MSR_ERCAP_R(reg) WBGEN2_GEN_READ(reg, 0, 1)
/* definitions for field: Jabber Detect in reg: MDIO Status Register */
#define MDIO_MSR_JCD_MASK WBGEN2_GEN_MASK(1, 1)
#define MDIO_MSR_JCD_SHIFT 1
#define MDIO_MSR_JCD_W(value) WBGEN2_GEN_WRITE(value, 1, 1)
#define MDIO_MSR_JCD_R(reg) WBGEN2_GEN_READ(reg, 1, 1)
/* definitions for field: Link Status in reg: MDIO Status Register */
#define MDIO_MSR_LSTATUS WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Auto-Negotiation Ability in reg: MDIO Status Register */
#define MDIO_MSR_ANEGCAPABLE_MASK WBGEN2_GEN_MASK(3, 1)
#define MDIO_MSR_ANEGCAPABLE_SHIFT 3
#define MDIO_MSR_ANEGCAPABLE_W(value) WBGEN2_GEN_WRITE(value, 3, 1)
#define MDIO_MSR_ANEGCAPABLE_R(reg) WBGEN2_GEN_READ(reg, 3, 1)
/* definitions for field: Remote Fault in reg: MDIO Status Register */
#define MDIO_MSR_RFAULT WBGEN2_GEN_MASK(4, 1)
/* definitions for field: Auto-Negotiation Complete in reg: MDIO Status Register */
#define MDIO_MSR_ANEGCOMPLETE WBGEN2_GEN_MASK(5, 1)
/* definitions for field: MF Preamble Suppression in reg: MDIO Status Register */
#define MDIO_MSR_MFSUPPRESS_MASK WBGEN2_GEN_MASK(6, 1)
#define MDIO_MSR_MFSUPPRESS_SHIFT 6
#define MDIO_MSR_MFSUPPRESS_W(value) WBGEN2_GEN_WRITE(value, 6, 1)
#define MDIO_MSR_MFSUPPRESS_R(reg) WBGEN2_GEN_READ(reg, 6, 1)
/* definitions for field: Unidirectional Ability in reg: MDIO Status Register */
#define MDIO_MSR_UNIDIRABLE_MASK WBGEN2_GEN_MASK(7, 1)
#define MDIO_MSR_UNIDIRABLE_SHIFT 7
#define MDIO_MSR_UNIDIRABLE_W(value) WBGEN2_GEN_WRITE(value, 7, 1)
#define MDIO_MSR_UNIDIRABLE_R(reg) WBGEN2_GEN_READ(reg, 7, 1)
/* definitions for field: Extended Status Capable in reg: MDIO Status Register */
#define MDIO_MSR_ESTATEN_MASK WBGEN2_GEN_MASK(8, 1)
#define MDIO_MSR_ESTATEN_SHIFT 8
#define MDIO_MSR_ESTATEN_W(value) WBGEN2_GEN_WRITE(value, 8, 1)
#define MDIO_MSR_ESTATEN_R(reg) WBGEN2_GEN_READ(reg, 8, 1)
/* definitions for field: 100BASE-T2 Half Duplex in reg: MDIO Status Register */
#define MDIO_MSR_100HALF2_MASK WBGEN2_GEN_MASK(9, 1)
#define MDIO_MSR_100HALF2_SHIFT 9
#define MDIO_MSR_100HALF2_W(value) WBGEN2_GEN_WRITE(value, 9, 1)
#define MDIO_MSR_100HALF2_R(reg) WBGEN2_GEN_READ(reg, 9, 1)
/* definitions for field: 100BASE-T2 Full Duplex in reg: MDIO Status Register */
#define MDIO_MSR_100FULL2_MASK WBGEN2_GEN_MASK(10, 1)
#define MDIO_MSR_100FULL2_SHIFT 10
#define MDIO_MSR_100FULL2_W(value) WBGEN2_GEN_WRITE(value, 10, 1)
#define MDIO_MSR_100FULL2_R(reg) WBGEN2_GEN_READ(reg, 10, 1)
/* definitions for field: 10 Mbps Half Duplex in reg: MDIO Status Register */
#define MDIO_MSR_10HALF_MASK WBGEN2_GEN_MASK(11, 1)
#define MDIO_MSR_10HALF_SHIFT 11
#define MDIO_MSR_10HALF_W(value) WBGEN2_GEN_WRITE(value, 11, 1)
#define MDIO_MSR_10HALF_R(reg) WBGEN2_GEN_READ(reg, 11, 1)
/* definitions for field: 10 Mbps Full Duplex in reg: MDIO Status Register */
#define MDIO_MSR_10FULL_MASK WBGEN2_GEN_MASK(12, 1)
#define MDIO_MSR_10FULL_SHIFT 12
#define MDIO_MSR_10FULL_W(value) WBGEN2_GEN_WRITE(value, 12, 1)
#define MDIO_MSR_10FULL_R(reg) WBGEN2_GEN_READ(reg, 12, 1)
/* definitions for field: 100BASE-X Half Duplex in reg: MDIO Status Register */
#define MDIO_MSR_100HALF_MASK WBGEN2_GEN_MASK(13, 1)
#define MDIO_MSR_100HALF_SHIFT 13
#define MDIO_MSR_100HALF_W(value) WBGEN2_GEN_WRITE(value, 13, 1)
#define MDIO_MSR_100HALF_R(reg) WBGEN2_GEN_READ(reg, 13, 1)
/* definitions for field: 100BASE-X Full Duplex in reg: MDIO Status Register */
#define MDIO_MSR_100FULL_MASK WBGEN2_GEN_MASK(14, 1)
#define MDIO_MSR_100FULL_SHIFT 14
#define MDIO_MSR_100FULL_W(value) WBGEN2_GEN_WRITE(value, 14, 1)
#define MDIO_MSR_100FULL_R(reg) WBGEN2_GEN_READ(reg, 14, 1)
/* definitions for field: 100BASE-T4 in reg: MDIO Status Register */
#define MDIO_MSR_100BASE4_MASK WBGEN2_GEN_MASK(15, 1)
#define MDIO_MSR_100BASE4_SHIFT 15
#define MDIO_MSR_100BASE4_W(value) WBGEN2_GEN_WRITE(value, 15, 1)
#define MDIO_MSR_100BASE4_R(reg) WBGEN2_GEN_READ(reg, 15, 1)
/* definitions for register: MDIO PHY Identification Register 1 */
/* definitions for field: Organizationally Unique Identifier (bits 7-21) in reg: MDIO PHY Identification Register 1 */
#define MDIO_PHYSID1_OUI_MASK WBGEN2_GEN_MASK(0, 16)
#define MDIO_PHYSID1_OUI_SHIFT 0
#define MDIO_PHYSID1_OUI_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define MDIO_PHYSID1_OUI_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for register: MDIO PHY Identification Register 2 */
/* definitions for field: Revision Number in reg: MDIO PHY Identification Register 2 */
#define MDIO_PHYSID2_REV_NUM_MASK WBGEN2_GEN_MASK(0, 4)
#define MDIO_PHYSID2_REV_NUM_SHIFT 0
#define MDIO_PHYSID2_REV_NUM_W(value) WBGEN2_GEN_WRITE(value, 0, 4)
#define MDIO_PHYSID2_REV_NUM_R(reg) WBGEN2_GEN_READ(reg, 0, 4)
/* definitions for field: Manufacturer Model Number in reg: MDIO PHY Identification Register 2 */
#define MDIO_PHYSID2_MMNUM_MASK WBGEN2_GEN_MASK(4, 6)
#define MDIO_PHYSID2_MMNUM_SHIFT 4
#define MDIO_PHYSID2_MMNUM_W(value) WBGEN2_GEN_WRITE(value, 4, 6)
#define MDIO_PHYSID2_MMNUM_R(reg) WBGEN2_GEN_READ(reg, 4, 6)
/* definitions for field: Organizationally Unique Identifier (bits 0-5) in reg: MDIO PHY Identification Register 2 */
#define MDIO_PHYSID2_OUI_MASK WBGEN2_GEN_MASK(10, 6)
#define MDIO_PHYSID2_OUI_SHIFT 10
#define MDIO_PHYSID2_OUI_W(value) WBGEN2_GEN_WRITE(value, 10, 6)
#define MDIO_PHYSID2_OUI_R(reg) WBGEN2_GEN_READ(reg, 10, 6)
/* definitions for register: MDIO Auto-Negotiation Advertisement Register */
/* definitions for field: Reserved in reg: MDIO Auto-Negotiation Advertisement Register */
#define MDIO_ADVERTISE_RSVD3_MASK WBGEN2_GEN_MASK(0, 5)
#define MDIO_ADVERTISE_RSVD3_SHIFT 0
#define MDIO_ADVERTISE_RSVD3_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define MDIO_ADVERTISE_RSVD3_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: Full Duplex in reg: MDIO Auto-Negotiation Advertisement Register */
#define MDIO_ADVERTISE_FULL_MASK WBGEN2_GEN_MASK(5, 1)
#define MDIO_ADVERTISE_FULL_SHIFT 5
#define MDIO_ADVERTISE_FULL_W(value) WBGEN2_GEN_WRITE(value, 5, 1)
#define MDIO_ADVERTISE_FULL_R(reg) WBGEN2_GEN_READ(reg, 5, 1)
/* definitions for field: Half Duplex in reg: MDIO Auto-Negotiation Advertisement Register */
#define MDIO_ADVERTISE_HALF_MASK WBGEN2_GEN_MASK(6, 1)
#define MDIO_ADVERTISE_HALF_SHIFT 6
#define MDIO_ADVERTISE_HALF_W(value) WBGEN2_GEN_WRITE(value, 6, 1)
#define MDIO_ADVERTISE_HALF_R(reg) WBGEN2_GEN_READ(reg, 6, 1)
/* definitions for field: Pause in reg: MDIO Auto-Negotiation Advertisement Register */
#define MDIO_ADVERTISE_PAUSE_MASK WBGEN2_GEN_MASK(7, 2)
#define MDIO_ADVERTISE_PAUSE_SHIFT 7
#define MDIO_ADVERTISE_PAUSE_W(value) WBGEN2_GEN_WRITE(value, 7, 2)
#define MDIO_ADVERTISE_PAUSE_R(reg) WBGEN2_GEN_READ(reg, 7, 2)
/* definitions for field: Reserved in reg: MDIO Auto-Negotiation Advertisement Register */
#define MDIO_ADVERTISE_RSVD2_MASK WBGEN2_GEN_MASK(9, 3)
#define MDIO_ADVERTISE_RSVD2_SHIFT 9
#define MDIO_ADVERTISE_RSVD2_W(value) WBGEN2_GEN_WRITE(value, 9, 3)
#define MDIO_ADVERTISE_RSVD2_R(reg) WBGEN2_GEN_READ(reg, 9, 3)
/* definitions for field: Remote Fault in reg: MDIO Auto-Negotiation Advertisement Register */
#define MDIO_ADVERTISE_RFAULT_MASK WBGEN2_GEN_MASK(12, 2)
#define MDIO_ADVERTISE_RFAULT_SHIFT 12
#define MDIO_ADVERTISE_RFAULT_W(value) WBGEN2_GEN_WRITE(value, 12, 2)
#define MDIO_ADVERTISE_RFAULT_R(reg) WBGEN2_GEN_READ(reg, 12, 2)
/* definitions for field: Reserved in reg: MDIO Auto-Negotiation Advertisement Register */
#define MDIO_ADVERTISE_RSVD1_MASK WBGEN2_GEN_MASK(14, 1)
#define MDIO_ADVERTISE_RSVD1_SHIFT 14
#define MDIO_ADVERTISE_RSVD1_W(value) WBGEN2_GEN_WRITE(value, 14, 1)
#define MDIO_ADVERTISE_RSVD1_R(reg) WBGEN2_GEN_READ(reg, 14, 1)
/* definitions for field: Next Page in reg: MDIO Auto-Negotiation Advertisement Register */
#define MDIO_ADVERTISE_NPAGE_MASK WBGEN2_GEN_MASK(15, 1)
#define MDIO_ADVERTISE_NPAGE_SHIFT 15
#define MDIO_ADVERTISE_NPAGE_W(value) WBGEN2_GEN_WRITE(value, 15, 1)
#define MDIO_ADVERTISE_NPAGE_R(reg) WBGEN2_GEN_READ(reg, 15, 1)
/* definitions for register: MDIO Auto-Negotiation Link Partner Ability Register */
/* definitions for field: Reserved in reg: MDIO Auto-Negotiation Link Partner Ability Register */
#define MDIO_LPA_RSVD3_MASK WBGEN2_GEN_MASK(0, 5)
#define MDIO_LPA_RSVD3_SHIFT 0
#define MDIO_LPA_RSVD3_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define MDIO_LPA_RSVD3_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: Full Duplex in reg: MDIO Auto-Negotiation Link Partner Ability Register */
#define MDIO_LPA_FULL WBGEN2_GEN_MASK(5, 1)
/* definitions for field: Half Duplex in reg: MDIO Auto-Negotiation Link Partner Ability Register */
#define MDIO_LPA_HALF WBGEN2_GEN_MASK(6, 1)
/* definitions for field: Pause in reg: MDIO Auto-Negotiation Link Partner Ability Register */
#define MDIO_LPA_PAUSE_MASK WBGEN2_GEN_MASK(7, 2)
#define MDIO_LPA_PAUSE_SHIFT 7
#define MDIO_LPA_PAUSE_W(value) WBGEN2_GEN_WRITE(value, 7, 2)
#define MDIO_LPA_PAUSE_R(reg) WBGEN2_GEN_READ(reg, 7, 2)
/* definitions for field: Reserved in reg: MDIO Auto-Negotiation Link Partner Ability Register */
#define MDIO_LPA_RSVD2_MASK WBGEN2_GEN_MASK(9, 3)
#define MDIO_LPA_RSVD2_SHIFT 9
#define MDIO_LPA_RSVD2_W(value) WBGEN2_GEN_WRITE(value, 9, 3)
#define MDIO_LPA_RSVD2_R(reg) WBGEN2_GEN_READ(reg, 9, 3)
/* definitions for field: Remote Fault in reg: MDIO Auto-Negotiation Link Partner Ability Register */
#define MDIO_LPA_RFAULT_MASK WBGEN2_GEN_MASK(12, 2)
#define MDIO_LPA_RFAULT_SHIFT 12
#define MDIO_LPA_RFAULT_W(value) WBGEN2_GEN_WRITE(value, 12, 2)
#define MDIO_LPA_RFAULT_R(reg) WBGEN2_GEN_READ(reg, 12, 2)
/* definitions for field: Acknowledge in reg: MDIO Auto-Negotiation Link Partner Ability Register */
#define MDIO_LPA_LPACK WBGEN2_GEN_MASK(14, 1)
/* definitions for field: Next Page in reg: MDIO Auto-Negotiation Link Partner Ability Register */
#define MDIO_LPA_NPAGE WBGEN2_GEN_MASK(15, 1)
/* definitions for register: MDIO Auto-Negotiation Expansion Register */
/* definitions for field: Reserved in reg: MDIO Auto-Negotiation Expansion Register */
#define MDIO_EXPANSION_RSVD1_MASK WBGEN2_GEN_MASK(0, 1)
#define MDIO_EXPANSION_RSVD1_SHIFT 0
#define MDIO_EXPANSION_RSVD1_W(value) WBGEN2_GEN_WRITE(value, 0, 1)
#define MDIO_EXPANSION_RSVD1_R(reg) WBGEN2_GEN_READ(reg, 0, 1)
/* definitions for field: Page Received in reg: MDIO Auto-Negotiation Expansion Register */
#define MDIO_EXPANSION_LWCP_MASK WBGEN2_GEN_MASK(1, 1)
#define MDIO_EXPANSION_LWCP_SHIFT 1
#define MDIO_EXPANSION_LWCP_W(value) WBGEN2_GEN_WRITE(value, 1, 1)
#define MDIO_EXPANSION_LWCP_R(reg) WBGEN2_GEN_READ(reg, 1, 1)
/* definitions for field: Next Page Able in reg: MDIO Auto-Negotiation Expansion Register */
#define MDIO_EXPANSION_ENABLENPAGE_MASK WBGEN2_GEN_MASK(2, 1)
#define MDIO_EXPANSION_ENABLENPAGE_SHIFT 2
#define MDIO_EXPANSION_ENABLENPAGE_W(value) WBGEN2_GEN_WRITE(value, 2, 1)
#define MDIO_EXPANSION_ENABLENPAGE_R(reg) WBGEN2_GEN_READ(reg, 2, 1)
/* definitions for field: Reserved in reg: MDIO Auto-Negotiation Expansion Register */
#define MDIO_EXPANSION_RSVD2_MASK WBGEN2_GEN_MASK(3, 13)
#define MDIO_EXPANSION_RSVD2_SHIFT 3
#define MDIO_EXPANSION_RSVD2_W(value) WBGEN2_GEN_WRITE(value, 3, 13)
#define MDIO_EXPANSION_RSVD2_R(reg) WBGEN2_GEN_READ(reg, 3, 13)
/* definitions for register: MDIO Extended Status Register */
/* definitions for field: Reserved in reg: MDIO Extended Status Register */
#define MDIO_ESTATUS_RSVD1_MASK WBGEN2_GEN_MASK(0, 12)
#define MDIO_ESTATUS_RSVD1_SHIFT 0
#define MDIO_ESTATUS_RSVD1_W(value) WBGEN2_GEN_WRITE(value, 0, 12)
#define MDIO_ESTATUS_RSVD1_R(reg) WBGEN2_GEN_READ(reg, 0, 12)
/* definitions for field: 1000Base-T Half Duplex in reg: MDIO Extended Status Register */
#define MDIO_ESTATUS_1000_THALF_MASK WBGEN2_GEN_MASK(12, 1)
#define MDIO_ESTATUS_1000_THALF_SHIFT 12
#define MDIO_ESTATUS_1000_THALF_W(value) WBGEN2_GEN_WRITE(value, 12, 1)
#define MDIO_ESTATUS_1000_THALF_R(reg) WBGEN2_GEN_READ(reg, 12, 1)
/* definitions for field: 1000Base-T Full Duplex in reg: MDIO Extended Status Register */
#define MDIO_ESTATUS_1000_TFULL_MASK WBGEN2_GEN_MASK(13, 1)
#define MDIO_ESTATUS_1000_TFULL_SHIFT 13
#define MDIO_ESTATUS_1000_TFULL_W(value) WBGEN2_GEN_WRITE(value, 13, 1)
#define MDIO_ESTATUS_1000_TFULL_R(reg) WBGEN2_GEN_READ(reg, 13, 1)
/* definitions for field: 1000Base-X Half Duplex in reg: MDIO Extended Status Register */
#define MDIO_ESTATUS_1000_XHALF_MASK WBGEN2_GEN_MASK(14, 1)
#define MDIO_ESTATUS_1000_XHALF_SHIFT 14
#define MDIO_ESTATUS_1000_XHALF_W(value) WBGEN2_GEN_WRITE(value, 14, 1)
#define MDIO_ESTATUS_1000_XHALF_R(reg) WBGEN2_GEN_READ(reg, 14, 1)
/* definitions for field: 1000Base-X Full Duplex in reg: MDIO Extended Status Register */
#define MDIO_ESTATUS_1000_XFULL_MASK WBGEN2_GEN_MASK(15, 1)
#define MDIO_ESTATUS_1000_XFULL_SHIFT 15
#define MDIO_ESTATUS_1000_XFULL_W(value) WBGEN2_GEN_WRITE(value, 15, 1)
#define MDIO_ESTATUS_1000_XFULL_R(reg) WBGEN2_GEN_READ(reg, 15, 1)
/* definitions for register: WhiteRabbit-specific Configuration Register */
/* definitions for field: TX Calibration Pattern in reg: WhiteRabbit-specific Configuration Register */
#define MDIO_WR_SPEC_TX_CAL WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Calibration Pattern RX Status in reg: WhiteRabbit-specific Configuration Register */
#define MDIO_WR_SPEC_RX_CAL_STAT WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Reset calibration counter in reg: WhiteRabbit-specific Configuration Register */
#define MDIO_WR_SPEC_CAL_CRST WBGEN2_GEN_MASK(2, 1)
/* definitions for field: GTP RX Bitslide in reg: WhiteRabbit-specific Configuration Register */
#define MDIO_WR_SPEC_BSLIDE_MASK WBGEN2_GEN_MASK(4, 4)
#define MDIO_WR_SPEC_BSLIDE_SHIFT 4
#define MDIO_WR_SPEC_BSLIDE_W(value) WBGEN2_GEN_WRITE(value, 4, 4)
#define MDIO_WR_SPEC_BSLIDE_R(reg) WBGEN2_GEN_READ(reg, 4, 4)
/* [0x0]: REG MDIO Control Register */
#define MDIO_REG_MCR 0x00000000
/* [0x4]: REG MDIO Status Register */
#define MDIO_REG_MSR 0x00000004
/* [0x8]: REG MDIO PHY Identification Register 1 */
#define MDIO_REG_PHYSID1 0x00000008
/* [0xc]: REG MDIO PHY Identification Register 2 */
#define MDIO_REG_PHYSID2 0x0000000c
/* [0x10]: REG MDIO Auto-Negotiation Advertisement Register */
#define MDIO_REG_ADVERTISE 0x00000010
/* [0x14]: REG MDIO Auto-Negotiation Link Partner Ability Register */
#define MDIO_REG_LPA 0x00000014
/* [0x18]: REG MDIO Auto-Negotiation Expansion Register */
#define MDIO_REG_EXPANSION 0x00000018
/* [0x3c]: REG MDIO Extended Status Register */
#define MDIO_REG_ESTATUS 0x0000003c
/* [0x40]: REG WhiteRabbit-specific Configuration Register */
#define MDIO_REG_WR_SPEC 0x00000040
#endif
/*
Register definitions for slave core: WR switch endpoint controller
* File : endpoint_regs.h
* Author : auto-generated by wbgen2 from ep_wishbone_controller.wb
* Created : Wed Apr 6 22:46:02 2011
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ep_wishbone_controller.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_EP_WISHBONE_CONTROLLER_WB
#define __WBGEN2_REGDEFS_EP_WISHBONE_CONTROLLER_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Endpoint Control Register */
/* definitions for field: Port identifier in reg: Endpoint Control Register */
#define EP_ECR_PORTID_MASK WBGEN2_GEN_MASK(0, 5)
#define EP_ECR_PORTID_SHIFT 0
#define EP_ECR_PORTID_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define EP_ECR_PORTID_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: Reset event counters in reg: Endpoint Control Register */
#define EP_ECR_RST_CNT WBGEN2_GEN_MASK(5, 1)
/* definitions for field: Transmit framer enable in reg: Endpoint Control Register */
#define EP_ECR_TX_EN_FRA WBGEN2_GEN_MASK(6, 1)
/* definitions for field: Receive deframer enable in reg: Endpoint Control Register */
#define EP_ECR_RX_EN_FRA WBGEN2_GEN_MASK(7, 1)
/* definitions for register: Timestamping Control Register */
/* definitions for field: Transmit timestamping enable in reg: Timestamping Control Register */
#define EP_TSCR_EN_TXTS WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Receive timestamping enable in reg: Timestamping Control Register */
#define EP_TSCR_EN_RXTS WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Timestamping counter synchronization start in reg: Timestamping Control Register */
#define EP_TSCR_CS_START WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Timestamping counter synchronization done in reg: Timestamping Control Register */
#define EP_TSCR_CS_DONE WBGEN2_GEN_MASK(3, 1)
/* definitions for register: RX Deframer Control Register */
/* definitions for field: RX accept runts in reg: RX Deframer Control Register */
#define EP_RFCR_A_RUNT WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX accept giants in reg: RX Deframer Control Register */
#define EP_RFCR_A_GIANT WBGEN2_GEN_MASK(1, 1)
/* definitions for field: RX accept HP in reg: RX Deframer Control Register */
#define EP_RFCR_A_HP WBGEN2_GEN_MASK(2, 1)
/* definitions for field: RX accept fragments in reg: RX Deframer Control Register */
#define EP_RFCR_A_FRAG WBGEN2_GEN_MASK(3, 1)
/* definitions for field: RX 802.1q port mode in reg: RX Deframer Control Register */
#define EP_RFCR_QMODE_MASK WBGEN2_GEN_MASK(4, 2)
#define EP_RFCR_QMODE_SHIFT 4
#define EP_RFCR_QMODE_W(value) WBGEN2_GEN_WRITE(value, 4, 2)
#define EP_RFCR_QMODE_R(reg) WBGEN2_GEN_READ(reg, 4, 2)
/* definitions for field: Force 802.1q priority in reg: RX Deframer Control Register */
#define EP_RFCR_FIX_PRIO WBGEN2_GEN_MASK(6, 1)
/* definitions for field: Port-assigned 802.1x priority in reg: RX Deframer Control Register */
#define EP_RFCR_PRIO_VAL_MASK WBGEN2_GEN_MASK(8, 3)
#define EP_RFCR_PRIO_VAL_SHIFT 8
#define EP_RFCR_PRIO_VAL_W(value) WBGEN2_GEN_WRITE(value, 8, 3)
#define EP_RFCR_PRIO_VAL_R(reg) WBGEN2_GEN_READ(reg, 8, 3)
/* definitions for field: Port-assigned VID in reg: RX Deframer Control Register */
#define EP_RFCR_VID_VAL_MASK WBGEN2_GEN_MASK(16, 12)
#define EP_RFCR_VID_VAL_SHIFT 16
#define EP_RFCR_VID_VAL_W(value) WBGEN2_GEN_WRITE(value, 16, 12)
#define EP_RFCR_VID_VAL_R(reg) WBGEN2_GEN_READ(reg, 16, 12)
/* definitions for register: Flow Control Register */
/* definitions for field: RX Pause enable in reg: Flow Control Register */
#define EP_FCR_RXPAUSE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: TX Pause enable in reg: Flow Control Register */
#define EP_FCR_TXPAUSE WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX pause threshold in reg: Flow Control Register */
#define EP_FCR_TX_THR_MASK WBGEN2_GEN_MASK(8, 8)
#define EP_FCR_TX_THR_SHIFT 8
#define EP_FCR_TX_THR_W(value) WBGEN2_GEN_WRITE(value, 8, 8)
#define EP_FCR_TX_THR_R(reg) WBGEN2_GEN_READ(reg, 8, 8)
/* definitions for field: TX pause quanta in reg: Flow Control Register */
#define EP_FCR_TX_QUANTA_MASK WBGEN2_GEN_MASK(16, 16)
#define EP_FCR_TX_QUANTA_SHIFT 16
#define EP_FCR_TX_QUANTA_W(value) WBGEN2_GEN_WRITE(value, 16, 16)
#define EP_FCR_TX_QUANTA_R(reg) WBGEN2_GEN_READ(reg, 16, 16)
/* definitions for register: Endpoint MAC address high part register */
/* definitions for register: Endpoint MAC address low part register */
/* definitions for register: DMTD Control Register */
/* definitions for field: DMTD Phase measurement enable in reg: DMTD Control Register */
#define EP_DMCR_EN WBGEN2_GEN_MASK(0, 1)
/* definitions for field: DMTD averaging samples in reg: DMTD Control Register */
#define EP_DMCR_N_AVG_MASK WBGEN2_GEN_MASK(16, 12)
#define EP_DMCR_N_AVG_SHIFT 16
#define EP_DMCR_N_AVG_W(value) WBGEN2_GEN_WRITE(value, 16, 12)
#define EP_DMCR_N_AVG_R(reg) WBGEN2_GEN_READ(reg, 16, 12)
/* definitions for register: DMTD Status register */
/* definitions for field: DMTD Phase shift value in reg: DMTD Status register */
#define EP_DMSR_PS_VAL_MASK WBGEN2_GEN_MASK(0, 24)
#define EP_DMSR_PS_VAL_SHIFT 0
#define EP_DMSR_PS_VAL_W(value) WBGEN2_GEN_WRITE(value, 0, 24)
#define EP_DMSR_PS_VAL_R(reg) WBGEN2_GEN_READ(reg, 0, 24)
/* definitions for field: DMTD Phase shift value ready in reg: DMTD Status register */
#define EP_DMSR_PS_RDY WBGEN2_GEN_MASK(24, 1)
/* definitions for register: MDIO Control Register */
/* definitions for field: MDIO Register Value in reg: MDIO Control Register */
#define EP_MDIO_CR_DATA_MASK WBGEN2_GEN_MASK(0, 16)
#define EP_MDIO_CR_DATA_SHIFT 0
#define EP_MDIO_CR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define EP_MDIO_CR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: MDIO Register Address in reg: MDIO Control Register */
#define EP_MDIO_CR_ADDR_MASK WBGEN2_GEN_MASK(16, 8)
#define EP_MDIO_CR_ADDR_SHIFT 16
#define EP_MDIO_CR_ADDR_W(value) WBGEN2_GEN_WRITE(value, 16, 8)
#define EP_MDIO_CR_ADDR_R(reg) WBGEN2_GEN_READ(reg, 16, 8)
/* definitions for field: MDIO Read/Write select in reg: MDIO Control Register */
#define EP_MDIO_CR_RW WBGEN2_GEN_MASK(31, 1)
/* definitions for register: MDIO Status Register */
/* definitions for field: MDIO Read Value in reg: MDIO Status Register */
#define EP_MDIO_SR_RDATA_MASK WBGEN2_GEN_MASK(0, 16)
#define EP_MDIO_SR_RDATA_SHIFT 0
#define EP_MDIO_SR_RDATA_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define EP_MDIO_SR_RDATA_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: MDIO Ready in reg: MDIO Status Register */
#define EP_MDIO_SR_READY WBGEN2_GEN_MASK(31, 1)
/* definitions for register: Identification register */
/* definitions for register: Debug/Status register */
/* definitions for field: Link status in reg: Debug/Status register */
#define EP_DSR_LSTATUS WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Link activity in reg: Debug/Status register */
#define EP_DSR_LACT WBGEN2_GEN_MASK(1, 1)
/* definitions for RAM: Event counters memory */
#define EP_RMON_RAM_BYTES 0x00000080 /* size in bytes */
#define EP_RMON_RAM_WORDS 0x00000020 /* size in 32-bit words, 32-bit aligned */
PACKED struct EP_WB {
/* [0x0]: REG Endpoint Control Register */
uint32_t ECR;
/* [0x4]: REG Timestamping Control Register */
uint32_t TSCR;
/* [0x8]: REG RX Deframer Control Register */
uint32_t RFCR;
/* [0xc]: REG Flow Control Register */
uint32_t FCR;
/* [0x10]: REG Endpoint MAC address high part register */
uint32_t MACH;
/* [0x14]: REG Endpoint MAC address low part register */
uint32_t MACL;
/* [0x18]: REG DMTD Control Register */
uint32_t DMCR;
/* [0x1c]: REG DMTD Status register */
uint32_t DMSR;
/* [0x20]: REG MDIO Control Register */
uint32_t MDIO_CR;
/* [0x24]: REG MDIO Status Register */
uint32_t MDIO_SR;
/* [0x28]: REG Identification register */
uint32_t IDCODE;
/* [0x2c]: REG Debug/Status register */
uint32_t DSR;
/* padding to: 32 words */
uint32_t __padding_0[20];
/* [0x80 - 0xff]: RAM Event counters memory, 32 32-bit words, 32-bit aligned, word-addressable */
uint32_t RMON_RAM [32];
};
#endif
/*
Register definitions for slave core: Mini NIC for WhiteRabbit
* File : ../../../software/include/hw/minic_regs.h
* Author : auto-generated by wbgen2 from mini_nic.wb
* Created : Fri Aug 13 02:17:20 2010
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE mini_nic.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_MINI_NIC_WB
#define __WBGEN2_REGDEFS_MINI_NIC_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: miNIC Control Register */
/* definitions for field: TX DMA start in reg: miNIC Control Register */
#define MINIC_MCR_TX_START WBGEN2_GEN_MASK(0, 1)
/* definitions for field: TX DMA idle in reg: miNIC Control Register */
#define MINIC_MCR_TX_IDLE WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX DMA error in reg: miNIC Control Register */
#define MINIC_MCR_TX_ERROR WBGEN2_GEN_MASK(2, 1)
/* definitions for field: RX DMA ready in reg: miNIC Control Register */
#define MINIC_MCR_RX_READY WBGEN2_GEN_MASK(8, 1)
/* definitions for field: RX DMA buffer full in reg: miNIC Control Register */
#define MINIC_MCR_RX_FULL WBGEN2_GEN_MASK(9, 1)
/* definitions for field: RX DMA enable in reg: miNIC Control Register */
#define MINIC_MCR_RX_EN WBGEN2_GEN_MASK(10, 1)
/* definitions for register: TX DMA Address */
/* definitions for register: RX DMA Address */
/* definitions for register: RX buffer size register */
/* definitions for register: Debug register */
/* definitions for field: interrupt counter in reg: Debug register */
#define MINIC_DBGR_IRQ_CNT_MASK WBGEN2_GEN_MASK(0, 24)
#define MINIC_DBGR_IRQ_CNT_SHIFT 0
#define MINIC_DBGR_IRQ_CNT_W(value) WBGEN2_GEN_WRITE(value, 0, 24)
#define MINIC_DBGR_IRQ_CNT_R(reg) WBGEN2_GEN_READ(reg, 0, 24)
/* definitions for field: status of wb_irq_o line in reg: Debug register */
#define MINIC_DBGR_WB_IRQ_VAL WBGEN2_GEN_MASK(24, 1)
/* definitions for register: Interrupt disable register */
/* definitions for field: TX DMA interrupt in reg: Interrupt disable register */
#define MINIC_EIC_IDR_TX WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX DMA interrupt in reg: Interrupt disable register */
#define MINIC_EIC_IDR_RX WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX timestamp available in reg: Interrupt disable register */
#define MINIC_EIC_IDR_TXTS WBGEN2_GEN_MASK(2, 1)
/* definitions for register: Interrupt enable register */
/* definitions for field: TX DMA interrupt in reg: Interrupt enable register */
#define MINIC_EIC_IER_TX WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX DMA interrupt in reg: Interrupt enable register */
#define MINIC_EIC_IER_RX WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX timestamp available in reg: Interrupt enable register */
#define MINIC_EIC_IER_TXTS WBGEN2_GEN_MASK(2, 1)
/* definitions for register: Interrupt mask register */
/* definitions for field: TX DMA interrupt in reg: Interrupt mask register */
#define MINIC_EIC_IMR_TX WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX DMA interrupt in reg: Interrupt mask register */
#define MINIC_EIC_IMR_RX WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX timestamp available in reg: Interrupt mask register */
#define MINIC_EIC_IMR_TXTS WBGEN2_GEN_MASK(2, 1)
/* definitions for register: Interrupt status register */
/* definitions for field: TX DMA interrupt in reg: Interrupt status register */
#define MINIC_EIC_ISR_TX WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX DMA interrupt in reg: Interrupt status register */
#define MINIC_EIC_ISR_RX WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX timestamp available in reg: Interrupt status register */
#define MINIC_EIC_ISR_TXTS WBGEN2_GEN_MASK(2, 1)
/* definitions for register: FIFO 'TX timestamp FIFO' data output register 0 */
/* definitions for field: Timestamp value in reg: FIFO 'TX timestamp FIFO' data output register 0 */
#define MINIC_TSFIFO_R0_TSVAL_MASK WBGEN2_GEN_MASK(0, 32)
#define MINIC_TSFIFO_R0_TSVAL_SHIFT 0
#define MINIC_TSFIFO_R0_TSVAL_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define MINIC_TSFIFO_R0_TSVAL_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: FIFO 'TX timestamp FIFO' data output register 1 */
/* definitions for field: Port ID in reg: FIFO 'TX timestamp FIFO' data output register 1 */
#define MINIC_TSFIFO_R1_PID_MASK WBGEN2_GEN_MASK(0, 5)
#define MINIC_TSFIFO_R1_PID_SHIFT 0
#define MINIC_TSFIFO_R1_PID_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define MINIC_TSFIFO_R1_PID_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: Frame ID in reg: FIFO 'TX timestamp FIFO' data output register 1 */
#define MINIC_TSFIFO_R1_FID_MASK WBGEN2_GEN_MASK(5, 16)
#define MINIC_TSFIFO_R1_FID_SHIFT 5
#define MINIC_TSFIFO_R1_FID_W(value) WBGEN2_GEN_WRITE(value, 5, 16)
#define MINIC_TSFIFO_R1_FID_R(reg) WBGEN2_GEN_READ(reg, 5, 16)
/* definitions for register: FIFO 'TX timestamp FIFO' control/status register */
/* definitions for field: FIFO empty flag in reg: FIFO 'TX timestamp FIFO' control/status register */
#define MINIC_TSFIFO_CSR_EMPTY WBGEN2_GEN_MASK(17, 1)
/* [0x0]: REG miNIC Control Register */
#define MINIC_REG_MCR 0x00000000
/* [0x4]: REG TX DMA Address */
#define MINIC_REG_TX_ADDR 0x00000004
/* [0x8]: REG RX DMA Address */
#define MINIC_REG_RX_ADDR 0x00000008
/* [0xc]: REG RX buffer size register */
#define MINIC_REG_RX_AVAIL 0x0000000c
/* [0x10]: REG Debug register */
#define MINIC_REG_DBGR 0x00000010
/* [0x20]: REG Interrupt disable register */
#define MINIC_REG_EIC_IDR 0x00000020
/* [0x24]: REG Interrupt enable register */
#define MINIC_REG_EIC_IER 0x00000024
/* [0x28]: REG Interrupt mask register */
#define MINIC_REG_EIC_IMR 0x00000028
/* [0x2c]: REG Interrupt status register */
#define MINIC_REG_EIC_ISR 0x0000002c
/* [0x30]: REG FIFO 'TX timestamp FIFO' data output register 0 */
#define MINIC_REG_TSFIFO_R0 0x00000030
/* [0x34]: REG FIFO 'TX timestamp FIFO' data output register 1 */
#define MINIC_REG_TSFIFO_R1 0x00000034
/* [0x38]: REG FIFO 'TX timestamp FIFO' control/status register */
#define MINIC_REG_TSFIFO_CSR 0x00000038
#endif
/*
Register definitions for slave core: WR Switch PPS generator and RTC
* File : ../../../software/include/hw/pps_gen_regs.h
* Author : auto-generated by wbgen2 from wrsw_pps_gen.wb
* Created : Sat Sep 11 22:22:55 2010
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrsw_pps_gen.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WRSW_PPS_GEN_WB
#define __WBGEN2_REGDEFS_WRSW_PPS_GEN_WB
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Control Register */
/* definitions for field: Reset counter in reg: Control Register */
#define PPSG_CR_CNT_RST WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Enable counter in reg: Control Register */
#define PPSG_CR_CNT_EN WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Adjust offset in reg: Control Register */
#define PPSG_CR_CNT_ADJ WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Set time in reg: Control Register */
#define PPSG_CR_CNT_SET WBGEN2_GEN_MASK(3, 1)
/* definitions for field: PPS Pulse width in reg: Control Register */
#define PPSG_CR_PWIDTH_MASK WBGEN2_GEN_MASK(4, 28)
#define PPSG_CR_PWIDTH_SHIFT 4
#define PPSG_CR_PWIDTH_W(value) WBGEN2_GEN_WRITE(value, 4, 28)
#define PPSG_CR_PWIDTH_R(reg) WBGEN2_GEN_READ(reg, 4, 28)
/* definitions for register: Nanosecond counter register */
/* definitions for register: UTC Counter register (least-significant part) */
/* definitions for register: UTC Counter register (most-significant part) */
/* definitions for register: Nanosecond adjustment register */
/* definitions for register: UTC Adjustment register (least-significant part) */
/* definitions for register: UTC Adjustment register (most-significant part) */
/* [0x0]: REG Control Register */
#define PPSG_REG_CR 0x00000000
/* [0x4]: REG Nanosecond counter register */
#define PPSG_REG_CNTR_NSEC 0x00000004
/* [0x8]: REG UTC Counter register (least-significant part) */
#define PPSG_REG_CNTR_UTCLO 0x00000008
/* [0xc]: REG UTC Counter register (most-significant part) */
#define PPSG_REG_CNTR_UTCHI 0x0000000c
/* [0x10]: REG Nanosecond adjustment register */
#define PPSG_REG_ADJ_NSEC 0x00000010
/* [0x14]: REG UTC Adjustment register (least-significant part) */
#define PPSG_REG_ADJ_UTCLO 0x00000014
/* [0x18]: REG UTC Adjustment register (most-significant part) */
#define PPSG_REG_ADJ_UTCHI 0x00000018
#endif
/*
Register definitions for slave core: WR Softcore PLL
* File : softpll_regs.h
* Author : auto-generated by wbgen2 from wr_softpll.wb
* Created : Sat Apr 9 13:29:44 2011
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_softpll.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WR_SOFTPLL_WB
#define __WBGEN2_REGDEFS_WR_SOFTPLL_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: SPLL Control/Status Register */
/* definitions for field: Tagger enable in reg: SPLL Control/Status Register */
#define SPLL_CSR_TAG_EN_MASK WBGEN2_GEN_MASK(0, 4)
#define SPLL_CSR_TAG_EN_SHIFT 0
#define SPLL_CSR_TAG_EN_W(value) WBGEN2_GEN_WRITE(value, 0, 4)
#define SPLL_CSR_TAG_EN_R(reg) WBGEN2_GEN_READ(reg, 0, 4)
/* definitions for field: Tag ready in reg: SPLL Control/Status Register */
#define SPLL_CSR_TAG_RDY_MASK WBGEN2_GEN_MASK(4, 4)
#define SPLL_CSR_TAG_RDY_SHIFT 4
#define SPLL_CSR_TAG_RDY_W(value) WBGEN2_GEN_WRITE(value, 4, 4)
#define SPLL_CSR_TAG_RDY_R(reg) WBGEN2_GEN_READ(reg, 4, 4)
/* definitions for register: HPLL Frequency Error */
/* definitions for register: DMPLL Tag ref */
/* definitions for register: DMPLL Tag fb */
/* definitions for register: HPLL DAC Output */
/* definitions for register: DMPLL DAC Output */
/* definitions for register: Deglitcher threshold */
/* definitions for register: Interrupt disable register */
/* definitions for field: Got a tag in reg: Interrupt disable register */
#define SPLL_EIC_IDR_TAG WBGEN2_GEN_MASK(0, 1)
/* definitions for register: Interrupt enable register */
/* definitions for field: Got a tag in reg: Interrupt enable register */
#define SPLL_EIC_IER_TAG WBGEN2_GEN_MASK(0, 1)
/* definitions for register: Interrupt mask register */
/* definitions for field: Got a tag in reg: Interrupt mask register */
#define SPLL_EIC_IMR_TAG WBGEN2_GEN_MASK(0, 1)
/* definitions for register: Interrupt status register */
/* definitions for field: Got a tag in reg: Interrupt status register */
#define SPLL_EIC_ISR_TAG WBGEN2_GEN_MASK(0, 1)
PACKED struct SPLL_WB {
/* [0x0]: REG SPLL Control/Status Register */
uint32_t CSR;
/* [0x4]: REG HPLL Frequency Error */
uint32_t PER_HPLL;
/* [0x8]: REG DMPLL Tag ref */
uint32_t TAG_REF;
/* [0xc]: REG DMPLL Tag fb */
uint32_t TAG_FB;
/* [0x10]: REG HPLL DAC Output */
uint32_t DAC_HPLL;
/* [0x14]: REG DMPLL DAC Output */
uint32_t DAC_DMPLL;
/* [0x18]: REG Deglitcher threshold */
uint32_t DEGLITCH_THR;
/* padding to: 8 words */
uint32_t __padding_0[1];
/* [0x20]: REG Interrupt disable register */
uint32_t EIC_IDR;
/* [0x24]: REG Interrupt enable register */
uint32_t EIC_IER;
/* [0x28]: REG Interrupt mask register */
uint32_t EIC_IMR;
/* [0x2c]: REG Interrupt status register */
uint32_t EIC_ISR;
};
#endif
/*
Register definitions for slave core: Simple Wishbone UART
* File : ../../../../software/include/hw/wb_uart.h
* Author : auto-generated by wbgen2 from uart.wb
* Created : Mon Feb 21 22:25:02 2011
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE uart.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_UART_WB
#define __WBGEN2_REGDEFS_UART_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Status Register */
/* definitions for field: TX busy in reg: Status Register */
#define UART_SR_TX_BUSY WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX ready in reg: Status Register */
#define UART_SR_RX_RDY WBGEN2_GEN_MASK(1, 1)
/* definitions for register: Baudrate control register */
/* definitions for register: Transmit data regsiter */
/* definitions for field: Transmit data in reg: Transmit data regsiter */
#define UART_TDR_TX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_TDR_TX_DATA_SHIFT 0
#define UART_TDR_TX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_TDR_TX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Receive data regsiter */
/* definitions for field: Received data in reg: Receive data regsiter */
#define UART_RDR_RX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_RDR_RX_DATA_SHIFT 0
#define UART_RDR_RX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_RDR_RX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* [0x0]: REG Status Register */
#define UART_REG_SR 0x00000000
/* [0x4]: REG Baudrate control register */
#define UART_REG_BCR 0x00000004
/* [0x8]: REG Transmit data regsiter */
#define UART_REG_TDR 0x00000008
/* [0xc]: REG Receive data regsiter */
#define UART_REG_RDR 0x0000000c
PACKED struct UART_WB {
/* [0x0]: REG Status Register */
uint32_t SR;
/* [0x4]: REG Baudrate control register */
uint32_t BCR;
/* [0x8]: REG Transmit data regsiter */
uint32_t TDR;
/* [0xc]: REG Receive data regsiter */
uint32_t RDR;
};
#endif
/*
Register definitions for slave core: Virtual UART
* File : wb_vuart.h
* Author : auto-generated by wbgen2 from wb_virtual_uart.wb
* Created : Wed Apr 6 23:02:01 2011
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wb_virtual_uart.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WB_VIRTUAL_UART_WB
#define __WBGEN2_REGDEFS_WB_VIRTUAL_UART_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Status Register */
/* definitions for field: TX busy in reg: Status Register */
#define UART_SR_TX_BUSY WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX ready in reg: Status Register */
#define UART_SR_RX_RDY WBGEN2_GEN_MASK(1, 1)
/* definitions for register: Baudrate control register */
/* definitions for register: Transmit data regsiter */
/* definitions for field: Transmit data in reg: Transmit data regsiter */
#define UART_TDR_TX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_TDR_TX_DATA_SHIFT 0
#define UART_TDR_TX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_TDR_TX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: Receive data regsiter */
/* definitions for field: Received data in reg: Receive data regsiter */
#define UART_RDR_RX_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_RDR_RX_DATA_SHIFT 0
#define UART_RDR_RX_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_RDR_RX_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: FIFO 'UART TX FIFO' data output register 0 */
/* definitions for field: Char sent by UART to TX in reg: FIFO 'UART TX FIFO' data output register 0 */
#define UART_DEBUG_R0_TX_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_DEBUG_R0_TX_SHIFT 0
#define UART_DEBUG_R0_TX_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_DEBUG_R0_TX_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: FIFO 'UART TX FIFO' control/status register */
/* definitions for field: FIFO full flag in reg: FIFO 'UART TX FIFO' control/status register */
#define UART_DEBUG_CSR_FULL WBGEN2_GEN_MASK(16, 1)
/* definitions for field: FIFO empty flag in reg: FIFO 'UART TX FIFO' control/status register */
#define UART_DEBUG_CSR_EMPTY WBGEN2_GEN_MASK(17, 1)
/* definitions for field: FIFO counter in reg: FIFO 'UART TX FIFO' control/status register */
#define UART_DEBUG_CSR_USEDW_MASK WBGEN2_GEN_MASK(0, 8)
#define UART_DEBUG_CSR_USEDW_SHIFT 0
#define UART_DEBUG_CSR_USEDW_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define UART_DEBUG_CSR_USEDW_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
PACKED struct UART_WB {
/* [0x0]: REG Status Register */
uint32_t SR;
/* [0x4]: REG Baudrate control register */
uint32_t BCR;
/* [0x8]: REG Transmit data regsiter */
uint32_t TDR;
/* [0xc]: REG Receive data regsiter */
uint32_t RDR;
/* [0x10]: REG FIFO 'UART TX FIFO' data output register 0 */
uint32_t DEBUG_R0;
/* [0x14]: REG FIFO 'UART TX FIFO' control/status register */
uint32_t DEBUG_CSR;
};
#endif
/* wb-gen file we use insist in using <inttypes.h>: work around them by now */
#include <stdint.h>
#ifndef __ARCH_SPEC_STDINT_H__
#define __ARCH_SPEC_STDINT_H__
/*
* We miss a stdint.h in our compiler, so provide some types here,
* knowing the CPU is 32-bits and uses LP32 model
*/
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;
#endif /* __ARCH_SPEC_STDINT_H__ */
/*
* Alessandro Rubini for CERN, 2011 -- GNU LGPL v2.1 or later
*/
/*
* This is the main loop for the Spec board
*/
#include <pproto/pproto.h>
#include "spec.h"
void spec_main_loop(struct pp_instance *ppi)
{
int i, delay_ms;
/*
* The main loop here is polling every ms. While we are not
* doing anything else but the protocol, this allows extra stuff
* to fit.
*/
delay_ms = pp_state_machine(ppi, NULL, 0);
while (1) {
unsigned char packet[1500];
/* Wait for a packet or for the timeout */
while (delay_ms && !minic_poll_rx()) {
spec_udelay(1000);
delay_ms--;
}
if (!minic_poll_rx()) {
delay_ms = pp_state_machine(ppi, NULL, 0);
continue;
}
/*
* We got a packet. If it's not ours, continue consuming
* the pending timeout
*/
i = spec_recv_packet(ppi, packet, sizeof(packet));
if (0) {
int j;
pp_printf("recvd: %i\n", i);
for (j = 0; j < 32 && j < i; j++)
pp_printf(" %02x", packet[j]);
pp_printf("\n");
}
if (i < sizeof(struct pp_packet) /* or minimum of all pckts */)
continue;
/* Warning: PP_PROTO_NR is endian-agnostic by design */
if ( ((struct spec_ethhdr *)packet)->h_proto !=
htons(PP_PROTO_NR))
continue;
delay_ms = pp_state_machine(ppi, packet, i);
}
}
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
#include <pproto/pproto.h>
#include <hw/wb_uart.h>
#include "spec.h"
void pp_puts(const char *s)
{
spec_puts(s);
}
int pp_strnlen(const char *s, int maxlen)
{
int len = 0;
while (*(s++)) len++;
return len;
}
void *pp_memcpy(void * dest, const void *src, int count)
{
/* from u-boot-1.1.2 */
char *tmp = (char *) dest, *s = (char *) src;
while (count--)
*tmp++ = *s++;
return dest;
}
void pp_get_stamp(uint32_t *sptr)
{
*sptr = htonl(spec_time());
}
/* What follows has no prefix because it's only used by arch code */
char *strcpy(char *dest, const char *src)
{
/* from u-boot-1.1.2 */
char *tmp = dest;
while ((*dest++ = *src++) != '\0')
/* nothing */;
return tmp;
}
void *memset(void *s, int c, int count)
{
/* from u-boot-1.1.2 */
char *xs = (char *) s;
while (count--)
*xs++ = c;
return s;
}
void *memcpy(void *dest, const void *src, int count)
{
/* from u-boot-1.1.2 */
char *tmp = (char *) dest, *s = (char *) src;
while (count--)
*tmp++ = *s++;
return dest;
}
/*
* Alessandro Rubini for CERN, 2011 -- GNU LGPL v2.1 or later
*/
#include <pproto/pproto.h>
#include "spec.h"
#include "include/gpio.h"
int spec_errno;
/* This function should init the minic and get the mac address */
int spec_open_ch(struct pp_instance *ppi)
{
uint8_t fake_addr[] = {0x00, 0x10, 0x20, 0x30, 0x40, 0x50};
ep_init(fake_addr);
ep_enable(1,1);
minic_init();
memcpy(ppi->ch.addr, fake_addr, 6);
return 0;
}
/* To receive and send packets, we call the minic low-level stuff */
int spec_recv_packet(struct pp_instance *ppi, void *pkt, int len)
{
static int led = 0;
led ^= 1; /* blink one led at each rx event */
gpio_out(GPIO_PIN_LED_LINK, led);
return minic_rx_frame(pkt, pkt + 14, len - 14, NULL);
}
int spec_send_packet(struct pp_instance *ppi, void *pkt, int len)
{
static int led = 0;
led ^= 1; /* blink the other led at each tx event */
gpio_out(GPIO_PIN_LED_STATUS, led);
return minic_tx_frame(pkt, pkt + 14, len, NULL);
}
int pp_recv_packet(struct pp_instance *ppi, void *pkt, int len)
__attribute__((alias("spec_recv_packet")));
int pp_send_packet(struct pp_instance *ppi, void *pkt, int len)
__attribute__((alias("spec_send_packet")));
/*
* Alessandro Rubini for CERN, 2011 -- GNU LGPL v2.1 or later
*/
#include <pproto/pproto.h>
#include "spec.h"
#include "include/gpio.h"
static struct pp_instance ppi_static;
void pproto_main(void)
{
struct pp_instance *ppi = &ppi_static; /* no malloc, one instance */
spec_uart_init();
pp_puts("Spec: starting. Compiled on " __DATE__ "\n");
/* leds are off and button is input */
gpio_dir(GPIO_PIN_BTN1, 0);
gpio_dir(GPIO_PIN_LED_LINK, 1);
gpio_dir(GPIO_PIN_LED_STATUS, 1);
gpio_out(GPIO_PIN_LED_LINK, 0);
gpio_out(GPIO_PIN_LED_STATUS, 0);
if (spec_open_ch(ppi)) {
pp_diag_error(ppi, spec_errno);
pp_diag_fatal(ppi, "open_ch", "");
}
pp_open_instance(ppi);
spec_main_loop(ppi);
}
/* Our crt0.S is unchanged: it wants a "main" function, and "_irq_entry" too" */
int main(void) __attribute__((alias("pproto_main")));
void _irq_entry(void)
{
return;
}
/*
* Alessandro Rubini for CERN, 2011 -- GNU LGPL v2.1 or later
*/
#include <pproto/pproto.h>
/*
* These are the functions provided by the various bare files
*/
extern int spec_open_ch(struct pp_instance *ppi);
extern int spec_recv_packet(struct pp_instance *ppi, void *pkt, int len);
extern int spec_send_packet(struct pp_instance *ppi, void *pkt, int len);
extern void spec_main_loop(struct pp_instance *ppi);
extern void _irq_entry(void); /* unused, to make crt0.S happy */
extern int main(void); /* alias to pproto_main, so crt0.S is happy */
/* basics */
extern void *memset(void *s, int c, int count);
extern char *strcpy(char *dest, const char *src);
extern void *memcpy(void *dest, const void *src, int count);
/* syscall-lookalike */
extern int spec_time(void);
extern void spec_udelay(int usecs);
extern int spec_errno;
/* Dev stuff */
extern void spec_uart_init(void);
extern void spec_putc(int c);
extern void spec_puts(const char *s);
extern int spec_testc(void);
extern int spec_getc(void);
extern void minic_init(void);
extern int minic_poll_rx(void);
struct hw_timestamp;
extern int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size,
struct hw_timestamp *hwts /* unused */);
extern int minic_tx_frame(uint8_t *hdr, uint8_t *payload, uint32_t size,
struct hw_timestamp *hwts /* unused */);
extern void ep_init(uint8_t mac_addr[]);
extern void get_mac_addr(uint8_t dev_addr[]);
extern int ep_enable(int enabled, int autoneg);
extern int ep_link_up();
extern int ep_get_deltas(uint32_t *delta_tx, uint32_t *delta_rx);
extern int ep_get_psval(int32_t *psval);
extern int ep_cal_pattern_enable();
extern int ep_cal_pattern_disable();
/* other network lstuff, bah.... */
struct spec_ethhdr {
unsigned char h_dest[6];
unsigned char h_source[6];
uint16_t h_proto;
} __attribute__((packed));
/* Low-level details (from board.h in wr-core-tools) */
#define BASE_UART 0x60800
#define BASE_GPIO 0x60400
#define BASE_TIMER 0x61000
#define BASE_PPSGEN 0x50000
#define BASE_EP 0x20000
#define BASE_MINIC 0x10000
#define BASE_SOFTPLL 0x40000
#define CPU_CLOCK 62500000ULL
#define UART_BAUDRATE 115200ULL /* not a real UART */
#define GPIO_PIN_LED_LINK 0
#define GPIO_PIN_LED_STATUS 1
#define GPIO_PIN_SCL_OUT 2
#define GPIO_PIN_SDA_OUT 3
#define GPIO_PIN_SDA_IN 4
#define GPIO_PIN_BTN1 5
#define GPIO_PIN_BTN2 6
/* hacks to use code imported from other places (wr-core-software) */
#define TRACE_DEV pp_printf
struct hw_timestamp {
int ahead;
uint32_t utc;
uint32_t nsec;
uint32_t phase;
};
#define DMTD_AVG_SAMPLES 256
#define DMTD_MAX_PHASE 16384
#define NULL 0
/*
* Simulator Link script for Lattice Mico32.
* Contributed by Jon Beniston <jon@beniston.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
OUTPUT_FORMAT("elf32-lm32")
ENTRY(_start)
/*INPUT() */
GROUP(-lgcc -lc)
MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 0x10000
}
SECTIONS
{
.boot : { *(.boot) } > ram
/* Code */
.text :
{
. = ALIGN(4);
_ftext = .;
_ftext_rom = LOADADDR(.text);
*(.text .stub .text.* .gnu.linkonce.t.*)
*(.gnu.warning)
KEEP (*(.init))
KEEP (*(.fini))
/* Constructors and destructors */
KEEP (*crtbegin*.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
KEEP (*crtbegin*.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
KEEP (*(.jcr))
_etext = .;
} > ram =0
/* Exception handlers */
.eh_frame_hdr : { *(.eh_frame_hdr) } > ram
.eh_frame : { KEEP (*(.eh_frame)) } > ram
.gcc_except_table : { *(.gcc_except_table) *(.gcc_except_table.*) } > ram
/* Read-only data */
.rodata :
{
. = ALIGN(4);
_frodata = .;
_frodata_rom = LOADADDR(.rodata);
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
_erodata = .;
} > ram
/* Data */
.data :
{
. = ALIGN(4);
_fdata = .;
_fdata_rom = LOADADDR(.data);
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
SORT(CONSTRUCTORS)
_gp = ALIGN(16) + 0x7ff0;
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > ram
/* BSS */
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
_end = .;
PROVIDE (end = .);
} > ram
/* First location in stack is highest address in RAM */
PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
# Alessandro Rubini for CERN, 2011 -- public domain
# Diagnostics: we have tree levels: none, full and limited
# full: use a complete printf and the diag code
OBJ-$(HAS_FULL_DIAG) += diag/diag-yes.o diag/diag-printf.o diag/printf-full.o
# limited: use a minimal printf (can't coexist with FULL_DIAG)
ifndef HAS_FULL_DIAG
OBJ-$(HAS_DIAG) += diag/diag-yes.o diag/diag-printf.o diag/printf-mini.o
endif
# no diagnostics: the diag-no.c file includes weak aliases to an empty func
OBJ-y += diag/diag-no.o
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
#include <pproto/pproto.h>
/*
* Having no diagnostics, just make one function that returns 0 and alias
* all the rest to it (those returning void will have the caller ignore our 0)
*/
int pp_diag_nop(void)
{
return 0;
}
void pp_diag_fsm(struct pp_instance *ppi, int sequence, int plen)
__attribute__((weak,alias("pp_diag_nop")));
void pp_diag_trace(struct pp_instance *ppi, const char *f, int line)
__attribute__((weak,alias("pp_diag_nop")));
void pp_diag_error(struct pp_instance *ppi, int err)
__attribute__((weak,alias("pp_diag_nop")));
void pp_diag_error_str2(struct pp_instance *ppi, char *s1, char *s2)
__attribute__((weak,alias("pp_diag_nop")));
void pp_diag_fatal(struct pp_instance *ppi, char *s1, char *s2)
__attribute__((weak,alias("pp_diag_nop")));
void pp_diag_printf(struct pp_instance *ppi, char *fmt, ...)
__attribute__((weak,alias("pp_diag_nop")));
int pp_printf(const char *fmt, ...)
__attribute__((weak,alias("pp_diag_nop")));
/*
* Basic printf based on vprintf based on vsprintf
*
* Alessandro Rubini for CERN, 2011 -- public domain
* (please note that the vsprintf is not public domain but GPL)
*/
#include <stdarg.h>
#include <pproto/pproto.h>
#define PP_BUF 128 /* We prefer small targets */
static char print_buf[PP_BUF];
int pp_vprintf(const char *fmt, va_list args)
{
int ret;
ret = pp_vsprintf(print_buf, fmt, args);
pp_puts(print_buf);
return ret;
}
int pp_printf(const char *fmt, ...)
{
va_list args;
int r;
va_start(args, fmt);
r = pp_vprintf(fmt, args);
va_end(args);
return r;
}
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
#include <pproto/pproto.h>
/*
* This has diagnostics. It calls pp_printf (which one, we don't know)
*/
void pp_diag_fsm(struct pp_instance *ppi, int sequence, int plen)
{
if (!sequence) {
/* enter with or without a packet len */
pp_printf("fsm for %p: ENTER %3i (packet len %i)\n",
ppi, ppi->state, plen);
return;
}
/* leave has one \n more, so different states are separate */
pp_printf("fsm for %p: LEAVE %3i (next: %3i in %i ms)\n\n",
ppi, ppi->state, ppi->next_state, ppi->next_delay);
}
void pp_diag_trace(struct pp_instance *ppi, const char *f, int line)
{
pp_printf("TRACE for %p: %s:%i\n", ppi, f, line);
}
void pp_diag_error(struct pp_instance *ppi, int err)
{
pp_printf("ERR for %p: %i\n", ppi, err);
}
void pp_diag_error_str2(struct pp_instance *ppi, char *s1, char *s2)
{
pp_printf("ERR for %p: %s %s\n", ppi, s1, s2);
}
void pp_diag_fatal(struct pp_instance *ppi, char *s1, char *s2)
{
pp_printf("FATAL for %p: %s %s\n", ppi, s1, s2);
while (1)
/* nothing more */;
}
void pp_diag_printf(struct pp_instance *ppi, char *fmt, ...)
{
va_list args;
char buf[128];
va_start(args, fmt);
pp_vsprintf(buf, fmt, args);
va_end(args);
pp_printf("MESSAGE for %p: %s", ppi, buf);
}
/*
* linux/lib/vsprintf.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
* GNU GPL version 2
*/
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
* Wirzenius wrote this portably, Torvalds fucked it up :-)
*/
/* Retrieved from u-boot on 2010-02, changed some stuff (ARub) */
#include <stdarg.h>
/* BEGIN OF HACKS */
#include <pproto/pproto.h>
/* <ctype.h> */
static inline int isdigit(int c)
{
return c >= '0' && c <= '9';
}
static inline int islower(int c)
{
return c >= 'a' && c <= 'z';
}
static inline int isupper(int c)
{
return c >= 'A' && c <= 'Z';
}
static inline int isalpha(int c)
{
return islower(c) || isupper(c);
}
static inline int isalnum(int c)
{
return isalpha(c) || isdigit(c);
}
/* <linux/types.h> -- but if we typedef we get redefined type when hosted */
#define u8 uint8_t
#define size_t unsigned long
#define ptrdiff_t unsigned long
#define noinline __attribute__((noinline))
/* END OF HACKS */
const char hex_asc[] = "0123456789abcdef";
#define hex_asc_lo(x) hex_asc[((x) & 0x0f)]
#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4]
static inline char *pack_hex_byte(char *buf, u8 byte)
{
*buf++ = hex_asc_hi(byte);
*buf++ = hex_asc_lo(byte);
return buf;
}
/* we use this so that we can do without the ctype library */
#define is_digit(c) ((c) >= '0' && (c) <= '9')
static int skip_atoi(const char **s)
{
int i=0;
while (is_digit(**s))
i = i*10 + *((*s)++) - '0';
return i;
}
/* Decimal conversion is by far the most typical, and is used
* for /proc and /sys data. This directly impacts e.g. top performance
* with many processes running. We optimize it for speed
* using code from
* http://www.cs.uiowa.edu/~jones/bcd/decimal.html
* (with permission from the author, Douglas W. Jones). */
/* Formats correctly any integer in [0,99999].
* Outputs from one to five digits depending on input.
* On i386 gcc 4.1.2 -O2: ~250 bytes of code. */
static char* put_dec_trunc(char *buf, unsigned q)
{
unsigned d3, d2, d1, d0;
d1 = (q>>4) & 0xf;
d2 = (q>>8) & 0xf;
d3 = (q>>12);
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
q = (d0 * 0xcd) >> 11;
d0 = d0 - 10*q;
*buf++ = d0 + '0'; /* least significant digit */
d1 = q + 9*d3 + 5*d2 + d1;
if (d1 != 0) {
q = (d1 * 0xcd) >> 11;
d1 = d1 - 10*q;
*buf++ = d1 + '0'; /* next digit */
d2 = q + 2*d2;
if ((d2 != 0) || (d3 != 0)) {
q = (d2 * 0xd) >> 7;
d2 = d2 - 10*q;
*buf++ = d2 + '0'; /* next digit */
d3 = q + 4*d3;
if (d3 != 0) {
q = (d3 * 0xcd) >> 11;
d3 = d3 - 10*q;
*buf++ = d3 + '0'; /* next digit */
if (q != 0)
*buf++ = q + '0'; /* most sign. digit */
}
}
}
return buf;
}
/* Same with if's removed. Always emits five digits */
static char* put_dec_full(char *buf, unsigned q)
{
/* BTW, if q is in [0,9999], 8-bit ints will be enough, */
/* but anyway, gcc produces better code with full-sized ints */
unsigned d3, d2, d1, d0;
d1 = (q>>4) & 0xf;
d2 = (q>>8) & 0xf;
d3 = (q>>12);
/*
* Possible ways to approx. divide by 10
* gcc -O2 replaces multiply with shifts and adds
* (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386)
* (x * 0x67) >> 10: 1100111
* (x * 0x34) >> 9: 110100 - same
* (x * 0x1a) >> 8: 11010 - same
* (x * 0x0d) >> 7: 1101 - same, shortest code (on i386)
*/
d0 = 6*(d3 + d2 + d1) + (q & 0xf);
q = (d0 * 0xcd) >> 11;
d0 = d0 - 10*q;
*buf++ = d0 + '0';
d1 = q + 9*d3 + 5*d2 + d1;
q = (d1 * 0xcd) >> 11;
d1 = d1 - 10*q;
*buf++ = d1 + '0';
d2 = q + 2*d2;
q = (d2 * 0xd) >> 7;
d2 = d2 - 10*q;
*buf++ = d2 + '0';
d3 = q + 4*d3;
q = (d3 * 0xcd) >> 11; /* - shorter code */
/* q = (d3 * 0x67) >> 10; - would also work */
d3 = d3 - 10*q;
*buf++ = d3 + '0';
*buf++ = q + '0';
return buf;
}
/* No inlining helps gcc to use registers better */
static noinline char* put_dec(char *buf, unsigned long num)
{
while (1) {
unsigned rem;
if (num < 100000)
return put_dec_trunc(buf, num);
rem = num % 100000;
num /= 100000;
buf = put_dec_full(buf, rem);
}
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SMALL 32 /* Must be 32 == 0x20 */
#define SPECIAL 64 /* 0x */
static char *number(char *buf, unsigned long num, int base, int size, int precision, int type)
{
/* we are called with base 8, 10 or 16, only, thus don't need "G..." */
static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
char tmp[66];
char sign;
char locase;
int need_pfx = ((type & SPECIAL) && base != 10);
int i;
/* locase = 0 or 0x20. ORing digits or letters with 'locase'
* produces same digits or (maybe lowercased) letters */
locase = (type & SMALL);
if (type & LEFT)
type &= ~ZEROPAD;
sign = 0;
if (type & SIGN) {
if ((signed long) num < 0) {
sign = '-';
num = - (signed long) num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
}
}
if (need_pfx) {
size--;
if (base == 16)
size--;
}
/* generate full string in tmp[], in reverse order */
i = 0;
if (num == 0)
tmp[i++] = '0';
/* Generic code, for any base:
else do {
tmp[i++] = (digits[do_div(num,base)] | locase);
} while (num != 0);
*/
else if (base != 10) { /* 8 or 16 */
int mask = base - 1;
int shift = 3;
if (base == 16) shift = 4;
do {
tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
num >>= shift;
} while (num);
} else { /* base 10 */
i = put_dec(tmp, num) - tmp;
}
/* printing 100 using %2d gives "100", not "00" */
if (i > precision)
precision = i;
/* leading space padding */
size -= precision;
if (!(type & (ZEROPAD+LEFT)))
while(--size >= 0)
*buf++ = ' ';
/* sign */
if (sign)
*buf++ = sign;
/* "0x" / "0" prefix */
if (need_pfx) {
*buf++ = '0';
if (base == 16)
*buf++ = ('X' | locase);
}
/* zero or space padding */
if (!(type & LEFT)) {
char c = (type & ZEROPAD) ? '0' : ' ';
while (--size >= 0)
*buf++ = c;
}
/* hmm even more zero padding? */
while (i <= --precision)
*buf++ = '0';
/* actual digits of result */
while (--i >= 0)
*buf++ = tmp[i];
/* trailing space padding */
while (--size >= 0)
*buf++ = ' ';
return buf;
}
static char *string(char *buf, char *s, int field_width, int precision, int flags)
{
int len, i;
if (s == 0)
s = "<NULL>";
len = pp_strnlen(s, precision);
if (!(flags & LEFT))
while (len < field_width--)
*buf++ = ' ';
for (i = 0; i < len; ++i)
*buf++ = *s++;
while (len < field_width--)
*buf++ = ' ';
return buf;
}
#ifdef CONFIG_CMD_NET
static char *mac_address_string(char *buf, u8 *addr, int field_width,
int precision, int flags)
{
char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
char *p = mac_addr;
int i;
for (i = 0; i < 6; i++) {
p = pack_hex_byte(p, addr[i]);
if (!(flags & SPECIAL) && i != 5)
*p++ = ':';
}
*p = '\0';
return string(buf, mac_addr, field_width, precision, flags & ~SPECIAL);
}
static char *ip6_addr_string(char *buf, u8 *addr, int field_width,
int precision, int flags)
{
char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
char *p = ip6_addr;
int i;
for (i = 0; i < 8; i++) {
p = pack_hex_byte(p, addr[2 * i]);
p = pack_hex_byte(p, addr[2 * i + 1]);
if (!(flags & SPECIAL) && i != 7)
*p++ = ':';
}
*p = '\0';
return string(buf, ip6_addr, field_width, precision, flags & ~SPECIAL);
}
static char *ip4_addr_string(char *buf, u8 *addr, int field_width,
int precision, int flags)
{
char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
char temp[3]; /* hold each IP quad in reverse order */
char *p = ip4_addr;
int i, digits;
for (i = 0; i < 4; i++) {
digits = put_dec_trunc(temp, addr[i]) - temp;
/* reverse the digits in the quad */
while (digits--)
*p++ = temp[digits];
if (i != 3)
*p++ = '.';
}
*p = '\0';
return string(buf, ip4_addr, field_width, precision, flags & ~SPECIAL);
}
#endif
/*
* Show a '%p' thing. A kernel extension is that the '%p' is followed
* by an extra set of alphanumeric characters that are extended format
* specifiers.
*
* Right now we handle:
*
* - 'M' For a 6-byte MAC address, it prints the address in the
* usual colon-separated hex notation
* - 'I' [46] for IPv4/IPv6 addresses printed in the usual way (dot-separated
* decimal for v4 and colon separated network-order 16 bit hex for v6)
* - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is
* currently the same
*
* Note: The difference between 'S' and 'F' is that on ia64 and ppc64
* function pointers are really function descriptors, which contain a
* pointer to the real address.
*/
static char *pointer(const char *fmt, char *buf, void *ptr, int field_width, int precision, int flags)
{
if (!ptr)
return string(buf, "(null)", field_width, precision, flags);
#ifdef CONFIG_CMD_NET
switch (*fmt) {
case 'm':
flags |= SPECIAL;
/* Fallthrough */
case 'M':
return mac_address_string(buf, ptr, field_width, precision, flags);
case 'i':
flags |= SPECIAL;
/* Fallthrough */
case 'I':
if (fmt[1] == '6')
return ip6_addr_string(buf, ptr, field_width, precision, flags);
if (fmt[1] == '4')
return ip4_addr_string(buf, ptr, field_width, precision, flags);
flags &= ~SPECIAL;
break;
}
#endif
flags |= SMALL;
if (field_width == -1) {
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
return number(buf, (unsigned long) ptr, 16, field_width, precision, flags);
}
/**
* vsprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
* @fmt: The format string to use
* @args: Arguments for the format string
*
* This function follows C99 vsprintf, but has some extensions:
* %pS output the name of a text symbol
* %pF output the name of a function pointer
* %pR output the address range in a struct resource
*
* The function returns the number of characters written
* into @buf.
*
* Call this function if you are already dealing with a va_list.
* You probably want sprintf() instead.
*/
int pp_vsprintf(char *buf, const char *fmt, va_list args)
{
unsigned long num;
int base;
char *str;
int flags; /* flags to number() */
int field_width; /* width of output field */
int precision; /* min. # of digits for integers; max
number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */
/* 'z' support added 23/7/1999 S.H. */
/* 'z' changed to 'Z' --davidm 1/25/99 */
/* 't' added for ptrdiff_t */
str = buf;
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
*str++ = *fmt;
continue;
}
/* process flags */
flags = 0;
repeat:
++fmt; /* this also skips first '%' */
switch (*fmt) {
case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat;
case '#': flags |= SPECIAL; goto repeat;
case '0': flags |= ZEROPAD; goto repeat;
}
/* get field width */
field_width = -1;
if (is_digit(*fmt))
field_width = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
field_width = va_arg(args, int);
if (field_width < 0) {
field_width = -field_width;
flags |= LEFT;
}
}
/* get the precision */
precision = -1;
if (*fmt == '.') {
++fmt;
if (is_digit(*fmt))
precision = skip_atoi(&fmt);
else if (*fmt == '*') {
++fmt;
/* it's the next argument */
precision = va_arg(args, int);
}
if (precision < 0)
precision = 0;
}
/* get the conversion qualifier */
qualifier = -1;
if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
*fmt == 'Z' || *fmt == 'z' || *fmt == 't') {
qualifier = *fmt;
++fmt;
if (qualifier == 'l' && *fmt == 'l') {
qualifier = 'L';
++fmt;
}
}
/* default base */
base = 10;
switch (*fmt) {
case 'c':
if (!(flags & LEFT))
while (--field_width > 0)
*str++ = ' ';
*str++ = (unsigned char) va_arg(args, int);
while (--field_width > 0)
*str++ = ' ';
continue;
case 's':
str = string(str, va_arg(args, char *), field_width, precision, flags);
continue;
case 'p':
str = pointer(fmt+1, str,
va_arg(args, void *),
field_width, precision, flags);
/* Skip all alphanumeric pointer suffixes */
while (isalnum(fmt[1]))
fmt++;
continue;
case 'n':
if (qualifier == 'l') {
long * ip = va_arg(args, long *);
*ip = (str - buf);
} else {
int * ip = va_arg(args, int *);
*ip = (str - buf);
}
continue;
case '%':
*str++ = '%';
continue;
/* integer number formats - set up the flags and "break" */
case 'o':
base = 8;
break;
case 'x':
flags |= SMALL;
case 'X':
base = 16;
break;
case 'd':
case 'i':
flags |= SIGN;
case 'u':
break;
default:
*str++ = '%';
if (*fmt)
*str++ = *fmt;
else
--fmt;
continue;
}
#ifdef CONFIG_SYS_64BIT_VSPRINTF
if (qualifier == 'L') /* "quad" for 64 bit variables */
num = va_arg(args, unsigned long long);
else
#endif
if (qualifier == 'l') {
num = va_arg(args, unsigned long);
if (flags & SIGN)
num = (signed long) num;
} else if (qualifier == 'Z' || qualifier == 'z') {
num = va_arg(args, size_t);
} else if (qualifier == 't') {
num = va_arg(args, ptrdiff_t);
} else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int);
if (flags & SIGN)
num = (signed short) num;
} else {
num = va_arg(args, unsigned int);
if (flags & SIGN)
num = (signed int) num;
}
str = number(str, num, base, field_width, precision, flags);
}
*str = '\0';
return str-buf;
}
#include <stdarg.h>
/*
* minimal vsprintf: only %s and hex values
* Alessandro Rubini 2010, based on code in u-boot (from older Linux)
* GNU GPL version 2.
*/
int pp_vsprintf(char *buf, const char *fmt, va_list args)
{
int i, j;
static char hex[] = "0123456789abcdef";
char *s;
char *str = buf;
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
*str++ = *fmt;
continue;
}
repeat:
fmt++; /* Skip '%' initially, other stuff later */
/* Skip the complete format string */
switch(*fmt) {
case '\0':
goto ret;
case '*':
/* should be precision, just eat it */
i = va_arg(args, int);
/* fall through: discard unknown stuff */
default:
goto repeat;
/* Special cases for conversions */
case 'c': /* char: supported */
*str++ = (unsigned char) va_arg(args, int);
break;
case 's': /* string: supported */
s = va_arg(args, char *);
while (*s)
*str++ = *s++;
break;
case 'n': /* number-thus-far: not supported */
break;
case '%': /* supported */
*str++ = '%';
break;
/* all integer (and pointer) are printed as <%08x> */
case 'o':
case 'x':
case 'X':
case 'd':
case 'i':
case 'u':
case 'p':
i = va_arg(args, int);
*str++ = '<';
for (j = 28; j >= 0; j -= 4)
*str++ = hex[(i>>j)&0xf];
*str++ = '>';
break;
}
}
ret:
*str = '\0';
return str - buf;
}
/*
* FIXME: header
*/
#ifndef __PTP_DEP_H__
#define __PTP_DEP_H__
/* Our printf, that is implemented internally */
extern int pp_printf(const char *fmt, ...)
__attribute__((format(printf,1,2)));
extern int pp_vsprintf(char *buf, const char *, va_list)
__attribute__ ((format (printf, 2, 0)));
/* We base on puts and a few more functions: each arch must have it */
extern void pp_puts(const char *s);
extern int pp_strnlen(const char *s, int maxlen);
extern void *pp_memcpy(void *d, const void *s, int count);
#endif /* __PTP_DEP_H__ */
/*
* FIXME
*/
#ifndef __PTP_DIAG_H__
#define __PTP_DIAG_H__
/*
* The diagnostic functions (diag-yes.c and diag-no.c).
*
* Use trace like "pp_diag_trace(ppi, __func__, __LINE__)".
* error gets an integer, the other ones two strings (so we can
* strerror(errno) together with the explanation. Avoid diag_printf if
* possible, for size reasons, but here it is anyways.
*/
extern void pp_diag_fsm(struct pp_instance *ppi, int sequence, int plen);
extern void pp_diag_trace(struct pp_instance *ppi, const char *f, int line);
extern void pp_diag_error(struct pp_instance *ppi, int err);
extern void pp_diag_error_str2(struct pp_instance *ppi, char *s1, char *s2);
extern void pp_diag_fatal(struct pp_instance *ppi, char *s1, char *s2);
extern void pp_diag_printf(struct pp_instance *ppi, char *fmt, ...)
__attribute__((format(printf,2,3)));
#endif /* __PTP_DIAG_H__ */
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
#ifndef __PTP_PROTO_H__
#define __PTP_PROTO_H__
#include <stdint.h>
#include <stdarg.h>
#include <arch/arch.h> /* ntohs and so on */
/*
* This is the struct handling runtime options. Default values can be
* overridden by command line
*/
struct pp_runtime_opts {
/* TODO */
};
struct pp_net_path {
union {
int evt_sock;
void *custom;
};
int32_t gen_sock;
int32_t mcast_addr;
int32_t peer_mcast_addr;
int32_t ucast_addr;
};
extern struct pp_runtime_opts default_rt_opts; /* preinitialized
* with default values */
/*
* This is the communication channel. Either a socket (Posix stuff)
* or another implementation-specific thin, possibly allocated.
* For consistency, this is a struct not a union. gcc allows unnamed
* unions as structure fields, and we are gcc-specific anyways.
*/
struct pp_channel {
union {
int fd; /* Poisx wants fide descriptor */
void *custom; /* Other archs want other stuff */
};
void *arch_data; /* Other arch-private info, if any */
unsigned char addr[6]; /* Our own MAC address */
unsigned char peer[6]; /* Our peer's MAC address */
};
/*
* This is the structure for the standard protocol.
* Extensions may allocate a bigger structure that includes this one.
* The encompassing structure will be at the same address, or container_of()
* may be implemented and used
*/
struct pp_instance {
int state;
int next_state, next_delay; /* set by state processing */
void *arch_data; /* if arch needs it */
void *ext_data; /* if protocol ext needs it */
struct pp_channel ch;
struct pp_runtime_opts *rt_opts;
struct pp_clock *ppc;
};
/* The channel for an instance must be created and possibly destroyed. */
extern int pp_open_instance(struct pp_instance *ppi,
struct pp_runtime_opts *rt_opts);
extern int pp_close_instance(struct pp_instance *ppi);
extern int pp_parse_cmdline(struct pp_instance *ppi, int argc, char **argv);
/* network stuff */
extern int pp_net_init(struct pp_instance *ppi);
extern int pp_recv_packet(struct pp_instance *ppi, void *pkt, int len);
extern int pp_send_packet(struct pp_instance *ppi, void *pkt, int len);
/* Get a timestamp */
extern void pp_get_stamp(uint32_t *sptr);
/*
* The state machine itself is an array of these structures.
* Each state in the machine has an array item. Both functions are
* called (one is expected to be the standard one, the other the extension).
*
* The return value is 0 or a negative error code, but functions should
* also set the fields next_state and next_delay. Processing for the next
* state is entered when a packet arrives or when the delay expires.
*/
struct pp_state_table_item {
int state;
int (*f1)(struct pp_instance *ppi, uint8_t *packet, int plen);
int (*f2)(struct pp_instance *ppi, uint8_t *packet, int plen);
};
extern struct pp_state_table_item pp_state_table[]; /* 0-terminated */
enum pp_std_states {
PPS_END_OF_TABLE = 0,
PPS_INITIALIZING,
PPS_FAULTY,
PPS_DISABLED,
PPS_LISTENING,
PPS_PRE_MASTER,
PPS_MASTER,
PPS_PASSIVE,
PPS_UNCALIBRATED,
PPS_SLAVE,
};
/* Use a typedef, to avoid long prototypes -- I'm not sure I like it */
typedef int pp_action(struct pp_instance *ppi, uint8_t *packet, int plen);
/* Standard state-machine functions */
extern pp_action pp_initializing, pp_faulty, pp_disabled, pp_listening,
pp_pre_master, pp_master, pp_passive, pp_uncalibrated,
pp_slave;
/* The engine */
extern int pp_state_machine(struct pp_instance *ppi, uint8_t *packet, int plen);
/*
* FIXME
* What follows is the protocol itself. Definition of packet and such stuff.
* Whe talk raw sockets on PP_PROTO_NR.
*/
#define PP_PROTO_NR 0xcccc
#endif /* __PTP_PROTO_H__ */
# Makefile for an extended protocol.
# Alessandro Rubini for CERN, 2011 -- public domain
#
# We add to obj-y, and further undefined symbols are taken from libstd
# (i.e., code and data from the standard protocol)
P := proto-ext-$(PROTO_EXT)
OBJ-y += $P/ext-one.o
\ No newline at end of file
/*
* FIXME: header
*/
#include <pproto/pproto.h>
/* This is a placeholder for white rabbit extension. */
/* TODO */
# Hosted environment: build the final exectuable
# All files are under D: I'm lazy
D := proto-standard
LIBSTD := $D/libstd.a
LIBS += -L$D -lstd
OBJ-libstd := $D/state-table-default.o \
$D/state-initializing.o \
$D/state-faulty.o \
$D/state-disabled.o \
$D/state-listening.o \
$D/state-pre-master.o \
$D/state-master.o \
$D/state-passive.o \
$D/state-uncalibrated.o \
$D/state-slave.o \
$D/open-close.o
$(TARGET).o: $(LIBSTD)
$(LIBSTD): $(OBJ-libstd)
$(AR) r $@ $^
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
#include <pproto/pproto.h>
/*
* This file deals with opening and closing an instance. The channel
* must already have been created. In practices, this initializes the
* state machine to the first state.
*
* A protocol extension can override none or both of these functions.
*/
struct pp_runtime_opts default_rt_opts = {
/* TODO */
};
struct pp_runtime_opts *pp_get_default_rt_opts()
{
return &default_rt_opts;
}
int pp_parse_cmdline(struct pp_instance *ppi, int argc, char **argv)
{
/* TODO: Check how to parse cmdline. We can not rely on getopt()
* function. Which are the really useful parameters?
* Every parameter should be contained in ppi->rt_opts and set here
*/
return 0;
}
int pp_open_instance(struct pp_instance *ppi, struct pp_runtime_opts *rt_opts)
{
if (rt_opts) {
ppi->rt_opts = rt_opts;
}
else {
ppi->rt_opts = &default_rt_opts;
}
ppi->state = PPS_INITIALIZING;
return 0;
}
int pp_close_instance(struct pp_instance *ppi)
{
/* Nothing to do by now */
return 0;
}
/*
* FIXME: header
*/
#include <pproto/pproto.h>
int pp_disabled(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
/* TODO */
return 0;
}
/*
* FIXME: header
*/
#include <pproto/pproto.h>
#include <dep/dep.h>
/*
* Fault troubleshooting. Now only prints an error messages and comes back to
* PTP_INITIALIZING state
*/
int pp_faulty(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
pp_printf("event FAULT_CLEARED\n");
ppi->next_state = 1000;
ppi->next_delay = PPS_INITIALIZING;
return 0;
}
/*
* FIXME: header
*/
#include <pproto/pproto.h>
#include <dep/dep.h>
/*
* Initializes network and other stuff
*/
int pp_initializing(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
/* FIXME
if (pp_net_init(ppi) < 0)
goto failure;
*/
/* TODO initialize other stuff */
/* TODO copy &ppi->rt_opts to &ppi->ppc. Do it here, no real need for a
initData function */
/* TODO ARCH initTimer(); define a "timer" abstract object, define it for
all the archs and initialize it here */
/* TODO CHECK initClock(rtOpts, ptpClock); check what is it for */
/* TODO CHECK m1(ptpClock);*/
/* TODO initializes header of a packet msgPackHeader(ptpClock->msgObuf,
ptpClock); */
if (1) /* FIXME: implement above */
goto failure;
ppi->next_state = PPS_LISTENING;
return 0;
failure:
pp_printf("Failed to initialize network\n");
ppi->next_state = PPS_FAULTY;
return 0;
}
/*
* FIXME: header
*/
#include <pproto/pproto.h>
int pp_listening(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
/* TODO */
return 0;
}
/*
* FIXME: header
*/
#include <pproto/pproto.h>
int pp_master(struct pp_instance *ppi, unsigned char *newpkt, int plen)
{
/* TODO */
return 0;
}
/*
* FIXME: header
*/
#include <pproto/pproto.h>
int pp_passive(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
/* TODO */
return 0;
}
/*
* FIXME: header
*/
#include <pproto/pproto.h>
int pp_pre_master(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
/* TODO */
return 0;
}
/*
* FIXME: header
*/
#include <pproto/pproto.h>
int pp_slave(struct pp_instance *ppi, unsigned char *_newpkt, int plen)
{
/* TODO */
return 0;
}
/*
* FIXME: header
*/
#include <pproto/pproto.h>
/*
* This is the default state machine table. It is weak so an extension
* protocol can define its own stuff. It is in its own source file, so
* the linker can avoid pulling this data space if another table is there.
*/
struct pp_state_table_item pp_state_table[] = {
{ PPS_INITIALIZING, pp_initializing,},
{ PPS_FAULTY, pp_faulty,},
{ PPS_DISABLED, pp_disabled,},
{ PPS_LISTENING, pp_listening,},
{ PPS_PRE_MASTER, pp_pre_master,},
{ PPS_MASTER, pp_master,},
{ PPS_PASSIVE, pp_passive,},
{ PPS_UNCALIBRATED, pp_uncalibrated,},
{ PPS_SLAVE, pp_slave,},
{ PPS_END_OF_TABLE,}
};
/*
* FIXME: header
*/
#include <pproto/pproto.h>
int pp_uncalibrated(struct pp_instance *ppi, unsigned char *pkt, int plen)
{
/* TODO */
return 0;
}
/*
* Alessandro Rubini for CERN, 2011 -- public domain
*/
#include <pproto/pproto.h>
#include <pproto/diag.h>
/*
* This is the state machine code. i.e. the extension-independent
* function that runs the machine. Errors are managed and reported
* here (based on the diag module). The returned value is the time
* in milliseconds to wait before reentering the state machine.
* the normal protocol. If an extended protocol is used, the table used
* is that of the extension, otherwise the one in state-table-default.c
*/
int pp_state_machine(struct pp_instance *ppi, uint8_t *packet, int plen)
{
struct pp_state_table_item *ip;
int state, err;
state = ppi->state;
/* a linear search is affordable up to a few dozen items */
for (ip = pp_state_table; ip->state != PPS_END_OF_TABLE; ip++) {
if (ip->state != state)
continue;
/* found: handle this state */
ppi->next_state = state;
ppi->next_delay = 0;
pp_diag_fsm(ppi, 0 /* enter */, plen);
err = ip->f1(ppi, packet, plen);
if (!err && ip->f2)
err = ip->f2(ppi, packet, plen);
if (err)
pp_diag_error(ppi, err);
pp_diag_fsm(ppi, 1 /* leave */, 0 /* unused */);
/* done: accept next state and delay */
ppi->state = ppi->next_state;
return ppi->next_delay;
}
/* Unknwon state, can't happen */
pp_diag_error_str2(ppi, "Unknown state in FSM", "");
return 10000; /* No way out. Repeat message every 10s */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment