mirror of
				https://gitlab.com/qemu-project/openbios.git
				synced 2024-02-13 08:34:06 +08:00 
			
		
		
		
	initial import of openbios--main--1.0--patch-26
git-svn-id: svn://coreboot.org/openbios/openbios-devel@1 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
		
							
								
								
									
										341
									
								
								COPYING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								COPYING
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,341 @@ | ||||
|  | ||||
| 		    GNU GENERAL PUBLIC LICENSE | ||||
| 		       Version 2, June 1991 | ||||
|  | ||||
|  Copyright (C) 1989, 1991 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. | ||||
|  | ||||
| 			    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 Library 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) 19yy  <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 St, 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) 19yy 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 Library General | ||||
| Public License instead of this License. | ||||
							
								
								
									
										1895
									
								
								Documentation/ChangeLog.arch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1895
									
								
								Documentation/ChangeLog.arch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6
									
								
								Documentation/kernel/AUTHORS
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Documentation/kernel/AUTHORS
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| The OpenBIOS forth engine was written by | ||||
|  | ||||
|   Patrick Mauritz <oxygene@openbios.info> | ||||
|   Stefan Reinauer <stepan@openbios.info> | ||||
|  | ||||
| # tag: list of authors | ||||
							
								
								
									
										358
									
								
								Documentation/kernel/COPYING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										358
									
								
								Documentation/kernel/COPYING
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,358 @@ | ||||
| All or most of the source files in this distribution refer to this | ||||
| file for copyright and warranty information.  This file should be | ||||
| included whenever those files are redistributed. | ||||
|  | ||||
| This software is free software: you can redistribute it and/or modify | ||||
| it under the terms of the GNU General Public License, version 2, as | ||||
| published by the Free Software Foundation. This license is reproduced | ||||
| below. | ||||
|  | ||||
| Please note that we explicitely do not allow applying any newer version | ||||
| of the GPL to this work. Once the FSF releases such a revision we will | ||||
| reconsider to allow it as well. | ||||
|  | ||||
| ----------------- verbatim license text below --------------------- | ||||
|  | ||||
| 		    GNU GENERAL PUBLIC LICENSE | ||||
| 		       Version 2, June 1991 | ||||
|  | ||||
|  Copyright (C) 1989, 1991 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. | ||||
|  | ||||
| 			    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 Library 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 St, 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 Library General | ||||
| Public License instead of this License. | ||||
|  | ||||
| # tag: General Public License text | ||||
| # | ||||
							
								
								
									
										300
									
								
								Documentation/kernel/Changelog.stepan
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								Documentation/kernel/Changelog.stepan
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,300 @@ | ||||
| # tag: stepan's changelog for CVS | ||||
|  | ||||
| Mon Jul 14 02:16:49 CEST 2003 | ||||
|  - fix segv overrun while dumping dictionary in unix.c | ||||
|  - implement first version of >number and $number | ||||
|  - add stack diagram to digit | ||||
|  - no newline after accept | ||||
|  - new version of the interpreter | ||||
|  - fix make run target | ||||
|  | ||||
| Mon Jul 14 20:15:40 CEST 2003 | ||||
|  - negate true value in prims  | ||||
|  - get rid of primitive word bounds.  | ||||
|  - get rid of some obsolete code. | ||||
|  - implement io[cwl][@!] | ||||
|  - reorganize [in|out][bwl] | ||||
|  - start adding stack diagrams to primitives. | ||||
|   | ||||
| Mon Jul 14 23:57:46 CEST 2003 | ||||
|  - added some more stack diagrams in forth.h | ||||
|  - move parse, parse-word, word to bootstrap.fs | ||||
|  - include memory.fs from bootstrap.fs for above. | ||||
|  | ||||
| Wed Jul 16 22:57:31 CEST 2003 | ||||
|  - add include guards | ||||
|  - add banner | ||||
|  - fix primitives' dependencies | ||||
|  | ||||
| Sun Jul 20 03:27:40 CEST 2003 | ||||
|  - remove unneeded readcell | ||||
|  - rename ' to ['] to meet specs | ||||
|  | ||||
| Sun Jul 20 14:08:43 CEST 2003 | ||||
|  - add rest of stack diagrams in forth.h | ||||
|  - move here and here! to forth.h (from internal.h) | ||||
|  - indent includes | ||||
|  - merge system.h into forth.h | ||||
|  - Change tag of forth.h (!) because the old one  | ||||
|    did not meet the meaning of the code. | ||||
|  - update comments in primitives.c | ||||
|  | ||||
| Sun Jul 27 01:53:18 CEST 2003 | ||||
|  - include great new do/?do/loop/+loop  | ||||
|    implementation from Patrick. | ||||
|  - include testsuite enhancement from Patrick | ||||
|  - include trampoline from Patrick (fixes execute) | ||||
|  | ||||
| Sun Jul 27 21:11:50 CEST 2003 | ||||
|  - update x86 console code to become when using | ||||
|    multiboot (vga/keyboard). | ||||
|  - fix exit properly | ||||
|  - revert to old case..endcase code | ||||
|  - fix >number and $number | ||||
|  - add number parsing to interpreter | ||||
|  - add simple stack checking to interpreter | ||||
|  - add 2 testcases (exit and case2) | ||||
|  | ||||
| Mon Jul 28 14:49:31 CEST 2003 | ||||
|  - move 7.3.7 Flag constants up in bootstrap.fs | ||||
|  - move 7.3.9.2.4 Miscellaneous dictionary down. | ||||
|  - add reveal, recursive, recurse, environment? to 7.3.9.2.4 | ||||
|  - move (to) to bootstrap.fs | ||||
|   | ||||
| Mon Jul 28 17:08:58 CEST 2003 | ||||
|  - add stack overflow check to interpreter | ||||
|  - check parse-word result in interpreter.  | ||||
|  - add ascii and char, add helper handle-lit | ||||
|  | ||||
| Tue Jul 29 09:20:18 CEST 2003 | ||||
|  - add s" and ." | ||||
|  - add [char] and control | ||||
|  - heavily move around words in bootstrap.fs  | ||||
|    to get dependencies resolved. | ||||
|  - fix skipws crash | ||||
|  - rename query to refill | ||||
|  - interpreter reads several words in a line now | ||||
|  - interpreter stops now if error encountered in | ||||
|    currently parsed line. | ||||
|  - add forth definitions of ( and \ | ||||
|  - change c parser/interpreter to handle comments | ||||
|    correctly. | ||||
|  - indent, clean up unix.c | ||||
|  | ||||
| Tue Jul 29 18:13:27 CEST 2003 | ||||
|  - add .(  (chapter 7.3.4.4) | ||||
|  - add pack, -trailing (chapter 7.3.4.8) | ||||
|  - add d#, h#, o# (chapter 7.3.5.2) | ||||
|  - let first stack element start at 1 instead of 0 | ||||
|    to have a 1 cell guard band. | ||||
|  - set SA_NODEFER flag to signal handler to ensure | ||||
|    that it is entered recursively. | ||||
|  | ||||
| Tue Jul 29 19:06:18 CEST 2003 | ||||
|  - more simplification for unix.c | ||||
|  - add ', ['], find | ||||
|  - fix pack, count | ||||
|  - add literal, compile, [compile], compile, | ||||
|  - fix [ | ||||
|  | ||||
| Wed Jul 30 01:24:24 CEST 2003 | ||||
|  - add >body, body> | ||||
|  - add helpers: flags?, immediate?, compile-only?, header | ||||
|  - add :, ;, constant, value, variable, buffer: | ||||
|  - parse word's flags in interpreter to make colon  | ||||
|    definitions work | ||||
|  - add "compiled" acknowledge when interpreter is in compile mode | ||||
|  | ||||
| Wed Jul 30 07:27:58 CEST 2003 | ||||
|  - fix flags handling in interpreter | ||||
|  - fix handle-text compile mode behaviour | ||||
|  - add defer, struct, field | ||||
|  - add behaviour, to | ||||
|  - add $create, create, does> (missing c code DODOES) | ||||
|  - add abort | ||||
|  | ||||
| Thu Jul 31 07:58:35 CEST 2003 | ||||
|  - fix DODOES cfa code | ||||
|  - make 2@ and 2! colon definitions instead of primitives. | ||||
|  - add word "cell"  | ||||
|  - add warning message as described in 7.3.9.1 if an already  | ||||
|    existing word is created | ||||
|  | ||||
| Fri Aug  1 23:32:57 CEST 2003 | ||||
|  - fix s" in C interpreter (compare case insensitive) | ||||
|  - fix forth source dependencies | ||||
|  - fix forth word sm/rem  | ||||
|  | ||||
| Sat Aug  2 13:34:43 CEST 2003 | ||||
|  - add band guard around input buffer | ||||
|  - make sure that "header" pads null bytes | ||||
|  - define -1,0,1,2,3 early to safe dictionary space | ||||
|  | ||||
| Sat Aug  2 16:58:31 CEST 2003 | ||||
|  - use getopt/getopt_long for option parsing | ||||
|  - add include path option -I to unix | ||||
|  - don't create obsolete symlink in forth/Makefile | ||||
|  - fix recurse | ||||
|  - fix prim word / | ||||
|  - implement postpone | ||||
|  - fix 2!, ['] and ' | ||||
|  - implement evaluate/eval | ||||
|  | ||||
| Sun Aug  3 11:48:18 CEST 2003 | ||||
|  - implement "bye" to leave the engine | ||||
|  - change initial word to "initialize" and | ||||
|    make quit restart the forth engine. | ||||
|  - fix missing ; in u. | ||||
|  - fix return value of find when handling an immediate | ||||
|  - getting rid of primitives mod, /mod and /, replacing  | ||||
|    them by floored variants as IEEE 1275-1994 says. | ||||
|  - clean up primitives. | ||||
|     | ||||
| Sun Aug  3 23:06:39 CEST 2003 | ||||
|  - fix >body, body> | ||||
|  - make not a synonym for invert as described in IEEE 1275 | ||||
|  - todigit can now switch between capital and small letters via | ||||
|    value capital-hex? | ||||
|  | ||||
| Mon Aug  4 21:57:06 CEST 2003 | ||||
|  - indent unix.c | ||||
|  - reimplement do, ?do, loop, +loop with prim helpers. It now | ||||
|    passes hayes' ans forth test suite. | ||||
|  - adopt unix.c and bootstrap.fs to new (?)do..(+)loop | ||||
|  - remove unneeded if around ?do..loop in ", | ||||
|  - interpreter: clear input buffer before refilling it | ||||
|  - serialize PC changes in dobranch and do?branch | ||||
|  | ||||
| Thu Aug  7 19:00:43 CEST 2003 | ||||
|  - add/change missing/incomplete copyright notices | ||||
|  - implement " | ||||
|  | ||||
| Sun Aug 10 19:52:20 CEST 2003 | ||||
|  - reimplement catch, through | ||||
|  - implement abort" | ||||
|  - rephrase endcase | ||||
|  - change interpreter to use exception words | ||||
|  - implement forget | ||||
|  - add dummy "forth" | ||||
|  | ||||
| Sun Aug 10 22:12:28 CEST 2003 | ||||
|  - fix "spaces" | ||||
|  - create subdir util for types.sh and new bin2hex | ||||
|  - enable forth.html again, running hayes test suite. | ||||
|  - include dictionary in char array instead of elf section | ||||
|    when building an x86 "full" image | ||||
|  - don't newline in accept. | ||||
|  - fix " compile mode behavior. | ||||
|  - move throw/catch and use it with ' and ['] | ||||
|  - add :noname | ||||
|  | ||||
| Thu Aug 14 23:02:15 CEST 2003 | ||||
|  - fix "field" | ||||
|  - implement second stage bootstrapping | ||||
|    NOTE: changes dictionary format! | ||||
|  - drop initxt from dictionary, since we know "last" now. | ||||
|  - output dictionary can be named on command line. | ||||
|  - make segfault handler optional | ||||
|  | ||||
| Mon Sep  1 19:41:23 CEST 2003 | ||||
|  - move findword() et al to dict.c (needed by openbios.c due  | ||||
|    to last dictionary change) | ||||
|  - fix findword() return values and optimize it slightly. | ||||
|  - indented some files. | ||||
|   | ||||
| Mon Sep  8 22:43:55 CEST 2003 | ||||
|  - add initial AMD64 support (cloned x86 target) | ||||
|  - get vocabulary implementation working. maybe buggy, but operable | ||||
|  - enable vocabulary support by default (vocabularies? set to true) | ||||
|  - drop duplicate "forth" | ||||
|  - fix some comments in forth files. | ||||
|   | ||||
| Sun Sep 28 14:26:41 CEST 2003 | ||||
|  - some documentation and comment fixes | ||||
|  - fix parameter passing for io words. | ||||
|  | ||||
| Thu Oct  2 08:21:06 CEST 2003 | ||||
|  - clean up lit | ||||
|  - inline some functions from internal.h (reduces size and execution  | ||||
|    time) | ||||
|  | ||||
| Fri Oct  3 15:20:44 CEST 2003 | ||||
|  - make i and j primitives. This safes a lot of time in loops. | ||||
|    i.e. the following dummy loop executes 300% faster: | ||||
|    : fbar 1000 0 do 1000 0 do j drop i drop loop loop ; | ||||
|  | ||||
| Sat Oct 11 20:18:22 CEST 2003 | ||||
|  - include plugin interface for unix hosted version. | ||||
|  - add plugin_pci and plugin_qt as examples. | ||||
|  - add simple set of pci functions for testing the pci plugin | ||||
|  - add state variable "runforth" to be changed by the qt plugin | ||||
|    on exit. | ||||
|  | ||||
| Sun Oct 12 14:57:54 CEST 2003 | ||||
|  - move internal.h and forth.h to kernel/ | ||||
|  - replace make by $(MAKE) in some places. | ||||
|  | ||||
| Tue Oct 14 01:06:39 CEST 2003 | ||||
|  - add (immediate) and (compile-only)  | ||||
|  | ||||
| Wed Oct 15 00:52:49 CEST 2003 | ||||
|  - check whether dlopen() needs libdl. | ||||
|  - include BSD compile fixes from oxygene | ||||
|  - fix abort" | ||||
|   | ||||
| Tue Oct 21 22:08:00 CEST 2003 | ||||
|  - fix forth.html dependencies | ||||
|  - yet another indent orgy | ||||
|  | ||||
| Thu Oct 30 16:10:01 CET 2003 | ||||
|  - add "call" to execute native code functions | ||||
|  - plugin_qt: fix framebuffer address on 64bit systems | ||||
|  - plugin_pci: create position independent code. | ||||
|  | ||||
| Wed Nov  5 08:38:18 CET 2003 | ||||
|  - fix "comp" (from Samuel Rydh) | ||||
|  - include instance support (from Samuel Rydh) | ||||
|  | ||||
| Sun Nov  9 15:53:33 CET 2003 | ||||
|  - some changes for "see" | ||||
|  - apply more patches from Samuel. | ||||
|  - smaller, better implementation of handle-text | ||||
|  | ||||
| Mon Nov 10 22:06:32 CET 2003 | ||||
|  - increase max dictionary size from 64k to 128k | ||||
|  - add simple fcode to qt plugin | ||||
|  - fix handle-text (move null-align up) | ||||
|  | ||||
| Tue Nov 11 22:53:27 CET 2003 | ||||
|  - rename ?key to key?. | ||||
|  - clean up .s | ||||
|  - add (cr | ||||
|  | ||||
| Tue Nov 17 22:42:54 CET 2003 | ||||
|  - enterforth rstack fix (from Samuel) | ||||
|  - include latest version of qt interface  | ||||
|    fcode driver | ||||
|  - fix "header" (from Samuel) | ||||
|  | ||||
| Wed Nov 26 15:12:07 CET 2003 | ||||
|  - merge patches from Samuel: | ||||
|  - add $buffer: | ||||
|  - fill all of "ib", not only 80 characters | ||||
|  - interpreted conditionals support | ||||
|  - late initializers | ||||
|  | ||||
| Sun Nov 30 23:04:28 CET 2003 | ||||
|  - fix bug in enterforth (non-colon words would destroy PC) | ||||
|  | ||||
| Sat Dec 13 00:57:01 CET 2003 | ||||
|  - add initial ppc infrastructure | ||||
|  - only search current wordlist in "header" | ||||
|  - seperate unix host binary and bootstrap interpreter. | ||||
|  | ||||
| Sun Dec 14 18:13:29 CET 2003 | ||||
|  - add sys-debug word and use it to stop forth interpreter | ||||
|    during bootstrap if an error occurs. | ||||
|   | ||||
| Sat Mar 13 16:30:30 CET 2004 | ||||
|  - fix digit problem | ||||
|     | ||||
							
								
								
									
										11
									
								
								Documentation/kernel/TODO
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Documentation/kernel/TODO
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| TODO | ||||
|  | ||||
| booting | ||||
|  * support more arches than x86+amd64 | ||||
|  * compressed + rommable dictionary | ||||
|   | ||||
| forth bootstrap | ||||
|  * make prompt configurable  | ||||
|  * check state-variable when defining a new word. | ||||
|  | ||||
| tag: TODO for the forth system | ||||
							
								
								
									
										8
									
								
								Documentation/kernel/dictformat.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Documentation/kernel/dictformat.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| # tag: contains a description of the dictionary format | ||||
|  | ||||
| name | length of name in bytes + 0x80 | align with 0's | flags (bit 7 set) | LFA | CFA | PFA | ||||
|  | ||||
| LFA == link field address (backlink) | ||||
| CFA == code field address ("word type") | ||||
| PFA == program field address (definitions) | ||||
|  | ||||
							
								
								
									
										14
									
								
								Documentation/kernel/glossary.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Documentation/kernel/glossary.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| # tag: glossary of openbios forth  | ||||
|  | ||||
| # dictionary | ||||
| LFA == link field address (backlink) | ||||
| CFA == code field address ("word type") | ||||
| PFA == program field address (definitions) | ||||
|  | ||||
| # forth engine | ||||
| TIB == text input buffer | ||||
|  | ||||
| inner interpreter: interprets dictionary, does threading | ||||
| outer interpreter: "user" interpreter, reads forth words from user. | ||||
|  | ||||
|  | ||||
							
								
								
									
										24
									
								
								Documentation/kernel/initializers.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Documentation/kernel/initializers.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
|  | ||||
| Initializers are called when the forth kernel is started, to do some | ||||
| initialization stuff.  | ||||
| Pro: If code needs initialization you can keep this in place with the code | ||||
| and don't need to patch the kernel itself to do so. | ||||
|  | ||||
| There are 2 types of initializers. "Normal" and "Late" initializers. | ||||
|  | ||||
| Since initializers are only called during startup, they don't need a name. | ||||
|  | ||||
| Definition: | ||||
|   initializer      ( xt -- ) | ||||
|   late-initializer ( xt -- ) | ||||
|  | ||||
| Examples: | ||||
|   :noname <definition> ; initializer | ||||
|  | ||||
|   :noname | ||||
|      some-base initializations | ||||
|   ; late-initializer | ||||
|   | ||||
| Late initializers are run after all ordinary initializers have | ||||
| been executed. | ||||
|  | ||||
							
								
								
									
										59
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| ARCH= $(shell cat rules.xml |grep ^ARCH|cut -d\= -f2|tr -d \ ) | ||||
| HOSTARCH=$(shell config/scripts/archname) | ||||
| ODIR=obj-$(ARCH) | ||||
|  | ||||
| all: info build | ||||
|  | ||||
| info: | ||||
| 	@echo "Building OpenBIOS on $(HOSTARCH) for $(ARCH)" | ||||
|  | ||||
| clean: | ||||
| 	@echo -n "Cleaning up..." | ||||
| 	@rm -rf $(ODIR) forth.dict.core | ||||
| 	@echo " ok" | ||||
| 	 | ||||
| directories: clean | ||||
| 	@echo -n "Initializing build tree..." | ||||
| 	@mkdir $(ODIR) | ||||
| 	@mkdir -p $(ODIR)/target/include | ||||
| 	@mkdir -p $(ODIR)/target/arch/unix | ||||
| 	@mkdir -p $(ODIR)/target/arch/$(ARCH) | ||||
| 	@mkdir -p $(ODIR)/target/arch/ppc/briq # no autodetection of those.. | ||||
| 	@mkdir -p $(ODIR)/target/arch/ppc/pearpc | ||||
| 	@mkdir -p $(ODIR)/target/arch/ppc/mol | ||||
| 	@mkdir -p $(ODIR)/target/arch/x86/xbox | ||||
| 	@mkdir -p $(ODIR)/target/kernel | ||||
| 	@mkdir -p $(ODIR)/target/modules | ||||
| 	@mkdir -p $(ODIR)/target/fs/grubfs | ||||
| 	@mkdir -p $(ODIR)/target/fs/hfs | ||||
| 	@mkdir -p $(ODIR)/target/fs/hfsplus | ||||
| 	@mkdir -p $(ODIR)/target/drivers | ||||
| 	@mkdir -p $(ODIR)/target/libc | ||||
| 	@mkdir -p $(ODIR)/host/include | ||||
| 	@mkdir -p $(ODIR)/host/kernel | ||||
| 	@mkdir -p $(ODIR)/host/toke | ||||
| 	@mkdir -p $(ODIR)/forth | ||||
| 	@ln -s $(PWD)/include/$(ARCH) $(ODIR)/target/include/asm | ||||
| 	@#compile the host binary with target settings instead | ||||
| 	@#ln -s $(PWD)/include/$(HOSTARCH) $(ODIR)/host/include/asm | ||||
| 	@echo "ok." | ||||
|  | ||||
| xml: directories | ||||
| 	@echo -n "Creating target Makefile..." | ||||
| 	@xsltproc config/xml/xinclude.xsl build.xml > $(ODIR)/build-full.xml | ||||
| 	@xsltproc config/xml/makefile.xsl $(ODIR)/build-full.xml > $(ODIR)/Makefile | ||||
| 	@echo "ok." | ||||
| 	@echo -n "Creating config files..." | ||||
| 	@xsltproc config/xml/config-c.xsl config.xml > $(ODIR)/host/include/autoconf.h | ||||
| 	@xsltproc config/xml/config-c.xsl config.xml > $(ODIR)/target/include/autoconf.h | ||||
| 	@xsltproc config/xml/config-forth.xsl config.xml > $(ODIR)/forth/config.fs | ||||
| 	@echo "ok." | ||||
|  | ||||
| build: xml | ||||
| 	@echo -n "Building..." | ||||
| 	@( $(MAKE) -f $(ODIR)/Makefile > $(ODIR)/build.log 2>&1 && echo "ok." ) || \ | ||||
| 		( echo "error:"; tail -15 $(ODIR)/build.log ) | ||||
| 	 | ||||
| run:  | ||||
| 	@echo "Running..." | ||||
| 	@$(ODIR)/openbios-unix $(ODIR)/openbios-unix.dict | ||||
							
								
								
									
										131
									
								
								README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								README
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | ||||
| Welcome to OpenBIOS | ||||
| ------------------- | ||||
|  | ||||
| OpenBIOS is a free, portable implementation of IEEE 1275-1994  | ||||
| (Open Firmware). Find detailed information about OpenBIOS at  | ||||
| http://www.openbios.org/ | ||||
|  | ||||
| What is OpenBIOS? | ||||
| ----------------- | ||||
|  | ||||
| OpenBIOS can replace your system firmware (BIOS) partly or completely. It | ||||
| can also be used as a bootloader to create an Open Firmware compatible | ||||
| interface between legacy firmware and an operating system. | ||||
|  | ||||
| This is achieved by a modular concept that consists of a portable Forth | ||||
| kernel and three interfaces for user interaction, device initialization | ||||
| and client (operating system) control. | ||||
|  | ||||
| While far not all possible applications of OpenBIOS are implemented yet, | ||||
| a lot of functionality is already there. OpenBIOS can be used to enhance | ||||
| LinuxBIOS (http://www.linuxbios.org), or be booted from any multiboot | ||||
| capable bootloader to bring Open Firmware to your machine. OpenBIOS can | ||||
| also be used when an operating system is already running. It provides | ||||
| the needed OpenFirmware functionality to MOL (MacOnLinux) to boot MacOS | ||||
| 9 and X on PPC machines, as well as Linux (all supported platforms) | ||||
|  | ||||
| OpenBIOS build options | ||||
| --------------------- | ||||
|  | ||||
|    config/scripts/switch-arch <platform>  - build for specified platform | ||||
|    					    Look in config/example for | ||||
| 					    platforms. | ||||
|  | ||||
|    make            - build all configured binaries | ||||
|  | ||||
|    make run        - run unix example. | ||||
|  | ||||
|     | ||||
| How OpenBIOS works | ||||
| ------------------ | ||||
|  | ||||
|  The OpenBIOS forth core is split into a forth kernel written in portable  | ||||
|  C and a forth dictionary which operated on by the kernel. | ||||
|  | ||||
|  When building the forth core, you get different versions of | ||||
|  the forth kernel:  | ||||
|  | ||||
|  * a unix executable program | ||||
|  | ||||
|    - to execute a forth dictionary from a file. This can be used for | ||||
|      easily testing and developing OpenBIOS on a unix host. | ||||
|  | ||||
|    - to create a dictionary file. Such a dictionary file sets up | ||||
|      all of the forth language. Primitives are indexed to save relocations. | ||||
|  | ||||
|      The default is to create a forth dictionary forth.dict from | ||||
|      forth/start.fs. This file includes all of the basic forth language | ||||
|      constructs from forth/bootstrap.fs and starts the interpreter. | ||||
|  | ||||
|      To achieve this, the hosted unix version contains a basic set of | ||||
|      forth words coded in C that allow creating a full dictionary. | ||||
|  | ||||
|  * a varying number of target specific binaries. On x86 you can start  | ||||
|    openbios for example from GRUB or LinuxBIOS. They are all based on | ||||
|    the same forth engine consisting of a dictionary scheduler, primitive  | ||||
|    words needed to build the forth environment, 2 stacks and a simple  | ||||
|    set of console functions. These binaries can not be started directly | ||||
|    in the unix host environment. | ||||
|  | ||||
| Requirements | ||||
| ------------ | ||||
|  * gcc | ||||
|  * gnu make | ||||
|  * grub or any other multiboot loader to run the multiboot | ||||
|    binary "openbios.multiboot" with it's module "openbios-<platform>.dict" | ||||
|  * xsltproc | ||||
|   | ||||
| Building & Usage | ||||
| ---------------- | ||||
|  | ||||
|  * make | ||||
|  | ||||
|    this builds "openbios.multiboot", the standalone image and "openbios-unix",  | ||||
|    the hosted image. Additionally it creates a forth dictionary | ||||
|    file from forth/start.fs. All generated files are written to  | ||||
|    the absolute directory held by the variable BUILDDIR, which defaults | ||||
|    to obj-[platform]. Some compile time parameters can be tweaked in | ||||
|    include/config.h | ||||
|     | ||||
|  * use "openbios-unix" to create a forth dictionary on your own: | ||||
|    $ obj-x86/openbios-unix -Iforth start.fs | ||||
|    creates the file forth.dict from forth source forth/start.fs. | ||||
|  | ||||
|  * use "openbios-unix" to run a created dictionary:  | ||||
|    $ obj-x86/openbios-unix obj-x86/openbios-unix.dict | ||||
|    This is useful for testing | ||||
|   | ||||
|  * booting openbios | ||||
|    You can boot openbios i.e. in grub. Add the following lines to | ||||
|    your menu.lst: | ||||
|  | ||||
|     title openbios | ||||
|       kernel (hd0,2)/boot/openbios.multiboot | ||||
|       module (hd0,2)/boot/openbios-x86.dict | ||||
|  | ||||
|    Note: change (hd0,2) to the partition you copied the openbios image and | ||||
|    openbios-x86.dict to. | ||||
|  | ||||
|    To boot OpenBIOS from LinuxBIOS/etherboot, you can either use | ||||
|    "openbios-plain.elf" or "openbios-builtin.elf": | ||||
|  | ||||
|    - openbios-plain.elf is the pure kernel that loads the dictionary from a  | ||||
|      hardcoded address in flash memory (0xfffe0000) | ||||
|  | ||||
|    - openbios-builtin.elf also includes the dictionary directly so that it | ||||
|      can be easily used from etherboot or the LinuxBIOS builtin ELF | ||||
|      loader without taking care of the dictionary | ||||
|  | ||||
| CREDITS | ||||
| ------- | ||||
| OpenBIOS was developed by Stefan Reinauer, Samuel Rydh and Patrick Mauritz. | ||||
| The OpenBIOS IDE driver was written by Jens Axboe. | ||||
| For license details on this piece of software, see Documentation/COPYING. | ||||
|  | ||||
|  | ||||
| If you have patches, questions, comments, feel free to contact the OpenBIOS | ||||
| mailinglist. | ||||
|  | ||||
| Regards, | ||||
|      the OpenBIOS team | ||||
|  | ||||
							
								
								
									
										50
									
								
								arch/amd64/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								arch/amd64/Kconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | ||||
| mainmenu "OpenBIOS Configuration" | ||||
|  | ||||
| config AMD64 | ||||
| 	bool | ||||
| 	default y | ||||
| 	help | ||||
| 	  Building for AMD64 hardware. | ||||
|  | ||||
| config LITTLE_ENDIAN | ||||
| 	bool | ||||
| 	default y | ||||
| 	help | ||||
| 	  AMD64 is little endian. | ||||
|  | ||||
|  | ||||
| menu "Kernel binaries (AMD64)" | ||||
|  | ||||
| config IMAGE_ELF | ||||
| 	bool "ELF image (for LinuxBIOS)" | ||||
| 	default y | ||||
| 	help | ||||
| 	  Build a simple elf image that can be used with LinuxBIOS | ||||
| 	  This image will be called openbios.elf | ||||
|  | ||||
| config IMAGE_ELF_EMBEDDED | ||||
| 	bool "ELF image with embedded dictionary" | ||||
| 	default y | ||||
| 	help | ||||
| 	  Build an elf image with embedded dictionary. This image | ||||
| 	  can easily be used with etherboot.  | ||||
| 	  The image filename is openbios.full | ||||
|  | ||||
| config IMAGE_ELF_MULTIBOOT | ||||
| 	bool "Multiboot image" | ||||
| 	default y | ||||
| 	help | ||||
| 	  Build a multiboot image for booting with grub | ||||
|  | ||||
| endmenu | ||||
|  | ||||
| menu "Build hosted UNIX Binary" | ||||
| source "arch/unix/Kconfig" | ||||
| endmenu | ||||
|  | ||||
| source "kernel/Kconfig" | ||||
| source "forth/Kconfig" | ||||
| source "modules/Kconfig" | ||||
| source "drivers/Kconfig" | ||||
|  | ||||
|  | ||||
							
								
								
									
										43
									
								
								arch/amd64/boot.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								arch/amd64/boot.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| /* | ||||
|  * | ||||
|  */ | ||||
| #undef BOOTSTRAP | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "openbios/elfload.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "libc/diskio.h" | ||||
| #include "sys_info.h" | ||||
|  | ||||
| int elf_load(struct sys_info *, const char *filename, const char *cmdline); | ||||
| int linux_load(struct sys_info *, const char *filename, const char *cmdline); | ||||
|  | ||||
| void boot(void); | ||||
|  | ||||
| struct sys_info sys_info;                                                        | ||||
|  | ||||
| void boot(void) | ||||
| { | ||||
| 	char *path=pop_fstr_copy(), *param; | ||||
| 	 | ||||
| 	// char *param="root=/dev/hda2 console=ttyS0,115200n8 console=tty0"; | ||||
| 	 | ||||
| 	if(!path) { | ||||
| 		printk("[x86] Booting default not supported.\n"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	param = strchr(path, ' '); | ||||
| 	if(param) { | ||||
| 		*param = '\0'; | ||||
| 		param++; | ||||
| 	} | ||||
| 	 | ||||
| 	printk("[x86] Booting file '%s' with parameters '%s'\n",path, param); | ||||
|  | ||||
| 	if (elf_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) | ||||
| 		if (linux_load(&sys_info, path, param) == LOADER_NOT_SUPPORT) | ||||
| 			printk("Unsupported image format\n"); | ||||
|  | ||||
| 	free(path); | ||||
| } | ||||
							
								
								
									
										6
									
								
								arch/amd64/build.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								arch/amd64/build.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| <build condition="AMD64"> | ||||
|  <dictionary name="openbios-amd64" init="openbios" target="forth"> | ||||
|   <object source="init.fs"/> | ||||
|  </dictionary> | ||||
| </build> | ||||
|  | ||||
							
								
								
									
										26
									
								
								arch/amd64/builtin.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								arch/amd64/builtin.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| /* tag: openbios forth starter for builtin dictionary for amd64 | ||||
|  * | ||||
|  * Copyright (C) 2003 Stefan Reinauer | ||||
|  * | ||||
|  * See the file "COPYING" for further information about | ||||
|  * the copyright and warranty status of this work. | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include <asm/types.h> | ||||
| #include "sys_info.h" | ||||
|  | ||||
| /* | ||||
|  * wrap an array around the hex'ed dictionary file | ||||
|  */ | ||||
|  | ||||
| #include "static-dict.h" | ||||
|  | ||||
| void collect_multiboot_info(struct sys_info *info); | ||||
| void collect_multiboot_info(struct sys_info *info) | ||||
| { | ||||
| 	info->dict_start=(unsigned long *)forth_dictionary; | ||||
| 	info->dict_end=(unsigned long *)((ucell)forth_dictionary + | ||||
| 			sizeof(forth_dictionary)); | ||||
| } | ||||
|  | ||||
							
								
								
									
										412
									
								
								arch/amd64/console.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										412
									
								
								arch/amd64/console.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,412 @@ | ||||
| /* | ||||
|  * Copyright (C) 2003, 2004 Stefan Reinauer | ||||
|  * | ||||
|  * See the file "COPYING" for further information about | ||||
|  * the copyright and warranty status of this work. | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "openbios.h" | ||||
|  | ||||
| #ifdef CONFIG_DEBUG_CONSOLE | ||||
|  | ||||
| /* ****************************************************************** | ||||
|  *                       serial console functions | ||||
|  * ****************************************************************** */ | ||||
|  | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_SERIAL | ||||
|  | ||||
| #define RBR(x)  x==2?0x2f8:0x3f8 | ||||
| #define THR(x)  x==2?0x2f8:0x3f8 | ||||
| #define IER(x)  x==2?0x2f9:0x3f9 | ||||
| #define IIR(x)  x==2?0x2fa:0x3fa | ||||
| #define LCR(x)  x==2?0x2fb:0x3fb | ||||
| #define MCR(x)  x==2?0x2fc:0x3fc | ||||
| #define LSR(x)  x==2?0x2fd:0x3fd | ||||
| #define MSR(x)  x==2?0x2fe:0x3fe | ||||
| #define SCR(x)  x==2?0x2ff:0x3ff | ||||
| #define DLL(x)  x==2?0x2f8:0x3f8 | ||||
| #define DLM(x)  x==2?0x2f9:0x3f9 | ||||
|  | ||||
| static int uart_charav(int port) | ||||
| { | ||||
| 	if (!port) | ||||
| 		return -1; | ||||
| 	return ((inb(LSR(port)) & 1) != 0); | ||||
| } | ||||
|  | ||||
| static char uart_getchar(int port) | ||||
| { | ||||
| 	if (!port) | ||||
| 		return -1; | ||||
| 	while (!uart_charav(port)); | ||||
| 	return ((char) inb(RBR(port)) & 0177); | ||||
| } | ||||
|  | ||||
| static void uart_putchar(int port, unsigned char c) | ||||
| { | ||||
| 	if (!port) | ||||
| 		return; | ||||
| 	if (c == '\n') | ||||
| 		uart_putchar(port, '\r'); | ||||
| 	while (!(inb(LSR(port)) & 0x20)); | ||||
| 	outb(c, THR(port)); | ||||
| } | ||||
|  | ||||
| static void uart_init_line(int port, unsigned long baud) | ||||
| { | ||||
| 	int i, baudconst; | ||||
|  | ||||
| 	if (!port) | ||||
| 		return; | ||||
|  | ||||
| 	switch (baud) { | ||||
| 	case 115200: | ||||
| 		baudconst = 1; | ||||
| 		break; | ||||
| 	case 57600: | ||||
| 		baudconst = 2; | ||||
| 		break; | ||||
| 	case 38400: | ||||
| 		baudconst = 3; | ||||
| 		break; | ||||
| 	case 19200: | ||||
| 		baudconst = 6; | ||||
| 		break; | ||||
| 	case 9600: | ||||
| 	default: | ||||
| 		baudconst = 12; | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	outb(0x87, LCR(port)); | ||||
| 	outb(0x00, DLM(port)); | ||||
| 	outb(baudconst, DLL(port)); | ||||
| 	outb(0x07, LCR(port)); | ||||
| 	outb(0x0f, MCR(port)); | ||||
|  | ||||
| 	for (i = 10; i > 0; i--) { | ||||
| 		if (inb(LSR(port)) == (unsigned int) 0) | ||||
| 			break; | ||||
| 		inb(RBR(port)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int uart_init(int port, unsigned long speed) | ||||
| { | ||||
| 	if (port) | ||||
| 		uart_init_line(port, speed); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static void serial_putchar(int c) | ||||
| { | ||||
| 	uart_putchar(CONFIG_SERIAL_PORT, (unsigned char) (c & 0xff)); | ||||
| } | ||||
|  | ||||
| static void serial_cls(void) | ||||
| { | ||||
| 	serial_putchar(27); | ||||
| 	serial_putchar('['); | ||||
| 	serial_putchar('H'); | ||||
| 	serial_putchar(27); | ||||
| 	serial_putchar('['); | ||||
| 	serial_putchar('J'); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /* ****************************************************************** | ||||
|  *          simple polling video/keyboard console functions | ||||
|  * ****************************************************************** */ | ||||
|  | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_VGA | ||||
|  | ||||
| /* raw vga text mode */ | ||||
| #define COLUMNS			80	/* The number of columns.  */ | ||||
| #define LINES			25	/* The number of lines.  */ | ||||
| #define ATTRIBUTE		7	/* The attribute of an character.  */ | ||||
|  | ||||
| #define VGA_BASE		0xB8000	/* The video memory address.  */ | ||||
|  | ||||
| /* VGA Index and Data Registers */ | ||||
| #define VGA_REG_INDEX    0x03D4	/* VGA index register */ | ||||
| #define VGA_REG_DATA     0x03D5	/* VGA data register */ | ||||
|  | ||||
| #define VGA_IDX_CURMSL   0x09	/* cursor maximum scan line */ | ||||
| #define VGA_IDX_CURSTART 0x0A	/* cursor start */ | ||||
| #define VGA_IDX_CUREND   0x0B	/* cursor end */ | ||||
| #define VGA_IDX_CURLO    0x0F	/* cursor position (low 8 bits) */ | ||||
| #define VGA_IDX_CURHI    0x0E	/* cursor position (high 8 bits) */ | ||||
|  | ||||
| /* Save the X and Y position.  */ | ||||
| static int xpos, ypos; | ||||
| /* Point to the video memory.  */ | ||||
| static volatile unsigned char *video = (unsigned char *) VGA_BASE; | ||||
|  | ||||
| static void video_initcursor(void) | ||||
| { | ||||
| 	u8 val; | ||||
| 	outb(VGA_IDX_CURMSL, VGA_REG_INDEX); | ||||
| 	val = inb(VGA_REG_DATA) & 0x1f;	/* maximum scan line -1 */ | ||||
|  | ||||
| 	outb(VGA_IDX_CURSTART, VGA_REG_INDEX); | ||||
| 	outb(0, VGA_REG_DATA); | ||||
|  | ||||
| 	outb(VGA_IDX_CUREND, VGA_REG_INDEX); | ||||
| 	outb(val, VGA_REG_DATA); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| static void video_poscursor(unsigned int x, unsigned int y) | ||||
| { | ||||
| 	unsigned short pos; | ||||
|  | ||||
| 	/* Calculate new cursor position as a function of x and y */ | ||||
| 	pos = (y * COLUMNS) + x; | ||||
|  | ||||
| 	/* Output the new position to VGA card */ | ||||
| 	outb(VGA_IDX_CURLO, VGA_REG_INDEX);	/* output low 8 bits */ | ||||
| 	outb((u8) (pos), VGA_REG_DATA); | ||||
| 	outb(VGA_IDX_CURHI, VGA_REG_INDEX);	/* output high 8 bits */ | ||||
| 	outb((u8) (pos >> 8), VGA_REG_DATA); | ||||
|  | ||||
| }; | ||||
|  | ||||
|  | ||||
| static void video_newline(void) | ||||
| { | ||||
| 	xpos = 0; | ||||
|  | ||||
| 	if (ypos < LINES - 1) { | ||||
| 		ypos++; | ||||
| 	} else { | ||||
| 		int i; | ||||
| 		memmove((void *) video, (void *) (video + 2 * COLUMNS), | ||||
| 			(LINES - 1) * COLUMNS * 2); | ||||
|  | ||||
| 		for (i = ((LINES - 1) * 2 * COLUMNS); | ||||
| 		     i < 2 * COLUMNS * LINES;) { | ||||
| 			video[i++] = 0; | ||||
| 			video[i++] = ATTRIBUTE; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| /* Put the character C on the screen.  */ | ||||
| static void video_putchar(int c) | ||||
| { | ||||
| 	int p=1; | ||||
| 	 | ||||
| 	if (c == '\n' || c == '\r') { | ||||
| 		video_newline(); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (c == '\b') { | ||||
| 		if (xpos) xpos--; | ||||
| 		c=' '; | ||||
| 		p=0; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	if (xpos >= COLUMNS) | ||||
| 		video_newline(); | ||||
|  | ||||
| 	*(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF; | ||||
| 	*(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE; | ||||
|  | ||||
| 	if (p) | ||||
| 		xpos++; | ||||
|  | ||||
| 	video_poscursor(xpos, ypos); | ||||
| } | ||||
|  | ||||
| static void video_cls(void) | ||||
| { | ||||
| 	int i; | ||||
| 	 | ||||
| 	for (i = 0; i < 2 * COLUMNS * LINES;) { | ||||
| 		video[i++] = 0; | ||||
| 		video[i++] = ATTRIBUTE; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	xpos = 0; | ||||
| 	ypos = 0; | ||||
|  | ||||
| 	video_initcursor(); | ||||
| 	video_poscursor(xpos, ypos); | ||||
| } | ||||
|  | ||||
| void video_init(void) | ||||
| { | ||||
| 	video=phys_to_virt((unsigned char*)VGA_BASE); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  *  keyboard driver | ||||
|  */ | ||||
|  | ||||
| static char normal[] = { | ||||
| 	0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', | ||||
| 	'=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', | ||||
| 	'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j', | ||||
| 	'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b', | ||||
| 	'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, | ||||
| 	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, | ||||
| 	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f | ||||
| }; | ||||
|  | ||||
| static char shifted[] = { | ||||
| 	0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', | ||||
| 	'+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', | ||||
| 	'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', | ||||
| 	'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B', | ||||
| 	'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, | ||||
| 	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8', | ||||
| 	'9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f | ||||
| }; | ||||
|  | ||||
| static int key_ext; | ||||
| static int key_lshift = 0, key_rshift = 0, key_caps = 0; | ||||
|  | ||||
| static char last_key; | ||||
|  | ||||
| static void keyboard_cmd(unsigned char cmd, unsigned char val) | ||||
| { | ||||
| 	outb(cmd, 0x60); | ||||
| 	/* wait until keyboard controller accepts cmds: */ | ||||
| 	while (inb(0x64) & 2); | ||||
| 	outb(val, 0x60); | ||||
| 	while (inb(0x64) & 2); | ||||
| } | ||||
|  | ||||
| static char keyboard_poll(void) | ||||
| { | ||||
| 	unsigned int c; | ||||
| 	if (inb(0x64) & 1) { | ||||
| 		c = inb(0x60); | ||||
| 		switch (c) { | ||||
| 		case 0xe0: | ||||
| 			key_ext = 1; | ||||
| 			return 0; | ||||
| 		case 0x2a: | ||||
| 			key_lshift = 1; | ||||
| 			return 0; | ||||
| 		case 0x36: | ||||
| 			key_rshift = 1; | ||||
| 			return 0; | ||||
| 		case 0xaa: | ||||
| 			key_lshift = 0; | ||||
| 			return 0; | ||||
| 		case 0xb6: | ||||
| 			key_rshift = 0; | ||||
| 			return 0; | ||||
| 		case 0x3a: | ||||
| 			if (key_caps) { | ||||
| 				key_caps = 0; | ||||
| 				keyboard_cmd(0xed, 0); | ||||
| 			} else { | ||||
| 				key_caps = 1; | ||||
| 				keyboard_cmd(0xed, 4);	/* set caps led */ | ||||
| 			} | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (key_ext) { | ||||
| 			// void printk(const char *format, ...); | ||||
| 			printk("extended keycode: %x\n", c); | ||||
|  | ||||
| 			key_ext = 0; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		if (c & 0x80)	/* unhandled key release */ | ||||
| 			return 0; | ||||
|  | ||||
| 		if (key_lshift || key_rshift) | ||||
| 			return key_caps ? normal[c] : shifted[c]; | ||||
| 		else | ||||
| 			return key_caps ? shifted[c] : normal[c]; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int keyboard_dataready(void) | ||||
| { | ||||
| 	if (last_key) | ||||
| 		return 1; | ||||
|  | ||||
| 	last_key = keyboard_poll(); | ||||
|  | ||||
| 	return (last_key != 0); | ||||
| } | ||||
|  | ||||
| static unsigned char keyboard_readdata(void) | ||||
| { | ||||
| 	char tmp; | ||||
| 	while (!keyboard_dataready()); | ||||
| 	tmp = last_key; | ||||
| 	last_key = 0; | ||||
| 	return tmp; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* ****************************************************************** | ||||
|  *      common functions, implementing simple concurrent console | ||||
|  * ****************************************************************** */ | ||||
|  | ||||
| int putchar(int c) | ||||
| { | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_SERIAL | ||||
| 	serial_putchar(c); | ||||
| #endif | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_VGA | ||||
| 	video_putchar(c); | ||||
| #endif | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| int availchar(void) | ||||
| { | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_SERIAL | ||||
| 	if (uart_charav(CONFIG_SERIAL_PORT)) | ||||
| 		return 1; | ||||
| #endif | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_VGA | ||||
| 	if (keyboard_dataready()) | ||||
| 		return 1; | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int getchar(void) | ||||
| { | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_SERIAL | ||||
| 	if (uart_charav(CONFIG_SERIAL_PORT)) | ||||
| 		return (uart_getchar(CONFIG_SERIAL_PORT)); | ||||
| #endif | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_VGA | ||||
| 	if (keyboard_dataready()) | ||||
| 		return (keyboard_readdata()); | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void cls(void) | ||||
| { | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_SERIAL | ||||
| 	serial_cls(); | ||||
| #endif | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_VGA | ||||
| 	video_cls(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif				// CONFIG_DEBUG_CONSOLE | ||||
							
								
								
									
										124
									
								
								arch/amd64/context.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								arch/amd64/context.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,124 @@ | ||||
| /* | ||||
|  * context switching | ||||
|  * 2003-10 by SONE Takeshi | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "segment.h" | ||||
| #include "context.h" | ||||
|  | ||||
| #define MAIN_STACK_SIZE 16384 | ||||
| #define IMAGE_STACK_SIZE 4096 | ||||
|  | ||||
| #define debug printk | ||||
|  | ||||
| static void start_main(void); /* forward decl. */ | ||||
| void __exit_context(void); /* assembly routine */ | ||||
|  | ||||
| /* | ||||
|  * Main context structure  | ||||
|  * It is placed at the bottom of our stack, and loaded by assembly routine | ||||
|  * to start us up. | ||||
|  */ | ||||
| struct context main_ctx __attribute__((section (".initctx"))) = { | ||||
|     .gdt_base = (uint64_t) gdt, | ||||
|     .gdt_limit = GDT_LIMIT, | ||||
|     .cs = FLAT_CS, | ||||
|     .ds = FLAT_DS, | ||||
|     .es = FLAT_DS, | ||||
|     .fs = FLAT_DS, | ||||
|     .gs = FLAT_DS, | ||||
|     .ss = FLAT_DS, | ||||
|     .esp = (uint32_t) ESP_LOC(&main_ctx), | ||||
|     .eip = (uint32_t) start_main, | ||||
|     .return_addr = (uint32_t) __exit_context, | ||||
| }; | ||||
|  | ||||
| /* This is used by assembly routine to load/store the context which | ||||
|  * it is to switch/switched.  */ | ||||
| struct context *__context = &main_ctx; | ||||
|  | ||||
| /* Stack for loaded ELF image */ | ||||
| static uint8_t image_stack[IMAGE_STACK_SIZE]; | ||||
|  | ||||
| /* Pointer to startup context (physical address) */ | ||||
| unsigned long __boot_ctx; | ||||
|  | ||||
| /* | ||||
|  * Main starter | ||||
|  * This is the C function that runs first. | ||||
|  */ | ||||
| static void start_main(void) | ||||
| { | ||||
|     int retval; | ||||
|     extern int openbios(void); | ||||
|  | ||||
|     /* Save startup context, so we can refer to it later. | ||||
|      * We have to keep it in physical address since we will relocate. */ | ||||
|     __boot_ctx = virt_to_phys(__context); | ||||
|  | ||||
|     /* Start the real fun */ | ||||
|     retval = openbios(); | ||||
|  | ||||
|     /* Pass return value to startup context. Bootloader may see it. */ | ||||
|     boot_ctx->eax = retval; | ||||
|  | ||||
|     /* Returning from here should jump to __exit_context */ | ||||
|     __context = boot_ctx; | ||||
| } | ||||
|  | ||||
| /* Setup a new context using the given stack. | ||||
|  */ | ||||
| struct context * | ||||
| init_context(uint8_t *stack, uint32_t stack_size, int num_params) | ||||
| { | ||||
|     struct context *ctx; | ||||
|  | ||||
|     ctx = (struct context *) | ||||
| 	(stack + stack_size - (sizeof(*ctx) + num_params*sizeof(uint32_t))); | ||||
|     memset(ctx, 0, sizeof(*ctx)); | ||||
|  | ||||
|     /* Fill in reasonable default for flat memory model */ | ||||
|     ctx->gdt_base = virt_to_phys(gdt); | ||||
|     ctx->gdt_limit = GDT_LIMIT; | ||||
|     ctx->cs = FLAT_CS; | ||||
|     ctx->ds = FLAT_DS; | ||||
|     ctx->es = FLAT_DS; | ||||
|     ctx->fs = FLAT_DS; | ||||
|     ctx->gs = FLAT_DS; | ||||
|     ctx->ss = FLAT_DS; | ||||
|     ctx->esp = virt_to_phys(ESP_LOC(ctx)); | ||||
|     ctx->return_addr = virt_to_phys(__exit_context); | ||||
|  | ||||
|     return ctx; | ||||
| } | ||||
|  | ||||
| /* Switch to another context. */ | ||||
| struct context *switch_to(struct context *ctx) | ||||
| { | ||||
|     struct context *save, *ret; | ||||
|  | ||||
|     debug("switching to new context:\n"); | ||||
|     save = __context; | ||||
|     __context = ctx; | ||||
|     asm ("pushl %cs; call __switch_context"); | ||||
|     ret = __context; | ||||
|     __context = save; | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| /* Start ELF Boot image */ | ||||
| uint32_t start_elf(uint32_t entry_point, uint32_t param) | ||||
| { | ||||
|     struct context *ctx; | ||||
|  | ||||
|     ctx = init_context(image_stack, sizeof image_stack, 1); | ||||
|     ctx->eip = entry_point; | ||||
|     ctx->param[0] = param; | ||||
|     ctx->eax = 0xe1fb007; | ||||
|     ctx->ebx = param; | ||||
|  | ||||
|     ctx = switch_to(ctx); | ||||
|     return ctx->eax; | ||||
| } | ||||
							
								
								
									
										48
									
								
								arch/amd64/context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								arch/amd64/context.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| #ifndef AMD64_CONTEXT_H | ||||
| #define AMD64_CONTEXT_H | ||||
|  | ||||
| struct context { | ||||
|     /* Stack Segment, placed here because of the alignment issue... */ | ||||
|     uint16_t ss; | ||||
|     /* Used with sgdt/lgdt */ | ||||
|     uint16_t gdt_limit; | ||||
|     uint64_t gdt_base; | ||||
|     /* General registers, accessed with pushal/popal */ | ||||
|     uint32_t edi; | ||||
|     uint32_t esi; | ||||
|     uint32_t ebp; | ||||
|     uint32_t esp; /* points just below eax */ | ||||
|     uint32_t ebx; | ||||
|     uint32_t edx; | ||||
|     uint32_t ecx; | ||||
|     uint32_t eax; | ||||
| #define ESP_LOC(ctx) (&(ctx)->gs) | ||||
|     /* Segment registers */ | ||||
|     uint32_t gs; | ||||
|     uint32_t fs; | ||||
|     uint32_t es; | ||||
|     uint32_t ds; | ||||
|     /* Flags */ | ||||
|     uint32_t eflags; | ||||
|     /* Code segment:offset */ | ||||
|     uint32_t eip; | ||||
|     uint32_t cs; | ||||
|     /* Optional stack contents */ | ||||
|     uint32_t return_addr; | ||||
|     uint32_t param[0]; | ||||
| }; | ||||
|  | ||||
| /* Create a new context in the given stack */ | ||||
| struct context * | ||||
| init_context(uint8_t *stack, uint32_t stack_size, int num_param); | ||||
|  | ||||
| /* Switch context */ | ||||
| struct context *switch_to(struct context *); | ||||
|  | ||||
| /* Holds physical address of boot context */ | ||||
| extern unsigned long __boot_ctx; | ||||
|  | ||||
| /* This can always be safely used to refer to the boot context */ | ||||
| #define boot_ctx ((struct context *) phys_to_virt(__boot_ctx)) | ||||
|  | ||||
| #endif /* AMD64_CONTEXT_H */ | ||||
							
								
								
									
										65
									
								
								arch/amd64/defconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								arch/amd64/defconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| # | ||||
| # Automatically generated make config: don't edit | ||||
| # | ||||
| CONFIG_AMD64=y | ||||
| CONFIG_LITTLE_ENDIAN=y | ||||
|  | ||||
| # | ||||
| # Kernel binaries (AMD64) | ||||
| # | ||||
| # CONFIG_IMAGE_ELF is not set | ||||
| # CONFIG_IMAGE_ELF_EMBEDDED is not set | ||||
| # CONFIG_IMAGE_ELF_MULTIBOOT is not set | ||||
|  | ||||
| # | ||||
| # Build hosted UNIX Binary | ||||
| # | ||||
| CONFIG_HOST_UNIX=y | ||||
| # CONFIG_PLUGIN_PCI is not set | ||||
|  | ||||
| # | ||||
| # Kernel Debugging | ||||
| # | ||||
| # CONFIG_DEBUG is not set | ||||
| CONFIG_DEBUG_CONSOLE=y | ||||
| CONFIG_DEBUG_CONSOLE_SERIAL=y | ||||
| CONFIG_SERIAL_PORT=1 | ||||
| CONFIG_SERIAL_SPEED=115200 | ||||
| CONFIG_DEBUG_CONSOLE_VGA=y | ||||
|  | ||||
| # | ||||
| # Module Configuration | ||||
| # | ||||
| CONFIG_CMDLINE=y | ||||
| CONFIG_DEBLOCKER=y | ||||
|  | ||||
| # | ||||
| # Filesystem Configuration | ||||
| # | ||||
| CONFIG_DISK_LABEL=y | ||||
| CONFIG_PART_SUPPORT=y | ||||
| CONFIG_PC_PARTS=y | ||||
| CONFIG_FS=y | ||||
| CONFIG_GRUBFS=y | ||||
| CONFIG_FSYS_EXT2FS=y | ||||
| CONFIG_FSYS_FAT=y | ||||
| CONFIG_FSYS_JFS=y | ||||
| # CONFIG_FSYS_MINIX is not set | ||||
| CONFIG_FSYS_REISERFS=y | ||||
| CONFIG_FSYS_XFS=y | ||||
| CONFIG_FSYS_ISO9660=y | ||||
| # CONFIG_FSYS_FFS is not set | ||||
| # CONFIG_FSYS_VSTAFS is not set | ||||
| # CONFIG_DEBUG_FS is not set | ||||
|  | ||||
| # | ||||
| # Miscellaneous | ||||
| # | ||||
| CONFIG_LINUXBIOS=y | ||||
|  | ||||
| # | ||||
| # Drivers | ||||
| # | ||||
| CONFIG_DRIVER_PCI=y | ||||
| CONFIG_DRIVER_IDE=y | ||||
| # CONFIG_DEBUG_IDE is not set | ||||
							
								
								
									
										387
									
								
								arch/amd64/elfload.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								arch/amd64/elfload.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,387 @@ | ||||
| /* ELF Boot loader | ||||
|  * As we have seek, this implementation can be straightforward. | ||||
|  * 2003-07 by SONE Takeshi | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "openbios/elf.h" | ||||
| #include "asm/elf.h" | ||||
| #include "elf_boot.h" | ||||
| #include "sys_info.h" | ||||
| #include "ipchecksum.h" | ||||
| #include "loadfs.h" | ||||
| #define printf printk | ||||
| #define debug printk | ||||
|  | ||||
| extern unsigned int start_elf(unsigned long entry_point, unsigned long param); | ||||
| extern char _start, _end; | ||||
|  | ||||
| static char *image_name, *image_version; | ||||
|  | ||||
| static void *calloc(size_t nmemb, size_t size) | ||||
| { | ||||
|     size_t alloc_size = nmemb * size; | ||||
|     void *mem; | ||||
|  | ||||
|     if (alloc_size < nmemb || alloc_size < size) { | ||||
|         printf("calloc overflow: %u, %u\n", nmemb, size); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     mem = malloc(alloc_size); | ||||
|     memset(mem, 0, alloc_size); | ||||
|  | ||||
|     return mem; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int check_mem_ranges(struct sys_info *info, | ||||
| 	Elf_phdr *phdr, int phnum) | ||||
| { | ||||
|     int i, j; | ||||
|     unsigned long start, end; | ||||
|     unsigned long prog_start, prog_end; | ||||
|     struct memrange *mem; | ||||
|  | ||||
|     prog_start = virt_to_phys(&_start); | ||||
|     prog_end = virt_to_phys(&_end); | ||||
|  | ||||
|     for (i = 0; i < phnum; i++) { | ||||
| 	if (phdr[i].p_type != PT_LOAD) | ||||
| 	    continue; | ||||
| 	start = phdr[i].p_paddr; | ||||
| 	end = start + phdr[i].p_memsz; | ||||
| 	if (start < prog_start && end > prog_start) | ||||
| 	    goto conflict; | ||||
| 	if (start < prog_end && end > prog_end) | ||||
| 	    goto conflict; | ||||
| 	mem=info->memrange; | ||||
| 	for (j = 0; j < info->n_memranges; j++) { | ||||
| 	    if (mem[j].base <= start && mem[j].base + mem[j].size >= end) | ||||
| 		break; | ||||
| 	} | ||||
| 	if (j >= info->n_memranges) | ||||
| 	    goto badseg; | ||||
|     } | ||||
|     return 1; | ||||
|  | ||||
| conflict: | ||||
|     printf("%s occupies [%#lx-%#lx]\n", program_name, prog_start, prog_end); | ||||
|  | ||||
| badseg: | ||||
|     printf("Segment %d [%#lx-%#lx] doesn't fit into memory\n", i, start, end-1); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static unsigned long process_image_notes(Elf_phdr *phdr, int phnum, | ||||
| 	unsigned short *sum_ptr) | ||||
| { | ||||
|     int i; | ||||
|     char *buf = NULL; | ||||
|     int retval = 0; | ||||
|     unsigned long addr, end; | ||||
|     Elf_Nhdr *nhdr; | ||||
|     const char *name; | ||||
|     void *desc; | ||||
|  | ||||
|     for (i = 0; i < phnum; i++) { | ||||
| 	if (phdr[i].p_type != PT_NOTE) | ||||
| 	    continue; | ||||
| 	buf = malloc(phdr[i].p_filesz); | ||||
| 	file_seek(phdr[i].p_offset); | ||||
| 	if (lfile_read(buf, phdr[i].p_filesz) != phdr[i].p_filesz) { | ||||
| 	    printf("Can't read note segment\n"); | ||||
| 	    goto out; | ||||
| 	} | ||||
| 	addr = (unsigned long) buf; | ||||
| 	end = addr + phdr[i].p_filesz; | ||||
| 	while (addr < end) { | ||||
| 	    nhdr = (Elf_Nhdr *) addr; | ||||
| 	    addr += sizeof(Elf_Nhdr); | ||||
| 	    name = (const char *) addr; | ||||
| 	    addr += (nhdr->n_namesz+3) & ~3; | ||||
| 	    desc = (void *) addr; | ||||
| 	    addr += (nhdr->n_descsz+3) & ~3; | ||||
|  | ||||
| 	    if (nhdr->n_namesz==sizeof(ELF_NOTE_BOOT) | ||||
| 		    && memcmp(name, ELF_NOTE_BOOT, sizeof(ELF_NOTE_BOOT))==0) { | ||||
| 		if (nhdr->n_type == EIN_PROGRAM_NAME) { | ||||
| 		    image_name = calloc(1, nhdr->n_descsz + 1); | ||||
| 		    memcpy(image_name, desc, nhdr->n_descsz); | ||||
| 		} | ||||
| 		if (nhdr->n_type == EIN_PROGRAM_VERSION) { | ||||
| 		    image_version = calloc(1, nhdr->n_descsz + 1); | ||||
| 		    memcpy(image_version, desc, nhdr->n_descsz); | ||||
| 		} | ||||
| 		if (nhdr->n_type == EIN_PROGRAM_CHECKSUM) { | ||||
| 		    *sum_ptr = *(unsigned short *) desc; | ||||
| 		    debug("Image checksum: %#04x\n", *sum_ptr); | ||||
| 		    /* Where in the file */ | ||||
| 		    retval = phdr[i].p_offset | ||||
| 			+ (unsigned long) desc - (unsigned long) buf; | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
| out: | ||||
|     if (buf) | ||||
| 	free(buf); | ||||
|     return retval; | ||||
| } | ||||
|  | ||||
| static int load_segments(Elf_phdr *phdr, int phnum, | ||||
| 	unsigned long checksum_offset) | ||||
| { | ||||
|     unsigned long bytes; | ||||
|     //unsigned int start_time, time; | ||||
|     int i; | ||||
|  | ||||
|     bytes = 0; | ||||
|     // start_time = currticks(); | ||||
|     for (i = 0; i < phnum; i++) { | ||||
| 	if (phdr[i].p_type != PT_LOAD) | ||||
| 	    continue; | ||||
| 	debug("segment %d addr:%#x file:%#x mem:%#x ", | ||||
| 		i, phdr[i].p_paddr, phdr[i].p_filesz, phdr[i].p_memsz); | ||||
| 	file_seek(phdr[i].p_offset); | ||||
| 	debug("loading... "); | ||||
| 	if (lfile_read(phys_to_virt(phdr[i].p_paddr), phdr[i].p_filesz) | ||||
| 		!= phdr[i].p_filesz) { | ||||
| 	    printf("Can't read program segment %d\n", i); | ||||
| 	    return 0; | ||||
| 	} | ||||
| 	bytes += phdr[i].p_filesz; | ||||
| 	debug("clearing... "); | ||||
| 	memset(phys_to_virt(phdr[i].p_paddr + phdr[i].p_filesz), 0,  | ||||
| 		phdr[i].p_memsz - phdr[i].p_filesz); | ||||
| 	if (phdr[i].p_offset <= checksum_offset | ||||
| 		&& phdr[i].p_offset + phdr[i].p_filesz >= checksum_offset+2) { | ||||
| 	    debug("clearing checksum... "); | ||||
| 	    memset(phys_to_virt(phdr[i].p_paddr + checksum_offset | ||||
| 			- phdr[i].p_offset), 0, 2); | ||||
| 	} | ||||
| 	debug("ok\n"); | ||||
|  | ||||
|     } | ||||
|     // time = currticks() - start_time; | ||||
|     //debug("Loaded %lu bytes in %ums (%luKB/s)\n", bytes, time, | ||||
|     //	    time? bytes/time : 0); | ||||
|     debug("Loaded %lu bytes \n", bytes); | ||||
|  | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| static int verify_image(Elf_ehdr *ehdr, Elf_phdr *phdr, int phnum, | ||||
| 	unsigned short image_sum) | ||||
| { | ||||
|     unsigned short sum, part_sum; | ||||
|     unsigned long offset; | ||||
|     int i; | ||||
|  | ||||
|     sum = 0; | ||||
|     offset = 0; | ||||
|  | ||||
|     part_sum = ipchksum(ehdr, sizeof *ehdr); | ||||
|     sum = add_ipchksums(offset, sum, part_sum); | ||||
|     offset += sizeof *ehdr; | ||||
|  | ||||
|     part_sum = ipchksum(phdr, phnum * sizeof(*phdr)); | ||||
|     sum = add_ipchksums(offset, sum, part_sum); | ||||
|     offset += phnum * sizeof(*phdr); | ||||
|  | ||||
|     for (i = 0; i < phnum; i++) { | ||||
| 	if (phdr[i].p_type != PT_LOAD) | ||||
| 	    continue; | ||||
| 	part_sum = ipchksum(phys_to_virt(phdr[i].p_paddr), phdr[i].p_memsz); | ||||
| 	sum = add_ipchksums(offset, sum, part_sum); | ||||
| 	offset += phdr[i].p_memsz; | ||||
|     } | ||||
|  | ||||
|     if (sum != image_sum) { | ||||
| 	printf("Verify FAILED (image:%#04x vs computed:%#04x)\n", | ||||
| 		image_sum, sum); | ||||
| 	return 0; | ||||
|     } | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| static inline unsigned const padded(unsigned s) | ||||
| { | ||||
|     return (s + 3) & ~3; | ||||
| } | ||||
|  | ||||
| static Elf_Bhdr *add_boot_note(Elf_Bhdr *bhdr, const char *name, | ||||
| 	unsigned type, const char *desc, unsigned descsz) | ||||
| { | ||||
|     Elf_Nhdr nhdr; | ||||
|     unsigned ent_size, new_size, pad; | ||||
|     char *addr; | ||||
|  | ||||
|     if (!bhdr) | ||||
| 	return NULL; | ||||
|  | ||||
|     nhdr.n_namesz = name? strlen(name)+1 : 0; | ||||
|     nhdr.n_descsz = descsz; | ||||
|     nhdr.n_type = type; | ||||
|     ent_size = sizeof(nhdr) + padded(nhdr.n_namesz) + padded(nhdr.n_descsz); | ||||
|     if (bhdr->b_size + ent_size > 0xffff) { | ||||
| 	printf("Boot notes too big\n"); | ||||
| 	free(bhdr); | ||||
| 	return NULL; | ||||
|     } | ||||
|     if (bhdr->b_size + ent_size > bhdr->b_checksum) { | ||||
| 	do { | ||||
| 	    new_size = bhdr->b_checksum * 2; | ||||
| 	} while (new_size < bhdr->b_size + ent_size); | ||||
| 	if (new_size > 0xffff) | ||||
| 	    new_size = 0xffff; | ||||
| 	debug("expanding boot note size to %u\n", new_size); | ||||
| #ifdef HAVE_REALLOC | ||||
| 	bhdr = realloc(bhdr, new_size); | ||||
| 	bhdr->b_checksum = new_size; | ||||
| #else | ||||
| 	printf("Boot notes too big\n"); | ||||
| 	free(bhdr); | ||||
| 	return NULL; | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     addr = (char *) bhdr; | ||||
|     addr += bhdr->b_size; | ||||
|     memcpy(addr, &nhdr, sizeof(nhdr)); | ||||
|     addr += sizeof(nhdr); | ||||
|  | ||||
|     memcpy(addr, name, nhdr.n_namesz); | ||||
|     addr += nhdr.n_namesz; | ||||
|     pad = padded(nhdr.n_namesz) - nhdr.n_namesz; | ||||
|     memset(addr, 0, pad); | ||||
|     addr += pad; | ||||
|  | ||||
|     memcpy(addr, desc, nhdr.n_descsz); | ||||
|     addr += nhdr.n_descsz; | ||||
|     pad = padded(nhdr.n_descsz) - nhdr.n_descsz; | ||||
|     memset(addr, 0, pad); | ||||
|     addr += pad; | ||||
|  | ||||
|     bhdr->b_size += ent_size; | ||||
|     bhdr->b_records++; | ||||
|     return bhdr; | ||||
| } | ||||
|  | ||||
| static inline Elf_Bhdr *add_note_string(Elf_Bhdr *bhdr, const char *name, | ||||
| 	unsigned type, const char *desc) | ||||
| { | ||||
|     return add_boot_note(bhdr, name, type, desc, strlen(desc) + 1); | ||||
| } | ||||
|  | ||||
| static Elf_Bhdr *build_boot_notes(struct sys_info *info, const char *cmdline) | ||||
| { | ||||
|     Elf_Bhdr *bhdr; | ||||
|  | ||||
|     bhdr = malloc(256); | ||||
|     bhdr->b_signature = ELF_BHDR_MAGIC; | ||||
|     bhdr->b_size = sizeof *bhdr; | ||||
|     bhdr->b_checksum = 256; /* XXX cache the current buffer size here */ | ||||
|     bhdr->b_records = 0; | ||||
|  | ||||
|     if (info->firmware) | ||||
| 	bhdr = add_note_string(bhdr, NULL, EBN_FIRMWARE_TYPE, info->firmware); | ||||
|     bhdr = add_note_string(bhdr, NULL, EBN_BOOTLOADER_NAME, program_name); | ||||
|     bhdr = add_note_string(bhdr, NULL, EBN_BOOTLOADER_VERSION, program_version); | ||||
|     if (cmdline) | ||||
| 	bhdr = add_note_string(bhdr, NULL, EBN_COMMAND_LINE, cmdline); | ||||
|     if (!bhdr) | ||||
| 	return bhdr; | ||||
|     bhdr->b_checksum = 0; | ||||
|     bhdr->b_checksum = ipchksum(bhdr, bhdr->b_size); | ||||
|     return bhdr; | ||||
| } | ||||
|  | ||||
| int elf_load(struct sys_info *info, const char *filename, const char *cmdline) | ||||
| { | ||||
|     Elf_ehdr ehdr; | ||||
|     Elf_phdr *phdr = NULL; | ||||
|     unsigned long phdr_size; | ||||
|     unsigned long checksum_offset; | ||||
|     unsigned short checksum; | ||||
|     Elf_Bhdr *boot_notes = NULL; | ||||
|     int retval = -1; | ||||
|     int image_retval; | ||||
|  | ||||
|     image_name = image_version = 0; | ||||
|  | ||||
|     if (!file_open(filename)) | ||||
| 	goto out; | ||||
|  | ||||
|     if (lfile_read(&ehdr, sizeof ehdr) != sizeof ehdr) { | ||||
| 	debug("Can't read ELF header\n"); | ||||
| 	retval = LOADER_NOT_SUPPORT; | ||||
| 	goto out; | ||||
|     } | ||||
|  | ||||
|     if (ehdr.e_ident[EI_MAG0] != ELFMAG0 | ||||
| 	    || ehdr.e_ident[EI_MAG1] != ELFMAG1 | ||||
| 	    || ehdr.e_ident[EI_MAG2] != ELFMAG2 | ||||
| 	    || ehdr.e_ident[EI_MAG3] != ELFMAG3 | ||||
| 	    || ehdr.e_ident[EI_CLASS] != ARCH_ELF_CLASS | ||||
| 	    || ehdr.e_ident[EI_DATA] != ARCH_ELF_DATA | ||||
| 	    || ehdr.e_ident[EI_VERSION] != EV_CURRENT | ||||
| 	    || ehdr.e_type != ET_EXEC | ||||
| 	    || !ARCH_ELF_MACHINE_OK(ehdr.e_machine) | ||||
| 	    || ehdr.e_version != EV_CURRENT | ||||
| 	    || ehdr.e_phentsize != sizeof(Elf_phdr)) { | ||||
| 	debug("Not a bootable ELF image\n"); | ||||
| 	retval = LOADER_NOT_SUPPORT; | ||||
| 	goto out; | ||||
|     } | ||||
|  | ||||
|     phdr_size = ehdr.e_phnum * sizeof *phdr; | ||||
|     phdr = malloc(phdr_size); | ||||
|     file_seek(ehdr.e_phoff); | ||||
|     if (lfile_read(phdr, phdr_size) != phdr_size) { | ||||
| 	printf("Can't read program header\n"); | ||||
| 	goto out; | ||||
|     } | ||||
|  | ||||
|     if (!check_mem_ranges(info, phdr, ehdr.e_phnum)) | ||||
| 	goto out; | ||||
|  | ||||
|     checksum_offset = process_image_notes(phdr, ehdr.e_phnum, &checksum); | ||||
|  | ||||
|     printf("Loading %s", image_name ? image_name : "image"); | ||||
|     if (image_version) | ||||
| 	printf(" version %s", image_version); | ||||
|     printf("...\n"); | ||||
|  | ||||
|     if (!load_segments(phdr, ehdr.e_phnum, checksum_offset)) | ||||
| 	goto out; | ||||
|      | ||||
|     if (checksum_offset) { | ||||
| 	if (!verify_image(&ehdr, phdr, ehdr.e_phnum, checksum)) | ||||
| 	    goto out; | ||||
|     } | ||||
|  | ||||
|     boot_notes = build_boot_notes(info, cmdline); | ||||
|  | ||||
|     //debug("current time: %lu\n", currticks()); | ||||
|  | ||||
|     debug("entry point is %#x\n", ehdr.e_entry); | ||||
|     printf("Jumping to entry point...\n"); | ||||
|     image_retval = start_elf(ehdr.e_entry, virt_to_phys(boot_notes)); | ||||
|  | ||||
|     // console_init(); FIXME | ||||
|     printf("Image returned with return value %#x\n", image_retval); | ||||
|     retval = 0; | ||||
|  | ||||
| out: | ||||
|     if (phdr) | ||||
| 	free(phdr); | ||||
|     if (boot_notes) | ||||
| 	free(boot_notes); | ||||
|     if (image_name) | ||||
| 	free(image_name); | ||||
|     if (image_version) | ||||
| 	free(image_version); | ||||
|     return retval; | ||||
| } | ||||
							
								
								
									
										77
									
								
								arch/amd64/init.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								arch/amd64/init.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| :noname  | ||||
|   ."   Type 'help' for detailed information" cr | ||||
|   \ ."   boot secondary slave cdrom: " cr | ||||
|   \ ."    0 >  boot hd:2,\boot\vmlinuz root=/dev/hda2" cr | ||||
|   ; DIAG-initializer | ||||
|  | ||||
| " /" find-device | ||||
|  | ||||
| new-device | ||||
|   " memory" device-name | ||||
|   \ 12230 encode-int " reg" property | ||||
|   external | ||||
|   : open true ; | ||||
|   : close ; | ||||
|   \ claim ( phys size align -- base ) | ||||
|   \ release ( phys size -- ) | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
|   " cpus" device-name | ||||
|   1 " #address-cells" int-property | ||||
|   0 " #size-cells" int-property | ||||
|  | ||||
|   external | ||||
|   : open true ; | ||||
|   : close ; | ||||
|   : decode-unit parse-hex ; | ||||
|  | ||||
| finish-device | ||||
|  | ||||
| : make-openable ( path ) | ||||
|   find-dev if | ||||
|     begin ?dup while | ||||
|       \ install trivial open and close methods | ||||
|       dup active-package! is-open | ||||
|       parent | ||||
|     repeat | ||||
|   then | ||||
| ; | ||||
|  | ||||
| : preopen ( chosen-str node-path ) | ||||
|   2dup make-openable | ||||
|      | ||||
|   " /chosen" find-device | ||||
|   open-dev ?dup if | ||||
|     encode-int 2swap property | ||||
|   else | ||||
|     2drop | ||||
|   then | ||||
| ; | ||||
|   | ||||
| :noname | ||||
|   set-defaults | ||||
| ; SYSTEM-initializer | ||||
|  | ||||
| \ preopen device nodes (and store the ihandles under /chosen) | ||||
| :noname | ||||
|   " memory" " /memory" preopen | ||||
|   " mmu" " /cpus/@0" preopen | ||||
|   " stdout" " /builtin/console" preopen | ||||
|   " stdin" " /builtin/console" preopen | ||||
|  | ||||
| ; SYSTEM-initializer | ||||
|  | ||||
| \ use the tty interface if available | ||||
| :noname | ||||
|   " /builtin/console" find-dev if drop | ||||
|     " /builtin/console" " input-device" $setenv | ||||
|     " /builtin/console" " output-device" $setenv | ||||
|   then | ||||
| ; SYSTEM-initializer | ||||
| 	     | ||||
| :noname | ||||
|   " keyboard" input | ||||
| ; CONSOLE-IN-initializer | ||||
|    | ||||
|  | ||||
							
								
								
									
										73
									
								
								arch/amd64/ldscript
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								arch/amd64/ldscript
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | ||||
| OUTPUT_FORMAT(elf32-i386) | ||||
| OUTPUT_ARCH(i386) | ||||
|  | ||||
| ENTRY(entry) | ||||
|  | ||||
| /* Initial load address | ||||
|  * To be loaded by GRUB, this must be >= 1MB | ||||
|  */ | ||||
| BASE_ADDR = 0x100000; | ||||
|  | ||||
| /* 16KB heap and stack */ | ||||
| HEAP_SIZE = 16384; | ||||
| STACK_SIZE = 16384; | ||||
|  | ||||
| SECTIONS | ||||
| { | ||||
|     . = BASE_ADDR; | ||||
|  | ||||
|     /* Put Multiboot header near beginning of file, if any. */ | ||||
|     .hdr : { *(.hdr) *(.hdr.*) } | ||||
|  | ||||
|     /* Start of the program.  | ||||
|      * Now the version string is in the note, we must include it | ||||
|      * in the program. Otherwise we lose the string after relocation. */ | ||||
|     . = ALIGN(16); | ||||
|     _start = .; | ||||
|  | ||||
|     /* Putting ELF notes near beginning of file might help bootloaders. | ||||
|      * We discard .note sections other than .note.ELFBoot, | ||||
|      * because some versions of GCC generates useless ones. */ | ||||
|     .note : { *(.note.ELFBoot) } | ||||
|  | ||||
|     /* Normal sections */ | ||||
|     .text : { *(.text) *(.text.*) } | ||||
|     .rodata : { | ||||
| 	. = ALIGN(4); | ||||
| 	sound_drivers_start = .; | ||||
| 	*(.rodata.sound_drivers) | ||||
| 	sound_drivers_end = .; | ||||
| 	*(.rodata) | ||||
| 	*(.rodata.*) | ||||
|     } | ||||
|     .data : { *(.data) *(.data.*) } | ||||
|  | ||||
|     .bss : { | ||||
| 	*(.bss) | ||||
| 	*(.bss.*) | ||||
| 	*(COMMON) | ||||
|  | ||||
| 	/* Put heap and stack here, so they are included in PT_LOAD segment | ||||
| 	 * and the bootloader is aware of it. */ | ||||
|  | ||||
| 	. = ALIGN(16); | ||||
| 	_heap = .; | ||||
| 	. += HEAP_SIZE; | ||||
| 	. = ALIGN(16); | ||||
| 	_eheap = .; | ||||
|  | ||||
| 	_stack = .; | ||||
| 	. += STACK_SIZE; | ||||
| 	. = ALIGN(16); | ||||
| 	_estack = .; | ||||
|     } | ||||
|  | ||||
|     .initctx : { | ||||
| 	/* Initial contents of stack. This MUST BE just after the stack. */ | ||||
| 	*(.initctx) | ||||
|     } | ||||
|  | ||||
|     _end = .; | ||||
|  | ||||
|     /DISCARD/ : { *(.comment) *(.note) } | ||||
| } | ||||
							
								
								
									
										58
									
								
								arch/amd64/lib.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								arch/amd64/lib.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| /* lib.c | ||||
|  * tag: simple function library | ||||
|  * | ||||
|  * Copyright (C) 2003 Stefan Reinauer | ||||
|  * | ||||
|  * See the file "COPYING" for further information about | ||||
|  * the copyright and warranty status of this work. | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "asm/types.h" | ||||
| #include <stdarg.h> | ||||
| #include "libc/stdlib.h" | ||||
| #include "libc/vsprintf.h" | ||||
| #include "openbios/kernel.h" | ||||
|  | ||||
| /* Format a string and print it on the screen, just like the libc | ||||
|  * function printf.  | ||||
|  */ | ||||
| int printk( const char *fmt, ... ) | ||||
| { | ||||
| 	char *p, buf[512];	/* XXX: no buffer overflow protection... */ | ||||
| 	va_list args; | ||||
| 	int i; | ||||
|  | ||||
| 	va_start(args, fmt); | ||||
| 	i=vsprintf(buf,fmt,args); | ||||
| 	va_end(args); | ||||
|  | ||||
| 	for( p=buf; *p; p++ ) | ||||
| 		putchar(*p); | ||||
| 	return i; | ||||
| } | ||||
|  | ||||
| // dumb quick memory allocator until we get a decent thing here. | ||||
|  | ||||
| #define MEMSIZE 128*1024 | ||||
| static char memory[MEMSIZE]; | ||||
| static void *memptr=memory; | ||||
| static int memsize=MEMSIZE; | ||||
|  | ||||
| void *malloc(int size) | ||||
| { | ||||
| 	void *ret=(void *)0; | ||||
| 	if(memsize>=size) { | ||||
| 		memsize-=size; | ||||
| 		ret=memptr; | ||||
| 		memptr+=size; | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| void free(void *ptr) | ||||
| { | ||||
| 	/* Nothing yet */ | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										647
									
								
								arch/amd64/linux_load.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										647
									
								
								arch/amd64/linux_load.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,647 @@ | ||||
| /* | ||||
|  * Linux/i386 loader | ||||
|  * Supports bzImage, zImage and Image format. | ||||
|  * | ||||
|  * Based on work by Steve Gehlbach. | ||||
|  * Portions are taken from mkelfImage. | ||||
|  * | ||||
|  * 2003-09 by SONE Takeshi | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "sys_info.h" | ||||
| #include "context.h" | ||||
| #include "segment.h" | ||||
| #include "loadfs.h" | ||||
|  | ||||
| #define printf printk | ||||
| #define debug printk | ||||
| #define strtoull_with_suffix strtol | ||||
|  | ||||
| #define LINUX_PARAM_LOC 0x90000 | ||||
| #define COMMAND_LINE_LOC 0x91000 | ||||
| #define GDT_LOC 0x92000 | ||||
| #define STACK_LOC 0x93000 | ||||
|  | ||||
| #define E820MAX	32		/* number of entries in E820MAP */ | ||||
| struct e820entry { | ||||
| 	unsigned long long addr;	/* start of memory segment */ | ||||
| 	unsigned long long size;	/* size of memory segment */ | ||||
| 	unsigned long type;		/* type of memory segment */ | ||||
| #define E820_RAM	1 | ||||
| #define E820_RESERVED	2 | ||||
| #define E820_ACPI	3 /* usable as RAM once ACPI tables have been read */ | ||||
| #define E820_NVS	4 | ||||
| }; | ||||
|  | ||||
| /* The header of Linux/i386 kernel */ | ||||
| struct linux_header { | ||||
|     uint8_t  reserved1[0x1f1];		/* 0x000 */ | ||||
|     uint8_t  setup_sects;		/* 0x1f1 */ | ||||
|     uint16_t root_flags;		/* 0x1f2 */ | ||||
|     uint8_t  reserved2[6];		/* 0x1f4 */ | ||||
|     uint16_t vid_mode;			/* 0x1fa */ | ||||
|     uint16_t root_dev;			/* 0x1fc */ | ||||
|     uint16_t boot_sector_magic;		/* 0x1fe */ | ||||
|     /* 2.00+ */ | ||||
|     uint8_t  reserved3[2];		/* 0x200 */ | ||||
|     uint8_t  header_magic[4];		/* 0x202 */ | ||||
|     uint16_t protocol_version;		/* 0x206 */ | ||||
|     uint32_t realmode_swtch;		/* 0x208 */ | ||||
|     uint16_t start_sys;			/* 0x20c */ | ||||
|     uint16_t kver_addr;			/* 0x20e */ | ||||
|     uint8_t  type_of_loader;		/* 0x210 */ | ||||
|     uint8_t  loadflags;			/* 0x211 */ | ||||
|     uint16_t setup_move_size;		/* 0x212 */ | ||||
|     uint32_t code32_start;		/* 0x214 */ | ||||
|     uint32_t ramdisk_image;		/* 0x218 */ | ||||
|     uint32_t ramdisk_size;		/* 0x21c */ | ||||
|     uint8_t  reserved4[4];		/* 0x220 */ | ||||
|     /* 2.01+ */ | ||||
|     uint16_t heap_end_ptr;		/* 0x224 */ | ||||
|     uint8_t  reserved5[2];		/* 0x226 */ | ||||
|     /* 2.02+ */ | ||||
|     uint32_t cmd_line_ptr;		/* 0x228 */ | ||||
|     /* 2.03+ */ | ||||
|     uint32_t initrd_addr_max;		/* 0x22c */ | ||||
| } __attribute__ ((packed)); | ||||
|  | ||||
|  | ||||
| /* Paramters passed to 32-bit part of Linux | ||||
|  * This is another view of the structure above.. */ | ||||
| struct linux_params { | ||||
|     uint8_t  orig_x;			/* 0x00 */ | ||||
|     uint8_t  orig_y;			/* 0x01 */ | ||||
|     uint16_t ext_mem_k;			/* 0x02 -- EXT_MEM_K sits here */ | ||||
|     uint16_t orig_video_page;		/* 0x04 */ | ||||
|     uint8_t  orig_video_mode;		/* 0x06 */ | ||||
|     uint8_t  orig_video_cols;		/* 0x07 */ | ||||
|     uint16_t unused2;			/* 0x08 */ | ||||
|     uint16_t orig_video_ega_bx;		/* 0x0a */ | ||||
|     uint16_t unused3;			/* 0x0c */ | ||||
|     uint8_t  orig_video_lines;		/* 0x0e */ | ||||
|     uint8_t  orig_video_isVGA;		/* 0x0f */ | ||||
|     uint16_t orig_video_points;		/* 0x10 */ | ||||
|  | ||||
|     /* VESA graphic mode -- linear frame buffer */ | ||||
|     uint16_t lfb_width;			/* 0x12 */ | ||||
|     uint16_t lfb_height;		/* 0x14 */ | ||||
|     uint16_t lfb_depth;			/* 0x16 */ | ||||
|     uint32_t lfb_base;			/* 0x18 */ | ||||
|     uint32_t lfb_size;			/* 0x1c */ | ||||
|     uint16_t cl_magic;			/* 0x20 */ | ||||
| #define CL_MAGIC_VALUE 0xA33F | ||||
|     uint16_t cl_offset;			/* 0x22 */ | ||||
|     uint16_t lfb_linelength;		/* 0x24 */ | ||||
|     uint8_t  red_size;			/* 0x26 */ | ||||
|     uint8_t  red_pos;			/* 0x27 */ | ||||
|     uint8_t  green_size;		/* 0x28 */ | ||||
|     uint8_t  green_pos;			/* 0x29 */ | ||||
|     uint8_t  blue_size;			/* 0x2a */ | ||||
|     uint8_t  blue_pos;			/* 0x2b */ | ||||
|     uint8_t  rsvd_size;			/* 0x2c */ | ||||
|     uint8_t  rsvd_pos;			/* 0x2d */ | ||||
|     uint16_t vesapm_seg;		/* 0x2e */ | ||||
|     uint16_t vesapm_off;		/* 0x30 */ | ||||
|     uint16_t pages;			/* 0x32 */ | ||||
|     uint8_t  reserved4[12];		/* 0x34 -- 0x3f reserved for future expansion */ | ||||
|  | ||||
|     //struct apm_bios_info apm_bios_info;	/* 0x40 */ | ||||
|     uint8_t  apm_bios_info[0x40]; | ||||
|     //struct drive_info_struct drive_info;	/* 0x80 */ | ||||
|     uint8_t  drive_info[0x20]; | ||||
|     //struct sys_desc_table sys_desc_table;	/* 0xa0 */ | ||||
|     uint8_t  sys_desc_table[0x140]; | ||||
|     uint32_t alt_mem_k;			/* 0x1e0 */ | ||||
|     uint8_t  reserved5[4];		/* 0x1e4 */ | ||||
|     uint8_t  e820_map_nr;		/* 0x1e8 */ | ||||
|     uint8_t  reserved6[9];		/* 0x1e9 */ | ||||
|     uint16_t mount_root_rdonly;		/* 0x1f2 */ | ||||
|     uint8_t  reserved7[4];		/* 0x1f4 */ | ||||
|     uint16_t ramdisk_flags;		/* 0x1f8 */ | ||||
| #define RAMDISK_IMAGE_START_MASK  	0x07FF | ||||
| #define RAMDISK_PROMPT_FLAG		0x8000 | ||||
| #define RAMDISK_LOAD_FLAG		0x4000	 | ||||
|     uint8_t  reserved8[2];		/* 0x1fa */ | ||||
|     uint16_t orig_root_dev;		/* 0x1fc */ | ||||
|     uint8_t  reserved9[1];		/* 0x1fe */ | ||||
|     uint8_t  aux_device_info;		/* 0x1ff */ | ||||
|     uint8_t  reserved10[2];		/* 0x200 */ | ||||
|     uint8_t  param_block_signature[4];	/* 0x202 */ | ||||
|     uint16_t param_block_version;	/* 0x206 */ | ||||
|     uint8_t  reserved11[8];		/* 0x208 */ | ||||
|     uint8_t  loader_type;		/* 0x210 */ | ||||
| #define LOADER_TYPE_LOADLIN         1 | ||||
| #define LOADER_TYPE_BOOTSECT_LOADER 2 | ||||
| #define LOADER_TYPE_SYSLINUX        3 | ||||
| #define LOADER_TYPE_ETHERBOOT       4 | ||||
| #define LOADER_TYPE_KERNEL          5 | ||||
|     uint8_t  loader_flags;		/* 0x211 */ | ||||
|     uint8_t  reserved12[2];		/* 0x212 */ | ||||
|     uint32_t kernel_start;		/* 0x214 */ | ||||
|     uint32_t initrd_start;		/* 0x218 */ | ||||
|     uint32_t initrd_size;		/* 0x21c */ | ||||
|     uint8_t  reserved12_5[8];		/* 0x220 */ | ||||
|     uint32_t cmd_line_ptr;		/* 0x228 */ | ||||
|     uint8_t  reserved13[164];		/* 0x22c */ | ||||
|     struct e820entry e820_map[E820MAX];	/* 0x2d0 */ | ||||
|     uint8_t  reserved16[688];		/* 0x550 */ | ||||
| #define COMMAND_LINE_SIZE 256 | ||||
|     /* Command line is copied here by 32-bit i386/kernel/head.S. | ||||
|      * So I will follow the boot protocol, rather than putting it | ||||
|      * directly here. --ts1 */ | ||||
|     uint8_t  command_line[COMMAND_LINE_SIZE]; /* 0x800 */ | ||||
|     uint8_t  reserved17[1792];		/* 0x900 - 0x1000 */ | ||||
| }; | ||||
|  | ||||
| uint64_t forced_memsize; | ||||
|  | ||||
| /* Load the first part the file and check if it's Linux */ | ||||
| static uint32_t load_linux_header(struct linux_header *hdr) | ||||
| { | ||||
|     int load_high; | ||||
|     uint32_t kern_addr; | ||||
|  | ||||
|     if (lfile_read(hdr, sizeof *hdr) != sizeof *hdr) { | ||||
| 	debug("Can't read Linux header\n"); | ||||
| 	return 0; | ||||
|     } | ||||
|     if (hdr->boot_sector_magic != 0xaa55) { | ||||
| 	debug("Not a Linux kernel image\n"); | ||||
| 	return 0; | ||||
|     } | ||||
|  | ||||
|     /* Linux is found. Print some information */ | ||||
|     if (memcmp(hdr->header_magic, "HdrS", 4) != 0) { | ||||
| 	/* This may be floppy disk image or something. | ||||
| 	 * Perform a simple (incomplete) sanity check. */ | ||||
| 	if (hdr->setup_sects >= 16 | ||||
| 		|| file_size() - (hdr->setup_sects<<9) >= 512<<10) { | ||||
| 	    debug("This looks like a bootdisk image but not like Linux...\n"); | ||||
| 	    return 0; | ||||
| 	} | ||||
|  | ||||
| 	printf("Possible very old Linux"); | ||||
| 	/* This kernel does not even have a protocol version. | ||||
| 	 * Force the value. */ | ||||
| 	hdr->protocol_version = 0; /* pre-2.00 */ | ||||
|     } else | ||||
| 	printf("Found Linux"); | ||||
|     if (hdr->protocol_version >= 0x200 && hdr->kver_addr) { | ||||
| 	char kver[256]; | ||||
| 	file_seek(hdr->kver_addr + 0x200); | ||||
| 	if (lfile_read(kver, sizeof kver) != 0) { | ||||
| 	    kver[255] = 0; | ||||
| 	    printf(" version %s", kver); | ||||
| 	} | ||||
|     } | ||||
|     debug(" (protocol %#x)", hdr->protocol_version); | ||||
|     load_high = 0; | ||||
|     if (hdr->protocol_version >= 0x200) { | ||||
| 	debug(" (loadflags %#x)", hdr->loadflags); | ||||
| 	load_high = hdr->loadflags & 1; | ||||
|     } | ||||
|     if (load_high) { | ||||
| 	printf(" bzImage"); | ||||
| 	kern_addr = 0x100000; | ||||
|     } else { | ||||
| 	printf(" zImage or Image"); | ||||
| 	kern_addr = 0x1000; | ||||
|     } | ||||
|     printf(".\n"); | ||||
|  | ||||
|     return kern_addr; | ||||
| } | ||||
|  | ||||
| /* Set up parameters for 32-bit kernel */ | ||||
| static void | ||||
| init_linux_params(struct linux_params *params, struct linux_header *hdr) | ||||
| { | ||||
|     debug("Setting up paramters at %#lx\n", virt_to_phys(params)); | ||||
|     memset(params, 0, sizeof *params); | ||||
|  | ||||
|     /* Copy some useful values from header */ | ||||
|     params->mount_root_rdonly = hdr->root_flags; | ||||
|     params->orig_root_dev = hdr->root_dev; | ||||
|  | ||||
|     /* Video parameters. | ||||
|      * This assumes we have VGA in standard 80x25 text mode, | ||||
|      * just like our vga.c does. | ||||
|      * Cursor position is filled later to allow some more printf's. */ | ||||
|     params->orig_video_mode = 3; | ||||
|     params->orig_video_cols = 80; | ||||
|     params->orig_video_lines = 25; | ||||
|     params->orig_video_isVGA = 1; | ||||
|     params->orig_video_points = 16; | ||||
|  | ||||
|     params->loader_type = 0xff; /* Unregistered Linux loader */ | ||||
| } | ||||
|  | ||||
| /* Memory map */ | ||||
| static void | ||||
| set_memory_size(struct linux_params *params, struct sys_info *info) | ||||
| { | ||||
|     int i; | ||||
|     uint64_t end; | ||||
|     uint32_t ramtop = 0; | ||||
|     struct e820entry *linux_map; | ||||
|     struct memrange *filo_map; | ||||
|  | ||||
|     linux_map = params->e820_map; | ||||
|     filo_map = info->memrange; | ||||
|     for (i = 0; i < info->n_memranges; i++, linux_map++, filo_map++) { | ||||
| 	if (i < E820MAX) { | ||||
| 	    /* Convert to BIOS e820 style */ | ||||
| 	    linux_map->addr = filo_map->base; | ||||
| 	    linux_map->size = filo_map->size; | ||||
| 	    linux_map->type = E820_RAM; | ||||
| 	    debug("%016Lx - %016Lx\n", linux_map->addr, | ||||
| 		    linux_map->addr + linux_map->size); | ||||
| 	    params->e820_map_nr = i+1; | ||||
| 	} | ||||
|  | ||||
| 	/* Find out top of RAM. XXX This ignores hole above 1MB */ | ||||
| 	end = filo_map->base + filo_map->size; | ||||
| 	if (end < (1ULL << 32)) { /* don't count memory above 4GB */ | ||||
| 	    if (end > ramtop) | ||||
| 		ramtop = (uint32_t) end; | ||||
| 	} | ||||
|     } | ||||
|     debug("ramtop=%#x\n", ramtop); | ||||
|     /* Size of memory above 1MB in KB */ | ||||
|     params->alt_mem_k = (ramtop - (1<<20)) >> 10; | ||||
|     /* old style, 64MB max */ | ||||
|     if (ramtop >= (64<<20)) | ||||
| 	params->ext_mem_k = (63<<10); | ||||
|     else | ||||
| 	params->ext_mem_k = params->alt_mem_k; | ||||
|     debug("ext_mem_k=%d, alt_mem_k=%d\n", params->ext_mem_k, params->alt_mem_k); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Parse command line | ||||
|  * Some parameters, like initrd=<file>, are not passed to kernel, | ||||
|  * we are responsible to process them. | ||||
|  * Parameters for kernel are copied to kern_cmdline. Returns name of initrd. | ||||
|  */ | ||||
| static char *parse_command_line(const char *orig_cmdline, char *kern_cmdline) | ||||
| { | ||||
|     const char *start, *sep, *end, *val; | ||||
|     char name[64]; | ||||
|     int len; | ||||
|     int k_len; | ||||
|     int to_kern; | ||||
|     char *initrd = 0; | ||||
|     int toolong = 0; | ||||
|  | ||||
|     forced_memsize = 0; | ||||
|  | ||||
|     if (!orig_cmdline) { | ||||
| 	*kern_cmdline = 0; | ||||
| 	return 0; | ||||
|     } | ||||
|  | ||||
|     k_len = 0; | ||||
|     debug("original command line: \"%s\"\n", orig_cmdline); | ||||
|     debug("kernel command line at %#lx\n", virt_to_phys(kern_cmdline)); | ||||
|  | ||||
|     start = orig_cmdline; | ||||
|     while (*start == ' ') | ||||
| 	start++; | ||||
|     while (*start) { | ||||
| 	end = strchr(start, ' '); | ||||
| 	if (!end) | ||||
| 	    end = start + strlen(start); | ||||
| 	sep = strchr(start, '='); | ||||
| 	if (!sep || sep > end) | ||||
| 	    sep = end; | ||||
| 	len = sep - start; | ||||
| 	if (len >= sizeof(name)) | ||||
| 	    len = sizeof(name) - 1; | ||||
| 	memcpy(name, start, len); | ||||
| 	name[len] = 0; | ||||
|  | ||||
| 	if (*sep == '=') { | ||||
| 	    val = sep + 1; | ||||
| 	    len = end - val; | ||||
| 	} else { | ||||
| 	    val = 0; | ||||
| 	    len = 0; | ||||
| 	} | ||||
|  | ||||
| 	/* Only initrd= and mem= are handled here. vga= is not, | ||||
| 	 * which I believe is a paramter to the realmode part of Linux, | ||||
| 	 * which we don't execute. */ | ||||
| 	if (strcmp(name, "initrd") == 0) { | ||||
| 	    if (!val) | ||||
| 		printf("Missing filename to initrd parameter\n"); | ||||
| 	    else { | ||||
| 		initrd = malloc(len + 1); | ||||
| 		memcpy(initrd, val, len); | ||||
| 		initrd[len] = 0; | ||||
| 		debug("initrd=%s\n", initrd); | ||||
| 	    } | ||||
| 	    /* Don't pass this to kernel */ | ||||
| 	    to_kern = 0; | ||||
| 	} else if (strcmp(name, "mem") == 0) { | ||||
| 	    if (!val) | ||||
| 		printf("Missing value for mem parameter\n"); | ||||
| 	    else { | ||||
| 		forced_memsize = strtoull_with_suffix(val, (char**)&val, 0); | ||||
| 		if (forced_memsize == 0) | ||||
| 		    printf("Invalid mem option, ignored\n"); | ||||
| 		if (val != end) { | ||||
| 		    printf("Garbage after mem=<size>, ignored\n"); | ||||
| 		    forced_memsize = 0; | ||||
| 		} | ||||
| 		debug("mem=%Lu\n", forced_memsize); | ||||
| 	    } | ||||
| 	    /* mem= is for both loader and kernel */ | ||||
| 	    to_kern = 1; | ||||
| 	} else | ||||
| 	    to_kern = 1; | ||||
|  | ||||
| 	if (to_kern) { | ||||
| 	    /* Copy to kernel command line buffer */ | ||||
| 	    if (k_len != 0) | ||||
| 		kern_cmdline[k_len++] = ' '; /* put separator */ | ||||
| 	    len = end - start; | ||||
| 	    if (k_len + len >= COMMAND_LINE_SIZE) { | ||||
| 		len = COMMAND_LINE_SIZE - k_len - 1; | ||||
| 		if (!toolong) { | ||||
| 		    printf("Kernel command line is too long; truncated to " | ||||
| 			    "%d bytes\n", COMMAND_LINE_SIZE-1); | ||||
| 		    toolong = 1; | ||||
| 		} | ||||
| 	    } | ||||
| 	    memcpy(kern_cmdline + k_len, start, len); | ||||
| 	    k_len += len; | ||||
| 	} | ||||
|  | ||||
| 	start = end; | ||||
| 	while (*start == ' ') | ||||
| 	    start++; | ||||
|     } | ||||
|     kern_cmdline[k_len] = 0; | ||||
|     debug("kernel command line (%d bytes): \"%s\"\n", k_len, kern_cmdline); | ||||
|  | ||||
|     return initrd; | ||||
| } | ||||
|  | ||||
| /* Set command line location */ | ||||
| static void set_command_line_loc(struct linux_params *params, | ||||
| 	struct linux_header *hdr) | ||||
| { | ||||
|     if (hdr->protocol_version >= 0x202) { | ||||
| 	/* new style */ | ||||
| 	params->cmd_line_ptr = COMMAND_LINE_LOC; | ||||
|     } else { | ||||
| 	/* old style */ | ||||
| 	params->cl_magic = CL_MAGIC_VALUE; | ||||
| 	params->cl_offset = COMMAND_LINE_LOC - LINUX_PARAM_LOC; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* Load 32-bit part of kernel */ | ||||
| static int load_linux_kernel(struct linux_header *hdr, uint32_t kern_addr) | ||||
| { | ||||
|     uint32_t kern_offset, kern_size; | ||||
|  | ||||
|     if (hdr->setup_sects == 0) | ||||
| 	hdr->setup_sects = 4; | ||||
|     kern_offset = (hdr->setup_sects + 1) * 512; | ||||
|     file_seek(kern_offset); | ||||
|     kern_size = file_size() - kern_offset; | ||||
|     debug("offset=%#x addr=%#x size=%#x\n", kern_offset, kern_addr, kern_size); | ||||
|  | ||||
| #if 0 | ||||
|     if (using_devsize) { | ||||
| 	printf("Attempt to load up to end of device as kernel; " | ||||
| 		"specify the image size\n"); | ||||
| 	return 0; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     printf("Loading kernel... "); | ||||
|     if (lfile_read(phys_to_virt(kern_addr), kern_size) != kern_size) { | ||||
| 	printf("Can't read kernel\n"); | ||||
| 	return 0; | ||||
|     } | ||||
|     printf("ok\n"); | ||||
|  | ||||
|     return kern_size; | ||||
| } | ||||
|  | ||||
| static int load_initrd(struct linux_header *hdr, struct sys_info *info, | ||||
| 	uint32_t kern_end, struct linux_params *params, const char *initrd_file) | ||||
| { | ||||
|     uint32_t max; | ||||
|     uint32_t start, end, size; | ||||
|     uint64_t forced; | ||||
|     extern char _start[], _end[]; | ||||
|  | ||||
|     if (!file_open(initrd_file)) { | ||||
| 	printf("Can't open initrd: %s\n", initrd_file); | ||||
| 	return -1; | ||||
|     } | ||||
|  | ||||
| #if 0 | ||||
|     if (using_devsize) { | ||||
| 	printf("Attempt to load up to end of device as initrd; " | ||||
| 		"specify the image size\n"); | ||||
| 	return -1; | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     size = file_size(); | ||||
|  | ||||
|  | ||||
|     /* Find out the kernel's restriction on how high the initrd can be | ||||
|      * placed */ | ||||
|     if (hdr->protocol_version >= 0x203) | ||||
| 	max = hdr->initrd_addr_max; | ||||
|     else | ||||
| 	max = 0x38000000; /* Hardcoded value for older kernels */ | ||||
|      | ||||
|     /* FILO itself is at the top of RAM. (relocated) | ||||
|      * So, try putting initrd just below us. */ | ||||
|     end = virt_to_phys(_start); | ||||
|     if (end > max) | ||||
| 	end = max; | ||||
|  | ||||
|     /* If "mem=" option is given, we have to put the initrd within | ||||
|      * the specified range. */ | ||||
|     if (forced_memsize) { | ||||
| 	forced = forced_memsize; | ||||
| 	if (forced > max) | ||||
| 	    forced = max; | ||||
| 	/* If the "mem=" is lower, it's easy */ | ||||
| 	if (forced <= end) | ||||
| 	    end = forced; | ||||
| 	else { | ||||
| 	    /* Otherwise, see if we can put it above us */ | ||||
| 	    if (virt_to_phys(_end) + size <= forced) | ||||
| 		end = forced; /* Ok */ | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|     start = end - size; | ||||
|     start &= ~0xfff; /* page align */ | ||||
|     end = start + size; | ||||
|  | ||||
|     debug("start=%#x end=%#x\n", start, end); | ||||
|  | ||||
|     if (start < kern_end) { | ||||
| 	printf("Initrd is too big to fit in memory\n"); | ||||
| 	return -1; | ||||
|     } | ||||
|  | ||||
|     printf("Loading initrd... "); | ||||
|     if (lfile_read(phys_to_virt(start), size) != size) { | ||||
| 	printf("Can't read initrd\n"); | ||||
| 	return -1; | ||||
|     } | ||||
|     printf("ok\n"); | ||||
|  | ||||
|     params->initrd_start = start; | ||||
|     params->initrd_size = size; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static void hardware_setup(void) | ||||
| { | ||||
|     /* Disable nmi */ | ||||
|     outb(0x80, 0x70); | ||||
|  | ||||
|     /* Make sure any coprocessor is properly reset.. */ | ||||
|     outb(0, 0xf0); | ||||
|     outb(0, 0xf1); | ||||
|  | ||||
|     /* we're getting screwed again and again by this problem of the 8259.  | ||||
|      * so we're going to leave this lying around for inclusion into  | ||||
|      * crt0.S on an as-needed basis.  | ||||
|      * | ||||
|      * well, that went ok, I hope. Now we have to reprogram the interrupts :-( | ||||
|      * we put them right after the intel-reserved hardware interrupts, at | ||||
|      * int 0x20-0x2F. There they won't mess up anything. Sadly IBM really | ||||
|      * messed this up with the original PC, and they haven't been able to | ||||
|      * rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f, | ||||
|      * which is used for the internal hardware interrupts as well. We just | ||||
|      * have to reprogram the 8259's, and it isn't fun. | ||||
|      */ | ||||
|  | ||||
|     outb(0x11, 0x20);		/* initialization sequence to 8259A-1 */ | ||||
|     outb(0x11, 0xA0);		/* and to 8259A-2 */ | ||||
|  | ||||
|     outb(0x20, 0x21);		/* start of hardware int's (0x20) */ | ||||
|     outb(0x28, 0xA1);		/* start of hardware int's 2 (0x28) */ | ||||
|  | ||||
|     outb(0x04, 0x21);		/* 8259-1 is master */ | ||||
|     outb(0x02, 0xA1);		/* 8259-2 is slave */ | ||||
|  | ||||
|     outb(0x01, 0x21);		/* 8086 mode for both */ | ||||
|     outb(0x01, 0xA1); | ||||
|  | ||||
|     outb(0xFF, 0xA1);		/* mask off all interrupts for now */ | ||||
|     outb(0xFB, 0x21);		/* mask all irq's but irq2 which is cascaded */ | ||||
| } | ||||
|  | ||||
| /* Start Linux */ | ||||
| static int start_linux(uint32_t kern_addr, struct linux_params *params) | ||||
| { | ||||
|     struct segment_desc *linux_gdt; | ||||
|     struct context *ctx; | ||||
|     //extern int cursor_x, cursor_y; | ||||
|  | ||||
|     ctx = init_context(phys_to_virt(STACK_LOC), 4096, 0); | ||||
|  | ||||
|     /* Linux expects GDT being in low memory */ | ||||
|     linux_gdt = phys_to_virt(GDT_LOC); | ||||
|     memset(linux_gdt, 0, 13*sizeof(struct segment_desc)); | ||||
|     /* Normal kernel code/data segments */ | ||||
|     linux_gdt[2] = gdt[FLAT_CODE]; | ||||
|     linux_gdt[3] = gdt[FLAT_DATA]; | ||||
|     /* 2.6 kernel uses 12 and 13, but head.S uses backward-compatible | ||||
|      * segments (2 and 3), so it SHOULD not be a problem.  | ||||
|      * However, some distro kernels (eg. RH9) with backported threading  | ||||
|      * patch use 12 and 13 also when booting... */ | ||||
|     linux_gdt[12] = gdt[FLAT_CODE]; | ||||
|     linux_gdt[13] = gdt[FLAT_DATA]; | ||||
|     ctx->gdt_base = GDT_LOC; | ||||
|     ctx->gdt_limit = 14*8-1; | ||||
|     ctx->cs = 0x10; | ||||
|     ctx->ds = 0x18; | ||||
|     ctx->es = 0x18; | ||||
|     ctx->fs = 0x18; | ||||
|     ctx->gs = 0x18; | ||||
|     ctx->ss = 0x18; | ||||
|  | ||||
|     /* Parameter location */ | ||||
|     ctx->esi = virt_to_phys(params); | ||||
|  | ||||
|     /* Entry point */ | ||||
|     ctx->eip = kern_addr; | ||||
|  | ||||
|     debug("eip=%#x\n", kern_addr); | ||||
|     printf("Jumping to entry point...\n"); | ||||
|  | ||||
| #ifdef VGA_CONSOLE | ||||
|     /* Update VGA cursor position. | ||||
|      * This must be here because the printf changes the value! */ | ||||
|     params->orig_x = cursor_x; | ||||
|     params->orig_y = cursor_y; | ||||
| #endif | ||||
|      | ||||
|     /* Go... */ | ||||
|     ctx = switch_to(ctx); | ||||
|  | ||||
|     /* It's impossible but... */ | ||||
|     printf("Returned with eax=%#x\n", ctx->eax); | ||||
|  | ||||
|     return ctx->eax; | ||||
| } | ||||
|  | ||||
| int linux_load(struct sys_info *info, const char *file, const char *cmdline) | ||||
| { | ||||
|     struct linux_header hdr; | ||||
|     struct linux_params *params; | ||||
|     uint32_t kern_addr, kern_size; | ||||
|     char *initrd_file = 0; | ||||
|  | ||||
|     if (!file_open(file)) | ||||
| 	return -1; | ||||
|  | ||||
|     kern_addr = load_linux_header(&hdr); | ||||
|     if (kern_addr == 0) | ||||
| 	return LOADER_NOT_SUPPORT; | ||||
|  | ||||
|     params = phys_to_virt(LINUX_PARAM_LOC); | ||||
|     init_linux_params(params, &hdr); | ||||
|     set_memory_size(params, info); | ||||
|     initrd_file = parse_command_line(cmdline, phys_to_virt(COMMAND_LINE_LOC)); | ||||
|     set_command_line_loc(params, &hdr); | ||||
|  | ||||
|     kern_size = load_linux_kernel(&hdr, kern_addr); | ||||
|     if (kern_size == 0) { | ||||
| 	if (initrd_file) | ||||
| 	    free(initrd_file); | ||||
| 	return -1; | ||||
|     } | ||||
|  | ||||
|     if (initrd_file) { | ||||
| 	if (load_initrd(&hdr, info, kern_addr+kern_size, params, initrd_file) | ||||
| 		!= 0) { | ||||
| 	    free(initrd_file); | ||||
| 	    return -1; | ||||
| 	} | ||||
| 	free(initrd_file); | ||||
|     } | ||||
|  | ||||
|     hardware_setup(); | ||||
|  | ||||
|     start_linux(kern_addr, params); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										46
									
								
								arch/amd64/loadfs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								arch/amd64/loadfs.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "libc/diskio.h" | ||||
| #include "loadfs.h" | ||||
|  | ||||
| static int load_fd=-1; | ||||
|  | ||||
| int file_open(const char *filename) | ||||
| { | ||||
| 	load_fd=open_io(filename); | ||||
| 	/* if(load_fd!=-1)  */ seek_io(load_fd, 0); | ||||
| 	return load_fd>-1; | ||||
| } | ||||
|  | ||||
| int lfile_read(void *buf, unsigned long len) | ||||
| { | ||||
| 	int ret; | ||||
| 	ret=read_io(load_fd, buf, len); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| int file_seek(unsigned long offset) | ||||
| { | ||||
| 	return seek_io(load_fd, offset); | ||||
| } | ||||
|  | ||||
| unsigned long file_size(void) | ||||
| { | ||||
| 	llong fpos, fsize; | ||||
| 	 | ||||
| 	/* save current position */ | ||||
| 	fpos=tell(load_fd); | ||||
|  | ||||
| 	/* go to end of file and get position */ | ||||
| 	seek_io(load_fd, -1); | ||||
| 	fsize=tell(load_fd); | ||||
| 	 | ||||
| 	/* go back to old position */ | ||||
| 	seek_io(load_fd, 0); | ||||
| 	seek_io(load_fd, fpos); | ||||
| 	 | ||||
| 	return fsize; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										7
									
								
								arch/amd64/loadfs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								arch/amd64/loadfs.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| int file_open(const char *filename); | ||||
| int lfile_read(void *buf, unsigned long len); | ||||
| int file_seek(unsigned long offset); | ||||
| unsigned long file_size(void); | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										125
									
								
								arch/amd64/multiboot.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								arch/amd64/multiboot.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,125 @@ | ||||
| /* Support for Multiboot */ | ||||
|  | ||||
| #include "openbios/config.h"  | ||||
| #include "asm/io.h" | ||||
| #include "sys_info.h" | ||||
| #include "multiboot.h" | ||||
|  | ||||
| #define printf printk | ||||
| #ifdef CONFIG_DEBUG_BOOT | ||||
| #define debug printk | ||||
| #else | ||||
| #define debug(x...)  | ||||
| #endif | ||||
|  | ||||
| struct mbheader { | ||||
|     unsigned int magic, flags, checksum; | ||||
| }; | ||||
| const struct mbheader multiboot_header | ||||
| 	__attribute__((section (".hdr"))) = | ||||
| { | ||||
|     MULTIBOOT_HEADER_MAGIC, | ||||
|     MULTIBOOT_HEADER_FLAGS, | ||||
|     -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) | ||||
| }; | ||||
|  | ||||
| /* Multiboot information structure, provided by loader to us */ | ||||
|  | ||||
| struct multiboot_mmap { | ||||
| 	unsigned entry_size; | ||||
| 	unsigned base_lo, base_hi; | ||||
| 	unsigned size_lo, size_hi; | ||||
| 	unsigned type; | ||||
| }; | ||||
|  | ||||
| #define MULTIBOOT_MEM_VALID       0x01 | ||||
| #define MULTIBOOT_BOOT_DEV_VALID  0x02 | ||||
| #define MULTIBOOT_CMDLINE_VALID   0x04 | ||||
| #define MULTIBOOT_MODS_VALID      0x08 | ||||
| #define MULTIBOOT_AOUT_SYMS_VALID 0x10 | ||||
| #define MULTIBOOT_ELF_SYMS_VALID  0x20 | ||||
| #define MULTIBOOT_MMAP_VALID      0x40 | ||||
|  | ||||
| void collect_multiboot_info(struct sys_info *info); | ||||
| void collect_multiboot_info(struct sys_info *info) | ||||
| { | ||||
|     struct multiboot_info *mbinfo; | ||||
|     struct multiboot_mmap *mbmem; | ||||
|     unsigned mbcount, mbaddr; | ||||
|     int i; | ||||
|     struct memrange *mmap; | ||||
|     int mmap_count; | ||||
|     module_t *mod; | ||||
|  | ||||
|     if (info->boot_type != 0x2BADB002) | ||||
| 	return; | ||||
|  | ||||
|     debug("Using Multiboot information at %#lx\n", info->boot_data); | ||||
|  | ||||
|     mbinfo = phys_to_virt(info->boot_data); | ||||
|  | ||||
|     if (mbinfo->mods_count != 1) { | ||||
| 	    printf("Multiboot: no dictionary\n"); | ||||
| 	    return; | ||||
|     } | ||||
|     | ||||
|     mod = (module_t *) mbinfo->mods_addr; | ||||
|     info->dict_start=(unsigned long *)mod->mod_start; | ||||
|     info->dict_end=(unsigned long *)mod->mod_end; | ||||
|     | ||||
|     if (mbinfo->flags & MULTIBOOT_MMAP_VALID) { | ||||
| 	/* convert mmap records */ | ||||
| 	mbmem = phys_to_virt(mbinfo->mmap_addr); | ||||
| 	mbcount = mbinfo->mmap_length / (mbmem->entry_size + 4); | ||||
| 	mmap = malloc(mbcount * sizeof(struct memrange)); | ||||
| 	mmap_count = 0; | ||||
| 	mbaddr = mbinfo->mmap_addr; | ||||
| 	for (i = 0; i < mbcount; i++) { | ||||
| 	    mbmem = phys_to_virt(mbaddr); | ||||
| 	    debug("%08x%08x %08x%08x (%d)\n", | ||||
| 		    mbmem->base_hi, | ||||
| 		    mbmem->base_lo, | ||||
| 		    mbmem->size_hi, | ||||
| 		    mbmem->size_lo, | ||||
| 		    mbmem->type); | ||||
| 	    if (mbmem->type == 1) { /* Only normal RAM */ | ||||
| 		mmap[mmap_count].base = mbmem->base_lo | ||||
| 		    + (((unsigned long long) mbmem->base_hi) << 32); | ||||
| 		mmap[mmap_count].size = mbmem->size_lo | ||||
| 		    + (((unsigned long long) mbmem->size_hi) << 32); | ||||
| 		mmap_count++; | ||||
| 	    } | ||||
| 	    mbaddr += mbmem->entry_size + 4; | ||||
| 	    if (mbaddr >= mbinfo->mmap_addr + mbinfo->mmap_length) | ||||
| 		break; | ||||
| 	} | ||||
| 	/* simple sanity check - there should be at least 2 RAM segments | ||||
| 	 * (base 640k and extended) */ | ||||
| 	if (mmap_count >= 2) | ||||
| 	    goto got_it; | ||||
|  | ||||
| 	printf("Multiboot mmap is broken\n"); | ||||
| 	free(mmap); | ||||
| 	/* fall back to mem_lower/mem_upper */ | ||||
|     } | ||||
|  | ||||
|     if (mbinfo->flags & MULTIBOOT_MEM_VALID) { | ||||
| 	/* use mem_lower and mem_upper */ | ||||
| 	mmap_count = 2; | ||||
| 	mmap = malloc(2 * sizeof(*mmap)); | ||||
| 	mmap[0].base = 0; | ||||
| 	mmap[0].size = mbinfo->mem_lower << 10; | ||||
| 	mmap[1].base = 1 << 20; /* 1MB */ | ||||
| 	mmap[1].size = mbinfo->mem_upper << 10; | ||||
| 	goto got_it; | ||||
|     } | ||||
|  | ||||
|     printf("Can't get memory information from Multiboot\n"); | ||||
|     return; | ||||
|  | ||||
| got_it: | ||||
|     info->memrange = mmap; | ||||
|     info->n_memranges = mmap_count; | ||||
|  | ||||
|     return; | ||||
| } | ||||
							
								
								
									
										96
									
								
								arch/amd64/multiboot.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								arch/amd64/multiboot.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | ||||
| /* multiboot.h  | ||||
|  * tag: header for multiboot  | ||||
|  * | ||||
|  * Copyright (C) 2003-2004 Stefan Reinauer | ||||
|  * | ||||
|  * See the file "COPYING" for further information about | ||||
|  * the copyright and warranty status of this work. | ||||
|  */ | ||||
|  | ||||
| /* magic number for multiboot header */ | ||||
| #define MULTIBOOT_HEADER_MAGIC		0x1BADB002 | ||||
|  | ||||
| /* flags for multiboot header */ | ||||
| #define MULTIBOOT_HEADER_FLAGS		0x00010003 | ||||
|  | ||||
| /* magic number passed by multiboot-compliant boot loader.  */ | ||||
| #define MULTIBOOT_BOOTLOADER_MAGIC	0x2BADB002 | ||||
|  | ||||
| /* The size of our stack (8KB).  */ | ||||
| #define STACK_SIZE			0x2000 | ||||
|  | ||||
| /* C symbol format. HAVE_ASM_USCORE is defined by configure.  */ | ||||
| #ifdef HAVE_ASM_USCORE | ||||
| # define EXT_C(sym)			_ ## sym | ||||
| #else | ||||
| # define EXT_C(sym)			sym | ||||
| #endif | ||||
|  | ||||
| #ifndef ASM | ||||
| /* We don't want these declarations in boot.S  */ | ||||
|  | ||||
| /* multiboot header */ | ||||
| typedef struct multiboot_header { | ||||
| 	unsigned long magic; | ||||
| 	unsigned long flags; | ||||
| 	unsigned long checksum; | ||||
| 	unsigned long header_addr; | ||||
| 	unsigned long load_addr; | ||||
| 	unsigned long load_end_addr; | ||||
| 	unsigned long bss_end_addr; | ||||
| 	unsigned long entry_addr; | ||||
| } multiboot_header_t; | ||||
|  | ||||
| /* symbol table for a.out */ | ||||
| typedef struct aout_symbol_table { | ||||
| 	unsigned long tabsize; | ||||
| 	unsigned long strsize; | ||||
| 	unsigned long addr; | ||||
| 	unsigned long reserved; | ||||
| } aout_symbol_table_t; | ||||
|  | ||||
| /* section header table for ELF */ | ||||
| typedef struct elf_section_header_table { | ||||
| 	unsigned long num; | ||||
| 	unsigned long size; | ||||
| 	unsigned long addr; | ||||
| 	unsigned long shndx; | ||||
| } elf_section_header_table_t; | ||||
|  | ||||
| /* multiboot information */ | ||||
| typedef struct multiboot_info { | ||||
| 	unsigned long flags; | ||||
| 	unsigned long mem_lower; | ||||
| 	unsigned long mem_upper; | ||||
| 	unsigned long boot_device; | ||||
| 	unsigned long cmdline; | ||||
| 	unsigned long mods_count; | ||||
| 	unsigned long mods_addr; | ||||
| 	union { | ||||
| 		aout_symbol_table_t aout_sym; | ||||
| 		elf_section_header_table_t elf_sec; | ||||
| 	} u; | ||||
| 	unsigned long mmap_length; | ||||
| 	unsigned long mmap_addr; | ||||
| } multiboot_info_t; | ||||
|  | ||||
| /* module structure */ | ||||
| typedef struct module { | ||||
| 	unsigned long mod_start; | ||||
| 	unsigned long mod_end; | ||||
| 	unsigned long string; | ||||
| 	unsigned long reserved; | ||||
| } module_t; | ||||
|  | ||||
| /* memory map. Be careful that the offset 0 is base_addr_low | ||||
|    but no size.  */ | ||||
| typedef struct memory_map { | ||||
| 	unsigned long size; | ||||
| 	unsigned long base_addr_low; | ||||
| 	unsigned long base_addr_high; | ||||
| 	unsigned long length_low; | ||||
| 	unsigned long length_high; | ||||
| 	unsigned long type; | ||||
| } memory_map_t; | ||||
|  | ||||
| #endif				/* ! ASM */ | ||||
							
								
								
									
										109
									
								
								arch/amd64/openbios.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								arch/amd64/openbios.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | ||||
| /* tag: openbios forth environment, executable code | ||||
|  * | ||||
|  * Copyright (C) 2003 Patrick Mauritz, Stefan Reinauer | ||||
|  * | ||||
|  * See the file "COPYING" for further information about | ||||
|  * the copyright and warranty status of this work. | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "asm/types.h" | ||||
| #include "dict.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "openbios/stack.h" | ||||
| #include "sys_info.h" | ||||
| #include "openbios.h" | ||||
| #include "relocate.h" | ||||
|  | ||||
| void boot(void); | ||||
| void ob_ide_init(void); | ||||
|  | ||||
| static char intdict[256 * 1024]; | ||||
|  | ||||
| static void init_memory(void) | ||||
| { | ||||
| 	/* push start and end of available memory to the stack | ||||
| 	 * so that the forth word QUIT can initialize memory  | ||||
| 	 * management. For now we use hardcoded memory between | ||||
| 	 * 0x10000 and 0x9ffff (576k). If we need more memory | ||||
| 	 * than that we have serious bloat. | ||||
| 	 */ | ||||
|  | ||||
| 	PUSH(0x10000); | ||||
| 	PUSH(0x9FFFF); | ||||
| } | ||||
|  | ||||
| void exception(cell no) | ||||
| { | ||||
| 	/* The exception mechanism is used during bootstrap to catch | ||||
| 	 * build errors. In a running system this is a noop since we | ||||
| 	 * can't break out to the unix host os anyways. | ||||
| 	 */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| arch_init( void ) | ||||
| { | ||||
| 	void setup_timers(void); | ||||
|  | ||||
| 	modules_init(); | ||||
| #ifdef CONFIG_DRIVER_IDE | ||||
| 	setup_timers(); | ||||
| 	ob_ide_init(); | ||||
| #endif | ||||
| 	device_end(); | ||||
| 	bind_func("platform-boot", boot ); | ||||
| } | ||||
|  | ||||
| int openbios(void) | ||||
| { | ||||
| 	extern struct sys_info sys_info; | ||||
| #ifdef CONFIG_DEBUG_CONSOLE | ||||
| #ifdef CONFIG_DEBUG_CONSOLE_SERIAL | ||||
| 	uart_init(CONFIG_SERIAL_PORT, CONFIG_SERIAL_SPEED); | ||||
| #endif | ||||
| 	/* Clear the screen.  */ | ||||
| 	cls(); | ||||
| #endif | ||||
|  | ||||
|         collect_sys_info(&sys_info); | ||||
| 	 | ||||
| 	dict=intdict; | ||||
| 	load_dictionary((char *)sys_info.dict_start, | ||||
| 			sys_info.dict_end-sys_info.dict_start); | ||||
| 	 | ||||
| 	relocate(&sys_info); | ||||
|  | ||||
| #ifdef CONFIG_DEBUG_CONSOLE | ||||
| 	video_init(); | ||||
| #endif | ||||
| #ifdef CONFIG_DEBUG_BOOT | ||||
| 	printk("forth started.\n"); | ||||
| 	printk("initializing memory..."); | ||||
| #endif | ||||
|  | ||||
| 	init_memory(); | ||||
|  | ||||
| #ifdef CONFIG_DEBUG_BOOT | ||||
| 	printk("done\n"); | ||||
| #endif | ||||
|  | ||||
| 	PUSH_xt( bind_noname_func(arch_init) ); | ||||
| 	fword("PREPOST-initializer"); | ||||
| 	 | ||||
| 	PC = (ucell)findword("initialize-of"); | ||||
|  | ||||
| 	if (!PC) { | ||||
| 		printk("panic: no dictionary entry point.\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| #ifdef CONFIG_DEBUG_DICTIONARY | ||||
| 	printk("done (%d bytes).\n", dicthead); | ||||
| 	printk("Jumping to dictionary...\n"); | ||||
| #endif | ||||
|  | ||||
| 	enterforth((xt_t)PC); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										29
									
								
								arch/amd64/openbios.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								arch/amd64/openbios.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/01/15 16:14:05 samuel> | ||||
|  *   Time-stamp: <2004/01/15 16:14:05 samuel> | ||||
|  *    | ||||
|  *	<openbios.h> | ||||
|  *	 | ||||
|  *	 | ||||
|  *    | ||||
|  *   Copyright (C) 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #ifndef _H_OPENBIOS | ||||
| #define _H_OPENBIOS | ||||
|  | ||||
| int openbios(void); | ||||
|  | ||||
| /* console.c */ | ||||
| extern void	cls(void); | ||||
| #ifdef CONFIG_DEBUG_CONSOLE | ||||
| extern int	uart_init(int port, unsigned long speed); | ||||
| extern void     video_init(void); | ||||
| #endif | ||||
|  | ||||
| #endif   /* _H_OPENBIOS */ | ||||
							
								
								
									
										22
									
								
								arch/amd64/plainboot.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								arch/amd64/plainboot.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| /* tag: openbios fixed address forth starter | ||||
|  * | ||||
|  * Copyright (C) 2003 Stefan Reinauer | ||||
|  * | ||||
|  * See the file "COPYING" for further information about | ||||
|  * the copyright and warranty status of this work. | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "sys_info.h" | ||||
| #include "multiboot.h" | ||||
|  | ||||
| #define FIXED_DICTSTART 0xfffe0000 | ||||
| #define FIXED_DICTEND   0xfffeffff | ||||
|  | ||||
| void collect_multiboot_info(struct sys_info *info); | ||||
| void collect_multiboot_info(struct sys_info *info) | ||||
| { | ||||
| 	info->dict_start=(unsigned long *)FIXED_DICTSTART; | ||||
| 	info->dict_end=(unsigned long *)FIXED_DICTEND; | ||||
| } | ||||
|  | ||||
							
								
								
									
										2
									
								
								arch/amd64/relocate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								arch/amd64/relocate.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| void relocate(struct sys_info *); | ||||
|  | ||||
							
								
								
									
										134
									
								
								arch/amd64/segment.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								arch/amd64/segment.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | ||||
| /* Segmentation of the AMD64 architecture. | ||||
|  * | ||||
|  * 2003-07 by SONE Takeshi | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "sys_info.h" | ||||
| #include "relocate.h" | ||||
| #include "segment.h" | ||||
|  | ||||
| #define printf printk | ||||
| #ifdef CONFIG_DEBUG_BOOT | ||||
| #define debug printk | ||||
| #else | ||||
| #define debug(x...) | ||||
| #endif | ||||
|  | ||||
| /* i386 lgdt argument */ | ||||
| struct gdtarg { | ||||
|     unsigned short limit; | ||||
|     unsigned int base; | ||||
| } __attribute__((packed)); | ||||
|  | ||||
| /* How far the virtual address (used in C) is different from physical  | ||||
|  * address. Since we start in flat mode, the initial value is zero. */ | ||||
| unsigned long virt_offset = 0; | ||||
|  | ||||
| /* GDT, the global descriptor table */ | ||||
| struct segment_desc gdt[NUM_SEG] = { | ||||
|     /* 0x00: null segment */ | ||||
|     {0, 0, 0, 0, 0, 0}, | ||||
|     /* 0x08: flat code segment */ | ||||
|     {0xffff, 0, 0, 0x9f, 0xcf, 0}, | ||||
|     /* 0x10: flat data segment */ | ||||
|     {0xffff, 0, 0, 0x93, 0xcf, 0}, | ||||
|     /* 0x18: code segment for relocated execution */ | ||||
|     {0xffff, 0, 0, 0x9f, 0xcf, 0}, | ||||
|     /* 0x20: data segment for relocated execution */ | ||||
|     {0xffff, 0, 0, 0x93, 0xcf, 0}, | ||||
| }; | ||||
|  | ||||
| extern char _start[], _end[]; | ||||
|  | ||||
| void relocate(struct sys_info *info) | ||||
| { | ||||
|     int i; | ||||
|     unsigned long prog_addr; | ||||
|     unsigned long prog_size; | ||||
|     unsigned long addr, new_base; | ||||
|     unsigned long long segsize; | ||||
|     unsigned long new_offset; | ||||
|     unsigned d0, d1, d2; | ||||
|     struct gdtarg gdtarg; | ||||
| #define ALIGNMENT 16 | ||||
|  | ||||
|     prog_addr = virt_to_phys(&_start); | ||||
|     prog_size = virt_to_phys(&_end) - virt_to_phys(&_start); | ||||
|     debug("Current location: %#lx-%#lx\n", prog_addr, prog_addr+prog_size-1); | ||||
|  | ||||
|     new_base = 0; | ||||
|     for (i = 0; i < info->n_memranges; i++) { | ||||
| 	if (info->memrange[i].base >= 1ULL<<32) | ||||
| 	    continue; | ||||
| 	segsize = info->memrange[i].size; | ||||
| 	if (info->memrange[i].base + segsize > 1ULL<<32) | ||||
| 	    segsize = (1ULL<<32) - info->memrange[i].base; | ||||
| 	if (segsize < prog_size+ALIGNMENT) | ||||
| 	    continue; | ||||
| 	addr = info->memrange[i].base + segsize - prog_size; | ||||
| 	addr &= ~(ALIGNMENT-1); | ||||
| 	if (addr >= prog_addr && addr < prog_addr + prog_size) | ||||
| 	    continue; | ||||
| 	if (prog_addr >= addr && prog_addr < addr + prog_size) | ||||
| 	    continue; | ||||
| 	if (addr > new_base) | ||||
| 	    new_base = addr; | ||||
|     } | ||||
|     if (new_base == 0) { | ||||
| 	printf("Can't find address to relocate\n"); | ||||
| 	return; | ||||
|     } | ||||
|  | ||||
|     debug("Relocating to %#lx-%#lx... ", | ||||
| 	    new_base, new_base + prog_size - 1); | ||||
|  | ||||
|     /* New virtual address offset */ | ||||
|     new_offset = new_base - (unsigned long) &_start; | ||||
|  | ||||
|     /* Tweak the GDT */ | ||||
|     gdt[RELOC_CODE].base_0 = (unsigned short) new_offset; | ||||
|     gdt[RELOC_CODE].base_16 = (unsigned char) (new_offset>>16); | ||||
|     gdt[RELOC_CODE].base_24 = (unsigned char) (new_offset>>24); | ||||
|     gdt[RELOC_DATA].base_0 = (unsigned short) new_offset; | ||||
|     gdt[RELOC_DATA].base_16 = (unsigned char) (new_offset>>16); | ||||
|     gdt[RELOC_DATA].base_24 = (unsigned char) (new_offset>>24); | ||||
|  | ||||
|     /* Load new GDT and reload segments */ | ||||
|     gdtarg.base = new_offset + (unsigned long) gdt; | ||||
|     gdtarg.limit = GDT_LIMIT; | ||||
|     __asm__ __volatile__ ( | ||||
| 	    "rep; movsb\n\t" /* copy everything */ | ||||
| 	    "lgdt %3\n\t" | ||||
| 	    "ljmp %4, $1f\n1:\t" | ||||
| 	    "movw %5, %%ds\n\t" | ||||
| 	    "movw %5, %%es\n\t" | ||||
| 	    "movw %5, %%fs\n\t" | ||||
| 	    "movw %5, %%gs\n\t" | ||||
| 	    "movw %5, %%ss\n" | ||||
| 	    : "=&S" (d0), "=&D" (d1), "=&c" (d2) | ||||
| 	    : "m" (gdtarg), "n" (RELOC_CS), "q" ((unsigned short) RELOC_DS),  | ||||
| 	    "0" (&_start), "1" (new_base), "2" (prog_size)); | ||||
|  | ||||
|     virt_offset = new_offset; | ||||
|     debug("ok\n"); | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| /* Copy GDT to new location and reload it */ | ||||
| void move_gdt(unsigned long newgdt) | ||||
| { | ||||
|     struct gdtarg gdtarg; | ||||
|  | ||||
|     debug("Moving GDT to %#lx...", newgdt); | ||||
|     memcpy(phys_to_virt(newgdt), gdt, sizeof gdt); | ||||
|     gdtarg.base = newgdt; | ||||
|     gdtarg.limit = GDT_LIMIT; | ||||
|     debug("reloading GDT..."); | ||||
|     __asm__ __volatile__ ("lgdt %0\n\t" : : "m" (gdtarg)); | ||||
|     debug("reloading CS for fun..."); | ||||
|     __asm__ __volatile__ ("ljmp %0, $1f\n1:" : : "n" (RELOC_CS)); | ||||
|     debug("ok\n"); | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										30
									
								
								arch/amd64/segment.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								arch/amd64/segment.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
|  | ||||
| /* Segment indexes. Must match the gdt definition in segment.c. */ | ||||
| enum { | ||||
|     NULL_SEG, | ||||
|     FLAT_CODE, | ||||
|     FLAT_DATA, | ||||
|     RELOC_CODE, | ||||
|     RELOC_DATA, | ||||
|     NUM_SEG, | ||||
| }; | ||||
|  | ||||
| /* Values for segment selector register */ | ||||
| #define FLAT_CS (FLAT_CODE << 3) | ||||
| #define FLAT_DS (FLAT_DATA << 3) | ||||
| #define RELOC_CS (RELOC_CODE << 3) | ||||
| #define RELOC_DS (RELOC_DATA << 3) | ||||
|  | ||||
| /* i386 segment descriptor */ | ||||
| struct segment_desc { | ||||
|     unsigned short limit_0; | ||||
|     unsigned short base_0; | ||||
|     unsigned char base_16; | ||||
|     unsigned char types; | ||||
|     unsigned char flags; | ||||
|     unsigned char base_24; | ||||
| }; | ||||
|  | ||||
| extern struct segment_desc gdt[NUM_SEG]; | ||||
|  | ||||
| #define GDT_LIMIT ((NUM_SEG << 3) - 1) | ||||
							
								
								
									
										116
									
								
								arch/amd64/switch.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								arch/amd64/switch.S
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| 	.globl	entry, __switch_context, __exit_context, halt | ||||
|  | ||||
| 	.text | ||||
| 	.align	4 | ||||
|  | ||||
| /* | ||||
|  * Entry point | ||||
|  * We start execution from here. | ||||
|  * It is assumed that CPU is in 32-bit protected mode and  | ||||
|  * all segments are 4GB and base zero (flat model). | ||||
|  */ | ||||
| entry: | ||||
| 	/* Save boot context and switch to our main context. | ||||
| 	 * Main context is statically defined in C. | ||||
| 	 */ | ||||
| 	pushl	%cs | ||||
| 	call	__switch_context | ||||
|  | ||||
| 	/* We get here when the main context switches back to | ||||
| 	 * the boot context. | ||||
| 	 * Return to previous bootloader. | ||||
| 	 */ | ||||
| 	ret | ||||
|  | ||||
| /* | ||||
|  * Switch execution context | ||||
|  * This saves registers, segments, and GDT in the stack, then | ||||
|  * switches the stack, and restores everything from the new stack. | ||||
|  * This function takes no argument. New stack pointer is | ||||
|  * taken from global variable __context, and old stack pointer | ||||
|  * is also saved to __context. This way we can just jump to  | ||||
|  * this routine to get back to the original context. | ||||
|  * | ||||
|  * Call this routine with lcall or pushl %cs; call. | ||||
|  */ | ||||
| __switch_context: | ||||
| 	/* Save everything in current stack */ | ||||
| 	pushfl		    /* 56 */ | ||||
| 	pushl	%ds	    /* 52 */ | ||||
| 	pushl	%es	    /* 48 */ | ||||
| 	pushl	%fs	    /* 44 */ | ||||
| 	pushl	%gs	    /* 40 */ | ||||
| 	pushal		    /* 8 */ | ||||
| 	subl	$8, %esp | ||||
| 	movw	%ss, (%esp) /* 0 */ | ||||
| 	sgdt	2(%esp)	    /* 2 */ | ||||
|  | ||||
| #if 0 | ||||
| 	/* Swap %cs and %eip on the stack, so lret will work */ | ||||
| 	movl	60(%esp), %eax | ||||
| 	xchgl	%eax, 64(%esp) | ||||
| 	movl	%eax, 60(%esp) | ||||
| #endif | ||||
| 	 | ||||
| 	/* At this point we don't know if we are on flat segment | ||||
| 	 * or relocated. So compute the address offset from %eip. | ||||
| 	 * Assuming CS.base==DS.base==SS.base. | ||||
| 	 */ | ||||
| 	call	1f | ||||
| 1:	popl	%ebx | ||||
| 	subl	$1b, %ebx | ||||
|  | ||||
| 	/* Interrupts are not allowed... */ | ||||
| 	cli | ||||
| 	 | ||||
| 	/* Current context pointer is our stack pointer */ | ||||
| 	movl	%esp, %esi | ||||
|  | ||||
| 	/* Normalize the ctx pointer */ | ||||
| 	subl	%ebx, %esi | ||||
|  | ||||
| 	/* Swap it with new value */ | ||||
| 	xchgl	%esi, __context(%ebx) | ||||
|  | ||||
| 	/* Adjust new ctx pointer for current address offset */ | ||||
| 	addl	%ebx, %esi | ||||
|  | ||||
| 	/* Load new %ss and %esp to temporary */ | ||||
| 	movzwl	(%esi), %edx | ||||
| 	movl	20(%esi), %eax | ||||
|  | ||||
| 	/* Load new GDT */ | ||||
| 	lgdt	2(%esi) | ||||
|  | ||||
| 	/* Load new stack segment with new GDT */ | ||||
| 	movl	%edx, %ss | ||||
|  | ||||
| 	/* Set new stack pointer, but we have to adjust it because | ||||
| 	 * pushal saves %esp value before pushal, and we want the value | ||||
| 	 * after pushal. | ||||
| 	 */ | ||||
| 	leal	-32(%eax), %esp | ||||
|  | ||||
| 	/* Load the rest from new stack */ | ||||
| 	popal | ||||
| 	popl	%gs | ||||
| 	popl	%fs | ||||
| 	popl	%es | ||||
| 	popl	%ds | ||||
| 	popfl | ||||
|  | ||||
| 	/* Finally, load new %cs and %eip */ | ||||
| 	lret | ||||
|  | ||||
| __exit_context: | ||||
| 	/* Get back to the original context */ | ||||
| 	pushl	%cs | ||||
| 	call	__switch_context | ||||
|  | ||||
| 	/* We get here if the other context attempt to switch to this | ||||
| 	 * dead context. This should not happen. */ | ||||
|  | ||||
| halt: | ||||
| 	cli | ||||
| 	hlt | ||||
| 	jmp	halt | ||||
							
								
								
									
										57
									
								
								arch/amd64/sys_info.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								arch/amd64/sys_info.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "sys_info.h" | ||||
| #include "context.h" | ||||
|  | ||||
| #define printf printk | ||||
| #ifdef CONFIG_DEBUG_BOOT | ||||
| #define debug printk | ||||
| #else | ||||
| #define debug(x...)  | ||||
| #endif | ||||
|  | ||||
| void collect_multiboot_info(struct sys_info *); | ||||
|  | ||||
| void collect_sys_info(struct sys_info *info) | ||||
| { | ||||
|     int i; | ||||
|     unsigned long long total = 0; | ||||
|     struct memrange *mmap; | ||||
|  | ||||
|     /* Pick up paramters given by bootloader to us */ | ||||
|     info->boot_type = boot_ctx->eax; | ||||
|     info->boot_data = boot_ctx->ebx; | ||||
|     info->boot_arg = boot_ctx->param[0]; | ||||
|     debug("boot eax = %#lx\n", info->boot_type); | ||||
|     debug("boot ebx = %#lx\n", info->boot_data); | ||||
|     debug("boot arg = %#lx\n", info->boot_arg); | ||||
|  | ||||
|     collect_elfboot_info(info); | ||||
| #ifdef CONFIG_LINUXBIOS | ||||
|     collect_linuxbios_info(info); | ||||
| #endif | ||||
| #ifdef CONFIG_IMAGE_ELF_MULTIBOOT | ||||
|     collect_multiboot_info(info); | ||||
| #endif | ||||
|  | ||||
|     if (!info->memrange) { | ||||
| 	printf("Can't get memory map from firmware. " | ||||
| 		"Using hardcoded default.\n"); | ||||
| 	info->n_memranges = 2; | ||||
| 	info->memrange = malloc(2 * sizeof(struct memrange)); | ||||
| 	info->memrange[0].base = 0; | ||||
| 	info->memrange[0].size = 640*1024; | ||||
| 	info->memrange[1].base = 1024*1024; | ||||
| 	info->memrange[1].size = 32*1024*1024 | ||||
| 	    - info->memrange[1].base; | ||||
|     } | ||||
|  | ||||
|     debug("\n"); | ||||
|     mmap=info->memrange; | ||||
|     for (i = 0; i < info->n_memranges; i++) { | ||||
| 	debug("%016Lx-", mmap[i].base); | ||||
| 	debug("%016Lx\n", mmap[i].base+mmap[i].size); | ||||
| 	total += mmap[i].size; | ||||
|     } | ||||
|     debug("RAM %Ld MB\n", (total + 512*1024) >> 20); | ||||
| } | ||||
							
								
								
									
										8
									
								
								arch/build.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								arch/build.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| <?xml version="1.0"?> | ||||
| <build> | ||||
|  <include href="x86/build.xml"/> | ||||
|  <include href="amd64/build.xml"/> | ||||
|  <include href="ppc/build.xml"/> | ||||
|  <include href="ia64/build.xml"/> | ||||
|  <include href="unix/build.xml"/> | ||||
| </build> | ||||
							
								
								
									
										24
									
								
								arch/ia64/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								arch/ia64/Kconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| mainmenu "OpenBIOS Configuration" | ||||
|  | ||||
| config IPF | ||||
| 	bool | ||||
| 	default y | ||||
| 	help | ||||
| 	  Building for IPF hardware. | ||||
|  | ||||
| config LITTLE_ENDIAN | ||||
| 	bool | ||||
| 	default y | ||||
| 	help | ||||
| 	  IPF is little endian. | ||||
|  | ||||
| menu "Build hosted UNIX Binary" | ||||
| source "arch/unix/Kconfig" | ||||
| endmenu | ||||
|  | ||||
| source "kernel/Kconfig" | ||||
| source "forth/Kconfig" | ||||
| source "modules/Kconfig" | ||||
| source "drivers/Kconfig" | ||||
|  | ||||
|  | ||||
							
								
								
									
										6
									
								
								arch/ia64/build.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								arch/ia64/build.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| <build condition="IPF"> | ||||
|  <dictionary name="openbios-ia64" init="openbios" target="forth"> | ||||
|   <object source="init.fs"/> | ||||
|  </dictionary> | ||||
| </build> | ||||
|  | ||||
							
								
								
									
										65
									
								
								arch/ia64/defconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								arch/ia64/defconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| # | ||||
| # Automatically generated make config: don't edit | ||||
| # | ||||
| CONFIG_IPF=y | ||||
| CONFIG_LITTLE_ENDIAN=y | ||||
|  | ||||
| # | ||||
| # Kernel binaries (x86) | ||||
| # | ||||
| # CONFIG_IMAGE_ELF is not set | ||||
| # CONFIG_IMAGE_ELF_EMBEDDED is not set | ||||
| # CONFIG_IMAGE_ELF_MULTIBOOT is not set | ||||
|  | ||||
| # | ||||
| # Build hosted UNIX Binary | ||||
| # | ||||
| CONFIG_HOST_UNIX=y | ||||
| # CONFIG_PLUGIN_PCI is not set | ||||
|  | ||||
| # | ||||
| # Kernel Debugging | ||||
| # | ||||
| # CONFIG_DEBUG is not set | ||||
| CONFIG_DEBUG_CONSOLE=y | ||||
| CONFIG_DEBUG_CONSOLE_SERIAL=y | ||||
| CONFIG_SERIAL_PORT=1 | ||||
| CONFIG_SERIAL_SPEED=115200 | ||||
| CONFIG_DEBUG_CONSOLE_VGA=y | ||||
|  | ||||
| # | ||||
| # Module Configuration | ||||
| # | ||||
| CONFIG_CMDLINE=y | ||||
| CONFIG_DEBLOCKER=y | ||||
|  | ||||
| # | ||||
| # Filesystem Configuration | ||||
| # | ||||
| CONFIG_DISK_LABEL=y | ||||
| CONFIG_PART_SUPPORT=y | ||||
| CONFIG_PC_PARTS=y | ||||
| CONFIG_FS=y | ||||
| CONFIG_GRUBFS=y | ||||
| CONFIG_FSYS_EXT2FS=y | ||||
| CONFIG_FSYS_FAT=y | ||||
| CONFIG_FSYS_JFS=y | ||||
| # CONFIG_FSYS_MINIX is not set | ||||
| CONFIG_FSYS_REISERFS=y | ||||
| CONFIG_FSYS_XFS=y | ||||
| CONFIG_FSYS_ISO9660=y | ||||
| # CONFIG_FSYS_FFS is not set | ||||
| # CONFIG_FSYS_VSTAFS is not set | ||||
| # CONFIG_DEBUG_FS is not set | ||||
|  | ||||
| # | ||||
| # Miscellaneous | ||||
| # | ||||
| CONFIG_LINUXBIOS=y | ||||
|  | ||||
| # | ||||
| # Drivers | ||||
| # | ||||
| CONFIG_DRIVER_PCI=y | ||||
| CONFIG_DRIVER_IDE=y | ||||
| # CONFIG_DEBUG_IDE is not set | ||||
							
								
								
									
										77
									
								
								arch/ia64/init.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								arch/ia64/init.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| :noname  | ||||
|   ."   Type 'help' for detailed information" cr | ||||
|   \ ."   boot secondary slave cdrom: " cr | ||||
|   \ ."    0 >  boot hd:2,\boot\vmlinuz root=/dev/hda2" cr | ||||
|   ; DIAG-initializer | ||||
|  | ||||
| " /" find-device | ||||
|  | ||||
| new-device | ||||
|   " memory" device-name | ||||
|   \ 12230 encode-int " reg" property | ||||
|   external | ||||
|   : open true ; | ||||
|   : close ; | ||||
|   \ claim ( phys size align -- base ) | ||||
|   \ release ( phys size -- ) | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
|   " cpus" device-name | ||||
|   1 " #address-cells" int-property | ||||
|   0 " #size-cells" int-property | ||||
|  | ||||
|   external | ||||
|   : open true ; | ||||
|   : close ; | ||||
|   : decode-unit parse-hex ; | ||||
|  | ||||
| finish-device | ||||
|  | ||||
| : make-openable ( path ) | ||||
|   find-dev if | ||||
|     begin ?dup while | ||||
|       \ install trivial open and close methods | ||||
|       dup active-package! is-open | ||||
|       parent | ||||
|     repeat | ||||
|   then | ||||
| ; | ||||
|  | ||||
| : preopen ( chosen-str node-path ) | ||||
|   2dup make-openable | ||||
|      | ||||
|   " /chosen" find-device | ||||
|   open-dev ?dup if | ||||
|     encode-int 2swap property | ||||
|   else | ||||
|     2drop | ||||
|   then | ||||
| ; | ||||
|   | ||||
| :noname | ||||
|   set-defaults | ||||
| ; SYSTEM-initializer | ||||
|  | ||||
| \ preopen device nodes (and store the ihandles under /chosen) | ||||
| :noname | ||||
|   " memory" " /memory" preopen | ||||
|   " mmu" " /cpus/@0" preopen | ||||
|   " stdout" " /builtin/console" preopen | ||||
|   " stdin" " /builtin/console" preopen | ||||
|  | ||||
| ; SYSTEM-initializer | ||||
|  | ||||
| \ use the tty interface if available | ||||
| :noname | ||||
|   " /builtin/console" find-dev if drop | ||||
|     " /builtin/console" " input-device" $setenv | ||||
|     " /builtin/console" " output-device" $setenv | ||||
|   then | ||||
| ; SYSTEM-initializer | ||||
| 	     | ||||
| :noname | ||||
|   " keyboard" input | ||||
| ; CONSOLE-IN-initializer | ||||
|    | ||||
|  | ||||
							
								
								
									
										48
									
								
								arch/ppc/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								arch/ppc/Kconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| mainmenu "OpenBIOS Configuration" | ||||
|  | ||||
| config PPC | ||||
| 	bool | ||||
| 	default y | ||||
| 	help | ||||
| 	  Building for PPC hardware. | ||||
|  | ||||
| config BIG_ENDIAN | ||||
| 	bool | ||||
| 	default y | ||||
| 	help | ||||
| 	  PPC hardware is big endian (per default) | ||||
|  | ||||
| choice | ||||
| 	prompt "Platform Type" | ||||
| 	default MOL | ||||
|  | ||||
| config MOL | ||||
| 	bool "Mac-on-Linux" | ||||
| 	help | ||||
| 	  Build an image for Mac-on-Linux | ||||
|  | ||||
| config MPC107 | ||||
| 	bool "MPC107 board (Crescendo)" | ||||
| 	help | ||||
| 	  Build for Crescendo board. | ||||
|  | ||||
| config BRIQ | ||||
| 	bool "Total Impact briQ" | ||||
| 	help | ||||
| 	  Build an image for the Total Impact briQ | ||||
|  | ||||
| config NO_ARCH | ||||
| 	bool "None" | ||||
| 	help | ||||
| 	  Don't build any images. | ||||
|  | ||||
| endchoice | ||||
|  | ||||
| menu "Build hosted UNIX Binary" | ||||
| source "arch/unix/Kconfig" | ||||
| endmenu | ||||
|  | ||||
| source "kernel/Kconfig" | ||||
| source "forth/Kconfig" | ||||
| source "modules/Kconfig" | ||||
| source "drivers/Kconfig" | ||||
							
								
								
									
										79
									
								
								arch/ppc/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								arch/ppc/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,79 @@ | ||||
|  | ||||
| include			../../config/Makefile.top | ||||
|  | ||||
| SUBDIRS			=  | ||||
| MOL			= $(CONFIG_MOL:y=mol) | ||||
| BRIQ			= $(CONFIG_BRIQ:y=briq) | ||||
| XTARGETS		= $(MOL) $(BRIQ) ppc mollink | ||||
| DICTIONARIES		= $(MOL) $(BRIQ) | ||||
|  | ||||
| INCLUDES		= -I../../kernel -I../../kernel/include \ | ||||
| 			  -I../../include/molasm -I$(ODIR)/include | ||||
|  | ||||
| ############################################################################# | ||||
|  | ||||
| mol-OBJS		= mol/init.o mol/main.o mol/mol.o mol/console.o mol/osi-blk.o \ | ||||
| 			  mol/osi-scsi.o mol/pseudodisk.o mol/methods.o ofmem.o \ | ||||
| 			  mol/video.o mol/prom.o mol/tree.o misc.o mol/kernel.o | ||||
|  | ||||
| briq-OBJS		= briq/init.o briq/main.o briq/briq.o briq/vfd.o \ | ||||
| 			  ofmem.o briq/methods.o briq/tree.o \ | ||||
| 			  misc.o briq/kernel.o | ||||
|  | ||||
| ppc-OBJS		= $(KOBJS) $(MODULE_LIBS) \ | ||||
| 			  $(FS_LIBS) $(DRIVER_LIBS) $(LIBC_LIBS) | ||||
|  | ||||
| all-$(CONFIG_MOL)	+= $(ODIR)/mol.image | ||||
| all-$(CONFIG_BRIQ)	+= $(ODIR)/briq.image | ||||
| all-$(CONFIG_MPC107)	+= $(ODIR)/mpc107.image | ||||
|  | ||||
|  | ||||
| ############################################################################# | ||||
|  | ||||
| mol-SRC			= ppc.fs tree.fs mol.fs $(ARCHDICT_SRC) | ||||
| briq-SRC		= ppc.fs briq/tree.fs briq/briq.fs $(ARCHDICT_SRC) | ||||
|  | ||||
| $(ODIR)/mol/kernel.o:	$(ODIR)/include/mol-dict.h | ||||
| $(ODIR)/briq/kernel.o:	$(ODIR)/include/briq-dict.h | ||||
|  | ||||
| $(ODIR)/include/mol-dict.h: $(ODIR)/mol.dict | ||||
| 	test -d $(dir $@) || $(INSTALL) -d $(dir $@) | ||||
| 	@echo "static const char forth_dictionary[] = {" > $@ | ||||
| 	@cat $< | hexdump -ve '1/0 "\t" 8/1 "0x%02x, " 1/0 "\n"' \ | ||||
| 		| sed 's/0x  ,//g' >> $@ | ||||
| 	@echo "};" >> $@ | ||||
|  | ||||
| $(ODIR)/include/briq-dict.h: $(ODIR)/briq.dict | ||||
| 	test -d $(dir $@) || $(INSTALL) -d $(dir $@) | ||||
| 	@echo "static const char forth_dictionary[] = {" > $@ | ||||
| 	@cat $< | hexdump -ve '1/0 "\t" 8/1 "0x%02x, " 1/0 "\n"' \ | ||||
| 		| sed 's/0x  ,//g' >> $@ | ||||
| 	@echo "};" >> $@ | ||||
|  | ||||
| ############################################################################# | ||||
|  | ||||
| $(ODIR)/mol.image: $(ODIR)/start.o $(ODIR)/libmol.a $(ODIR)/libppc.a | ||||
| 	@printf "= Building %-22s : " $@ | ||||
| 	building= | ||||
| 	$(LD) -Ttext=0x01e01000 -Bstatic $^ $(LIBGCC) -o $@ | ||||
| 	@nm $@ | sort > $(ODIR)/mol.syms | ||||
| 	strip -g $@ | ||||
| 	@echo "ok" | ||||
|  | ||||
| $(ODIR)/briq.image: $(ODIR)/start.o $(ODIR)/timebase.o $(ODIR)/libbriq.a $(ODIR)/libppc.a | ||||
| 	@printf "= Building %-22s : " $@ | ||||
| 	building= | ||||
| 	$(LD) -g -Ttext=0x01e01000 -Bstatic $^ $(LIBGCC) -o $@ | ||||
| 	@nm $@ | sort > $(ODIR)/briq.syms | ||||
| 	#strip -g $@ | ||||
| 	@echo "ok" | ||||
|  | ||||
| $(ODIR)/mpc107.image: | ||||
| 	@echo "BUILDING mpc107.image (not yet implemented)" | ||||
|  | ||||
| clean-local: | ||||
| 	$(RM) $(ODIR)/*.image $(ODIR)/*.syms $(ODIR)/include/mol-dict.h | ||||
|  | ||||
| include			Makefile.asm | ||||
| include			$(rules)/Rules.make | ||||
| include			$(rules)/Rules.forth | ||||
							
								
								
									
										32
									
								
								arch/ppc/Makefile.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								arch/ppc/Makefile.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| # -*- makefile -*-  | ||||
| # | ||||
| #   Makefile.asm - assembly support | ||||
| #    | ||||
| #   Copyright (C) 2004 Samuel Rydh (samuel@ibrium.se) | ||||
| #    | ||||
| #   This program is free software; you can redistribute it and/or | ||||
| #   modify it under the terms of the GNU General Public License | ||||
| #   version 2 | ||||
|  | ||||
|  | ||||
| ################################################# | ||||
| # Rules for asm targets | ||||
| ################################################# | ||||
|  | ||||
| ASMFLAGS	= -D__ASSEMBLY__ -I$(top_srcdir) $(ALTIVEC) | ||||
| FILTERBIN	= $(top_srcdir)/scripts/asfilter | ||||
| ASFILTER	= $(shell if test -x $(FILTERBIN) ; then echo $(FILTERBIN) \ | ||||
| 			; else echo "tr ';' '\n'" ; fi) | ||||
| INVOKE_M4	= | $(M4) -s $(M4_NO_GNU) | $(ASFILTER) | ||||
|  | ||||
| $(ODIR)/%.o: %.S | ||||
| 	@printf "    Compiling %-20s: " $(notdir $@) | ||||
| 	assembly= | ||||
| 	@install -d $(dir $@) | ||||
| 	@$(RM) $@ $@.s | ||||
| 	@$(CPP) $(ASMFLAGS) $(IDIRS) $< > /dev/null | ||||
| 	$(CPP) $(ASMFLAGS) $(IDIRS) $(DEPFLAGS) $< $(INVOKE_M4) > $@.s | ||||
| 	$(AS) $@.s $(AS_FLAGS) -o $@ | ||||
| 	@$(DEPEXTRA) | ||||
| 	@$(RM) $@.s | ||||
| 	@echo "ok" | ||||
							
								
								
									
										194
									
								
								arch/ppc/briq/briq.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								arch/ppc/briq/briq.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,194 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *    | ||||
|  *	<briq.c> | ||||
|  *    | ||||
|  *   Copyright (C) 2004, Greg Watson | ||||
|  *    | ||||
|  *   derived from mol.c | ||||
|  * | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "libc/vsprintf.h" | ||||
| #include "libc/string.h" | ||||
| #include "briq/briq.h" | ||||
| #include <stdarg.h> | ||||
|  | ||||
| #define UART_BASE 0x3f8 | ||||
|  | ||||
| unsigned long virt_offset = 0; | ||||
|  | ||||
| void | ||||
| exit( int status ) | ||||
| { | ||||
| 	for (;;); | ||||
| } | ||||
|  | ||||
| void | ||||
| fatal_error( const char *err ) | ||||
| { | ||||
| 	printk("Fatal error: %s\n", err ); | ||||
| 	exit(0); | ||||
| } | ||||
|  | ||||
| void | ||||
| panic( const char *err ) | ||||
| { | ||||
| 	printk("Panic: %s\n", err ); | ||||
| 	exit(0); | ||||
|  | ||||
| 	/* won't come here... this keeps the gcc happy */ | ||||
| 	for( ;; ) | ||||
| 		; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	print using OSI interface					*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static int do_indent; | ||||
|  | ||||
| int | ||||
| printk( const char *fmt, ... ) | ||||
| { | ||||
| 	char *p, buf[1024];	/* XXX: no buffer overflow protection... */ | ||||
| 	va_list args; | ||||
| 	int i; | ||||
|  | ||||
| 	va_start(args, fmt); | ||||
| 	i=vsprintf(buf,fmt,args); | ||||
| 	va_end(args); | ||||
|  | ||||
| 	for( p=buf; *p; p++ ) { | ||||
| 		if( *p == '\n' ) | ||||
| 			do_indent = 0; | ||||
| 		if( do_indent++ == 1 ) { | ||||
| 			putchar( '>' ); | ||||
| 			putchar( '>' ); | ||||
| 			putchar( ' ' ); | ||||
| 		} | ||||
| 		putchar( *p ); | ||||
| 	} | ||||
| 	return i; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	TTY iface							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static int ttychar = -1; | ||||
|  | ||||
| static int | ||||
| tty_avail( void ) | ||||
| { | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int | ||||
| tty_putchar( int c ) | ||||
| { | ||||
| 	if( tty_avail() ) { | ||||
| 		while (!(inb(UART_BASE + 0x05) & 0x20)) | ||||
| 			; | ||||
| 		outb(c, UART_BASE); | ||||
| 		while (!(inb(UART_BASE + 0x05) & 0x40)) | ||||
| 			; | ||||
| 	} | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| int | ||||
| availchar( void ) | ||||
| { | ||||
| 	if( !tty_avail() ) | ||||
| 		return 0; | ||||
| 	 | ||||
| 	if( ttychar < 0 ) | ||||
| 		ttychar = inb(UART_BASE); | ||||
| 	return (ttychar >= 0); | ||||
| } | ||||
|  | ||||
| int | ||||
| getchar( void ) | ||||
| { | ||||
| 	int ch; | ||||
|  | ||||
| 	if( !tty_avail() ) | ||||
| 		return 0; | ||||
|  | ||||
| 	if( ttychar < 0 ) | ||||
| 		return inb(UART_BASE); | ||||
| 	ch = ttychar; | ||||
| 	ttychar = -1; | ||||
| 	return ch; | ||||
| } | ||||
|  | ||||
| int | ||||
| putchar( int c ) | ||||
| { | ||||
| 	if (c == '\n') | ||||
| 		tty_putchar('\r'); | ||||
| 	return tty_putchar(c); | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	briQ specific stuff						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static char nvram[2048]; | ||||
|  | ||||
| void | ||||
| dump_nvram(void) | ||||
| { | ||||
|   static char hexdigit[] = "0123456789abcdef"; | ||||
|   int i; | ||||
|   for (i = 0; i < 16*4; i++) | ||||
|     { | ||||
|       printk ("%c", hexdigit[nvram[i] >> 4]); | ||||
|       printk ("%c", hexdigit[nvram[i] % 16]); | ||||
|       if (!((i + 1) % 16)) | ||||
|         { | ||||
|           printk ("\n"); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           printk (" "); | ||||
|         } | ||||
|     }	 | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| arch_nvram_size( void ) | ||||
| { | ||||
| 	return sizeof(nvram); | ||||
| } | ||||
|  | ||||
| void | ||||
| arch_nvram_put( char *buf ) | ||||
| { | ||||
| 	memcpy(nvram, buf, sizeof(nvram)); | ||||
| 	printk("new nvram:\n"); | ||||
| 	dump_nvram(); | ||||
| } | ||||
|  | ||||
| void | ||||
| arch_nvram_get( char *buf ) | ||||
| { | ||||
| 	memcpy(buf, nvram, sizeof(nvram)); | ||||
| 	printk("current nvram:\n"); | ||||
| 	dump_nvram(); | ||||
| } | ||||
							
								
								
									
										115
									
								
								arch/ppc/briq/briq.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								arch/ppc/briq/briq.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | ||||
| \   briq specific initialization code | ||||
| \  | ||||
| \   Copyright (C) 2004 Greg Watson | ||||
| \  | ||||
| \   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 | ||||
| \  | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------------------- | ||||
| \ initialization | ||||
| \ ------------------------------------------------------------------------- | ||||
|  | ||||
| : make-openable ( path ) | ||||
|   find-dev if | ||||
|     begin ?dup while | ||||
|       \ install trivial open and close methods | ||||
|       dup active-package! is-open | ||||
|       parent | ||||
|     repeat | ||||
|   then | ||||
| ; | ||||
|  | ||||
| : preopen ( chosen-str node-path ) | ||||
|   2dup make-openable | ||||
|    | ||||
|   " /chosen" find-device | ||||
|   open-dev ?dup if | ||||
|     encode-int 2swap property | ||||
|   else | ||||
|     2drop | ||||
|   then | ||||
| ; | ||||
|  | ||||
| \ preopen device nodes (and store the ihandles under /chosen) | ||||
| :noname | ||||
|   " rtc" " /pci/isa/rtc" preopen | ||||
|   " memory" " /memory" preopen | ||||
|   " mmu" " /cpu@0" preopen | ||||
|   " stdout" " /packages/terminal-emulator" preopen | ||||
|   " stdin" " keyboard" preopen | ||||
|  | ||||
| ; SYSTEM-initializer | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------------------- | ||||
| \ device tree fixing | ||||
| \ ------------------------------------------------------------------------- | ||||
|  | ||||
| \ add decode-address methods | ||||
| : (make-decodable) ( phandle -- ) | ||||
|  | ||||
|     dup " #address-cells" rot get-package-property 0= if | ||||
|       decode-int nip nip | ||||
|       over " decode-unit" rot find-method if 2drop else | ||||
|         ( save phandle ncells ) | ||||
|        | ||||
|         over active-package! | ||||
|         case | ||||
|           1 of ['] parse-hex " decode-unit" is-xt-func endof | ||||
|           3 of | ||||
|             " bus-range" active-package get-package-property 0= if | ||||
|               decode-int nip nip | ||||
|               ['] encode-unit-pci " encode-unit" is-xt-func | ||||
|               " decode-unit" is-func-begin | ||||
|                 ['] (lit) , , | ||||
|                 ['] decode-unit-pci-bus , | ||||
|               is-func-end | ||||
|             then | ||||
|           endof | ||||
|         endcase | ||||
|       then | ||||
|     then | ||||
|     drop | ||||
| ; | ||||
|      | ||||
| : init-briq-tree ( -- ) | ||||
|   active-package | ||||
|    | ||||
|   iterate-tree-begin | ||||
|   begin ?dup while | ||||
|  | ||||
|     dup (make-decodable) | ||||
|      | ||||
|     iterate-tree | ||||
|   repeat | ||||
|  | ||||
|   active-package! | ||||
| ; | ||||
|  | ||||
| \ use the tty interface if available | ||||
| : activate-tty-interface | ||||
|   " /packages/terminal-emulator" find-dev if drop | ||||
|     " /packages/terminal-emulator" " input-device" $setenv | ||||
|     " /packages/terminal-emulator" " output-device" $setenv | ||||
|   then | ||||
| ; | ||||
|  | ||||
| :noname | ||||
|   " keyboard" input | ||||
| ; CONSOLE-IN-initializer | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------------------- | ||||
| \ pre-booting | ||||
| \ ------------------------------------------------------------------------- | ||||
|  | ||||
| : update-chosen | ||||
|   " /chosen" find-device | ||||
|   stdin @ encode-int " stdin" property | ||||
|   stdout @ encode-int " stdout" property | ||||
|   " /pci/isa/interrupt-controller" find-dev if encode-int " interrupt-controller" property then | ||||
|   device-end | ||||
| ; | ||||
							
								
								
									
										24
									
								
								arch/ppc/briq/briq.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								arch/ppc/briq/briq.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 17:50:12 stepan> | ||||
|  *   Time-stamp: <2004/08/28 17:50:12 stepan> | ||||
|  *    | ||||
|  *	<briq.h> | ||||
|  *    | ||||
|  *   Copyright (C) 2004 Stefan Reinauer | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #ifndef _H_BRIQ | ||||
| #define _H_BRIQ | ||||
|  | ||||
| /* vfd.c */ | ||||
| extern int		vfd_draw_str( const char *str ); | ||||
| extern void		vfd_close( void ); | ||||
|  | ||||
| #include "kernel.h" | ||||
|  | ||||
| #endif   /* _H_BRIQ */ | ||||
							
								
								
									
										129
									
								
								arch/ppc/briq/init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								arch/ppc/briq/init.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *    | ||||
|  *	<init.c> | ||||
|  *	 | ||||
|  *	Initialization for briq | ||||
|  * | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  * | ||||
|  *   based on mol/init.c: | ||||
|  *    | ||||
|  *   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Samuel & David Rydh  | ||||
|  *      (samuel@ibrium.se, dary@lindesign.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "briq/briq.h" | ||||
| #include "ofmem.h" | ||||
| #include "openbios-version.h" | ||||
|  | ||||
| extern void unexpected_excep( int vector ); | ||||
| extern void ob_ide_init( void ); | ||||
| extern void setup_timers( void ); | ||||
|  | ||||
| #if 0 | ||||
| int | ||||
| get_bool_res( const char *res ) | ||||
| { | ||||
| 	char buf[8], *p; | ||||
|  | ||||
| 	p = BootHGetStrRes( res, buf, sizeof(buf) ); | ||||
| 	if( !p ) | ||||
| 		return -1; | ||||
| 	if( !strcasecmp(p,"true") || !strcasecmp(p,"yes") || !strcasecmp(p,"1") ) | ||||
| 		return 1; | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void | ||||
| unexpected_excep( int vector ) | ||||
| { | ||||
| 	printk("briQ panic: Unexpected exception %x\n", vector ); | ||||
| 	for( ;; ) | ||||
| 		; | ||||
| } | ||||
|  | ||||
| void | ||||
| entry( void ) | ||||
| { | ||||
| 	printk("\n"); | ||||
| 	printk("=============================================================\n"); | ||||
| 	printk("OpenBIOS %s [%s]\n", OPENBIOS_RELEASE, OPENBIOS_BUILD_DATE ); | ||||
| 	 | ||||
| 	ofmem_init(); | ||||
| 	initialize_forth(); | ||||
| 	/* won't return */ | ||||
|  | ||||
| 	printk("of_startup returned!\n"); | ||||
| 	for( ;; ) | ||||
| 		; | ||||
| } | ||||
|  | ||||
| static void | ||||
| setenv( char *env, char *value ) | ||||
| { | ||||
| 	push_str( value ); | ||||
| 	push_str( env ); | ||||
| 	fword("$setenv"); | ||||
| } | ||||
|  | ||||
| void | ||||
| arch_of_init( void ) | ||||
| { | ||||
| #if USE_RTAS | ||||
| 	phandle_t ph; | ||||
| #endif | ||||
| 	int autoboot; | ||||
| 	 | ||||
| 	devtree_init(); | ||||
| 	node_methods_init(); | ||||
| 	nvram_init(); | ||||
| 	modules_init(); | ||||
| #ifdef CONFIG_DRIVER_PCI | ||||
| 	ob_pci_init(); | ||||
| #endif | ||||
| #ifdef CONFIG_DRIVER_IDE | ||||
|         setup_timers(); | ||||
|         ob_ide_init(); | ||||
| #endif | ||||
|  | ||||
| #if USE_RTAS | ||||
| 	if( !(ph=find_dev("/rtas")) ) | ||||
| 		printk("Warning: No /rtas node\n"); | ||||
| 	else { | ||||
| 		ulong size = 0x1000; | ||||
| 		while( size < (ulong)of_rtas_end - (ulong)of_rtas_start ) | ||||
| 			size *= 2; | ||||
| 		set_property( ph, "rtas-size", (char*)&size, sizeof(size) ); | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| 	/* tweak boot settings */ | ||||
| 	autoboot = !!get_bool_res("autoboot"); | ||||
| #endif | ||||
| 	autoboot = 0; | ||||
| 	if( !autoboot ) | ||||
| 		printk("Autobooting disabled - dropping into OpenFirmware\n"); | ||||
| 	setenv("auto-boot?", autoboot ? "true" : "false" ); | ||||
| 	setenv("boot-command", "briqboot"); | ||||
|  | ||||
| #if 0 | ||||
| 	if( get_bool_res("tty-interface") == 1 ) | ||||
| #endif | ||||
| 		fword("activate-tty-interface"); | ||||
|  | ||||
| 	/* hack */ | ||||
| 	device_end(); | ||||
| 	bind_func("briqboot", boot ); | ||||
| } | ||||
							
								
								
									
										17
									
								
								arch/ppc/briq/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								arch/ppc/briq/kernel.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:03:25 stepan> | ||||
|  *   Time-stamp: <2004/08/28 18:03:25 stepan> | ||||
|  *    | ||||
|  *	<briq/kernel.c> | ||||
|  *	 | ||||
|  *   Copyright (C) 2004 Stefan Reinauer | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "briq-dict.h" | ||||
| #include "../kernel.c" | ||||
|  | ||||
							
								
								
									
										145
									
								
								arch/ppc/briq/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								arch/ppc/briq/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,145 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *    | ||||
|  *	<main.c> | ||||
|  *	 | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  *	 | ||||
|  *   Based on MOL specific code which is    | ||||
|  *   Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "openbios/elfload.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "libc/diskio.h" | ||||
| #include "libc/vsprintf.h" | ||||
| #include "briq/briq.h" | ||||
| #include "ofmem.h" | ||||
|  | ||||
| static void | ||||
| transfer_control_to_elf( ulong entry ) | ||||
| { | ||||
| 	extern void call_elf( ulong entry ); | ||||
| 	printk("Starting ELF image at 0x%08lX\n", entry); | ||||
| 	call_elf( 0x400000 ); | ||||
| 	//call_elf( entry ); | ||||
|  | ||||
| 	fatal_error("call_elf returned unexpectedly\n"); | ||||
| } | ||||
|  | ||||
| static int | ||||
| load_elf_rom( ulong *entry, int fd ) | ||||
| { | ||||
| 	int i, lszz_offs, elf_offs; | ||||
| 	char buf[128], *addr; | ||||
| 	Elf_ehdr ehdr; | ||||
| 	Elf_phdr *phdr; | ||||
| 	size_t s; | ||||
|  | ||||
| 	printk("Loading '%s'\n", get_file_path(fd)); | ||||
|  | ||||
| 	/* the ELF-image (usually) starts at offset 0x4000 */ | ||||
| 	if( (elf_offs=find_elf(fd)) < 0 ) { | ||||
| 		printk("----> %s is not an ELF image\n", buf ); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 	if( !(phdr=elf_readhdrs(fd, elf_offs, &ehdr)) ) | ||||
| 		fatal_error("elf_readhdrs failed\n"); | ||||
|  | ||||
| 	*entry = ehdr.e_entry; | ||||
|  | ||||
| 	/* load segments. Compressed ROM-image assumed to be located immediately | ||||
| 	 * after the last segment */ | ||||
| 	lszz_offs = elf_offs; | ||||
| 	for( i=0; i<ehdr.e_phnum; i++ ) { | ||||
| 		/* p_memsz, p_flags */ | ||||
| 		s = MIN( phdr[i].p_filesz, phdr[i].p_memsz ); | ||||
| 		seek_io( fd, elf_offs + phdr[i].p_offset ); | ||||
|  | ||||
| 		/* printk("filesz: %08lX memsz: %08lX p_offset: %08lX p_vaddr %08lX\n",  | ||||
| 		   phdr[i].p_filesz, phdr[i].p_memsz, phdr[i].p_offset, | ||||
| 		   phdr[i].p_vaddr ); */ | ||||
|  | ||||
| 		if( phdr[i].p_vaddr != phdr[i].p_paddr ) | ||||
| 			printk("WARNING: ELF segment virtual addr != physical addr\n"); | ||||
| 		lszz_offs = MAX( lszz_offs, elf_offs + phdr[i].p_offset + phdr[i].p_filesz ); | ||||
| 		if( !s ) | ||||
| 			continue; | ||||
| 		if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) | ||||
| 			fatal_error("Claim failed!\n"); | ||||
|  | ||||
| 		addr = (char*)phdr[i].p_vaddr; | ||||
| 		if( read_io(fd, addr, s) != s ) | ||||
| 			fatal_error("read failed\n"); | ||||
|  | ||||
| #if 0 | ||||
| 		/* patch CODE segment */ | ||||
| 		if( *entry >= phdr[i].p_vaddr && *entry < phdr[i].p_vaddr + s ) { | ||||
| 			patch_newworld_rom( (char*)phdr[i].p_vaddr, s ); | ||||
| 			newworld_timer_hack( (char*)phdr[i].p_vaddr, s ); | ||||
| 		} | ||||
| #endif | ||||
| 		flush_icache_range( addr, addr+s ); | ||||
|  | ||||
| 		/*printk("ELF ROM-section loaded at %08lX (size %08lX)\n",  | ||||
| 		   (ulong)phdr[i].p_vaddr, (ulong)phdr[i].p_memsz );*/ | ||||
| 	} | ||||
| 	free( phdr ); | ||||
| 	return lszz_offs; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| encode_bootpath( const char *spec, const char *args ) | ||||
| { | ||||
| 	phandle_t chosen_ph = find_dev("/chosen"); | ||||
| 	set_property( chosen_ph, "bootpath", spec, strlen(spec)+1 );	 | ||||
| 	set_property( chosen_ph, "bootargs", args, strlen(args)+1 );	 | ||||
| } | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	briq booting							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static void | ||||
| briq_startup( void ) | ||||
| { | ||||
| 	const char *paths[] = { "hd:0,\\zImage.chrp", NULL }; | ||||
| 	const char *args[] = { "root=/dev/hda2 console=ttyS0,115200", NULL }; | ||||
| 	ulong entry; | ||||
| 	int i, fd; | ||||
|  | ||||
| 	for( i=0; paths[i]; i++ ) { | ||||
| 		if( (fd=open_io(paths[i])) == -1 ) | ||||
| 			continue; | ||||
| 		(void) load_elf_rom( &entry, fd ); | ||||
| 		close_io( fd ); | ||||
| 		encode_bootpath( paths[i], args[i] ); | ||||
|  | ||||
| 		update_nvram(); | ||||
| 		transfer_control_to_elf( entry ); | ||||
| 		/* won't come here */ | ||||
| 	} | ||||
| 	printk("*** Boot failure! No secondary bootloader specified ***\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	entry								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| void | ||||
| boot( void ) | ||||
| { | ||||
| 	fword("update-chosen"); | ||||
| 	briq_startup(); | ||||
| } | ||||
							
								
								
									
										333
									
								
								arch/ppc/briq/methods.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										333
									
								
								arch/ppc/briq/methods.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,333 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *    | ||||
|  *	<methods.c> | ||||
|  *	 | ||||
|  *	Misc device node methods | ||||
|  * | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  *    | ||||
|  *   Based on MOL specific code which is | ||||
|  *    | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "libc/string.h" | ||||
| #include "briq/briq.h" | ||||
| #include "ofmem.h" | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	RTAS (run-time abstraction services)				*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #ifdef USE_RTAS | ||||
| DECLARE_NODE( rtas, INSTALL_OPEN, 0, "+/rtas" ); | ||||
|  | ||||
| /* ( physbase -- rtas_callback ) */ | ||||
| static void | ||||
| rtas_instantiate( void ) | ||||
| { | ||||
| 	int physbase = POP(); | ||||
| 	int s=0x1000, size = (int)of_rtas_end - (int)of_rtas_start; | ||||
| 	ulong virt; | ||||
| 	 | ||||
| 	while( s < size ) | ||||
| 		s += 0x1000; | ||||
| 	virt = ofmem_claim_virt( 0, s, 0x1000 ); | ||||
| 	ofmem_map( physbase, virt, s, -1 ); | ||||
| 	memcpy( (char*)virt, of_rtas_start, size ); | ||||
|  | ||||
| 	printk("RTAS instantiated at %08x\n", physbase ); | ||||
| 	flush_icache_range( (char*)virt, (char*)virt + size ); | ||||
|  | ||||
| 	PUSH( physbase ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( rtas ) = { | ||||
| 	{ "instantiate",	rtas_instantiate }, | ||||
| 	{ "instantiate-rtas",	rtas_instantiate }, | ||||
| }; | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	stdout								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( vfd_stdout, INSTALL_OPEN, 0, "Tdisplay" ); | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| stdout_write( void ) | ||||
| { | ||||
| 	int len = POP(); | ||||
| 	char *addr = (char*)POP(); | ||||
| 	char *s = malloc( len + 1 ); | ||||
|  | ||||
| 	strncpy_nopad( s, addr, len ); | ||||
| 	s[len]=0; | ||||
| 	 | ||||
| 	printk( "%s", s ); | ||||
| 	//vfd_draw_str( s ); | ||||
| 	free( s ); | ||||
|  | ||||
| 	PUSH( len ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( vfd_stdout ) = { | ||||
| 	{ "write",	stdout_write	}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	tty								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( tty, INSTALL_OPEN, 0, "/packages/terminal-emulator" ); | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| tty_read( void ) | ||||
| { | ||||
| 	int ch, len = POP(); | ||||
| 	char *p = (char*)POP(); | ||||
| 	int ret=0; | ||||
|  | ||||
| 	if( len > 0 ) { | ||||
| 		ret = 1; | ||||
| 		ch = getchar(); | ||||
| 		if( ch >= 0 ) { | ||||
| 			*p = ch; | ||||
| 		} else { | ||||
| 			ret = 0; | ||||
| 		} | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| tty_write( void ) | ||||
| { | ||||
| 	int i, len = POP(); | ||||
| 	char *p = (char*)POP(); | ||||
| 	for( i=0; i<len; i++ ) | ||||
| 		putchar( *p++ ); | ||||
| 	RET( len ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( tty ) = { | ||||
| 	{ "read",	tty_read	}, | ||||
| 	{ "write",	tty_write	}, | ||||
| }; | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	client interface 'quiesce'					*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( ciface, 0, 0, "/packages/client-iface" ); | ||||
|  | ||||
| /* ( -- ) */ | ||||
| static void | ||||
| ciface_quiesce( ulong args[], ulong ret[] )  | ||||
| { | ||||
| #if 0 | ||||
| 	ulong msr; | ||||
| 	/* This seems to be the correct thing to do - but I'm not sure */ | ||||
| 	asm volatile("mfmsr %0" : "=r" (msr) : ); | ||||
| 	msr &= ~(MSR_IR | MSR_DR); | ||||
| 	asm volatile("mtmsr %0" :: "r" (msr) ); | ||||
| #endif | ||||
| 	printk("=============================================================\n\n"); | ||||
| } | ||||
|  | ||||
| /* ( -- ms ) */ | ||||
| static void | ||||
| ciface_milliseconds( ulong args[], ulong ret[] )  | ||||
| { | ||||
| 	extern unsigned long get_timer_freq(); | ||||
| 	static ulong mticks=0, usecs=0; | ||||
| 	ulong t; | ||||
|          | ||||
| 	asm volatile("mftb %0" : "=r" (t) : ); | ||||
| 	if( mticks ) | ||||
| 		usecs += get_timer_freq() / 1000000 * ( t-mticks ); | ||||
| 	mticks = t; | ||||
|  | ||||
| 	PUSH( usecs/1000 ); | ||||
| } | ||||
|  | ||||
|  | ||||
| NODE_METHODS( ciface ) = { | ||||
| 	{ "quiesce",		ciface_quiesce		}, | ||||
| 	{ "milliseconds",	ciface_milliseconds	}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	MMU/memory methods						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( memory, INSTALL_OPEN, 0, "/memory" ); | ||||
| DECLARE_NODE( mmu, INSTALL_OPEN, 0, "/cpu@0" ); | ||||
| DECLARE_NODE( mmu_ciface, 0, 0, "/packages/client-iface" ); | ||||
|  | ||||
|  | ||||
| /* ( phys size align --- base ) */ | ||||
| static void | ||||
| mem_claim( void ) | ||||
| { | ||||
| 	int align = POP(); | ||||
| 	int size = POP(); | ||||
| 	int phys = POP(); | ||||
| 	int ret = ofmem_claim_phys( phys, size, align ); | ||||
| 	 | ||||
| 	if( ret == -1 ) { | ||||
| 		printk("MEM: claim failure\n"); | ||||
| 		throw( -13 ); | ||||
| 		return; | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( phys size --- ) */ | ||||
| static void | ||||
| mem_release( void ) | ||||
| { | ||||
| 	POP(); POP(); | ||||
| } | ||||
|  | ||||
| /* ( phys size align --- base ) */ | ||||
| static void | ||||
| mmu_claim( void ) | ||||
| { | ||||
| 	int align = POP(); | ||||
| 	int size = POP(); | ||||
| 	int phys = POP(); | ||||
| 	int ret = ofmem_claim_virt( phys, size, align ); | ||||
|  | ||||
| 	if( ret == -1 ) { | ||||
| 		printk("MMU: CLAIM failure\n"); | ||||
| 		throw( -13 ); | ||||
| 		return; | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( phys size --- ) */ | ||||
| static void | ||||
| mmu_release( void ) | ||||
| { | ||||
| 	POP(); POP(); | ||||
| } | ||||
|  | ||||
| /* ( phys virt size mode -- [ret???] ) */ | ||||
| static void  | ||||
| mmu_map( void ) | ||||
| { | ||||
| 	int mode = POP(); | ||||
| 	int size = POP(); | ||||
| 	int virt = POP(); | ||||
| 	int phys = POP(); | ||||
| 	int ret; | ||||
| 	 | ||||
| 	/* printk("mmu_map: %x %x %x %x\n", phys, virt, size, mode ); */ | ||||
| 	ret = ofmem_map( phys, virt, size, mode ); | ||||
|  | ||||
| 	if( ret ) { | ||||
| 		printk("MMU: map failure\n"); | ||||
| 		throw( -13 ); | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* ( virt size -- ) */ | ||||
| static void | ||||
| mmu_unmap( void ) | ||||
| { | ||||
| 	POP(); POP(); | ||||
| } | ||||
|  | ||||
| /* ( virt -- false | phys mode true ) */ | ||||
| static void | ||||
| mmu_translate( void ) | ||||
| { | ||||
| 	ulong mode; | ||||
| 	int virt = POP(); | ||||
| 	int phys = ofmem_translate( virt, &mode ); | ||||
|  | ||||
| 	if( phys == -1 ) { | ||||
| 		PUSH( 0 ); | ||||
| 	} else { | ||||
| 		PUSH( phys ); | ||||
| 		PUSH( (int)mode ); | ||||
| 		PUSH( -1 ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* ( virt size align -- baseaddr|-1 ) */ | ||||
| static void | ||||
| ciface_claim( void ) | ||||
| { | ||||
| 	int align = POP(); | ||||
| 	int size = POP(); | ||||
| 	int virt = POP(); | ||||
| 	int ret = ofmem_claim( virt, size, align ); | ||||
|  | ||||
| 	/* printk("ciface_claim: %08x %08x %x\n", virt, size, align ); */ | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( virt size -- ) */ | ||||
| static void | ||||
| ciface_release( void ) | ||||
| { | ||||
| 	POP(); | ||||
| 	POP(); | ||||
| } | ||||
|  | ||||
|  | ||||
| NODE_METHODS( memory ) = { | ||||
| 	{ "claim",		mem_claim		}, | ||||
| 	{ "release",		mem_release		}, | ||||
| }; | ||||
|  | ||||
| NODE_METHODS( mmu ) = { | ||||
| 	{ "claim",		mmu_claim		}, | ||||
| 	{ "release",		mmu_release		}, | ||||
| 	{ "map",		mmu_map			}, | ||||
| 	{ "unmap",		mmu_unmap		}, | ||||
| 	{ "translate",		mmu_translate		}, | ||||
| }; | ||||
|  | ||||
| NODE_METHODS( mmu_ciface ) = { | ||||
| 	{ "claim",		ciface_claim		}, | ||||
| 	{ "release",		ciface_release		}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	init								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| void | ||||
| node_methods_init( void ) | ||||
| { | ||||
| #ifdef USE_RTAS | ||||
| 	REGISTER_NODE( rtas ); | ||||
| #endif | ||||
| 	REGISTER_NODE( vfd_stdout ); | ||||
| 	REGISTER_NODE( ciface ); | ||||
| 	REGISTER_NODE( memory ); | ||||
| 	REGISTER_NODE( mmu ); | ||||
| 	REGISTER_NODE( mmu_ciface ); | ||||
| 	REGISTER_NODE( tty ); | ||||
| } | ||||
							
								
								
									
										23
									
								
								arch/ppc/briq/tree.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								arch/ppc/briq/tree.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *  | ||||
|  *	<tree.c> | ||||
|  *	 | ||||
|  *	device tree setup | ||||
|  *    | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
|  | ||||
| void devtree_init( void ) | ||||
| { | ||||
| 	fword("init-briq-tree"); | ||||
| } | ||||
							
								
								
									
										247
									
								
								arch/ppc/briq/tree.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								arch/ppc/briq/tree.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,247 @@ | ||||
| \   briq specific initialization code | ||||
| \  | ||||
| \   Copyright (C) 2004 Greg Watson | ||||
| \  | ||||
| \   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 | ||||
| \  | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ device-tree | ||||
| \ ------------------------------------------------------------- | ||||
|  | ||||
| " /" find-device | ||||
|  | ||||
| " chrp" device-type | ||||
| " TotalImpact,BRIQ-1" model | ||||
| h# 80000000 encode-int " isa-io-base" property | ||||
| 1 encode-int " #interrupt-cells" property | ||||
| 1 encode-int " #size-cells" property | ||||
|  | ||||
| new-device | ||||
| 	" memory" device-name | ||||
| 	" memory" device-type | ||||
| 	0 encode-int h# 1E00000 encode-int encode+ | ||||
| 	h# 2000000 encode-int encode+ h# 40000000 encode-int encode+  | ||||
| 	  " available" property | ||||
| 	0 h# 40000000 reg | ||||
| 	external | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
| 	" cpu" device-name | ||||
| 	" cpu" device-type | ||||
| 	" " encode-string " translations" property | ||||
| 	0 encode-phys h# 8000000 encode-int encode+ " available" property | ||||
| 	d# 32 encode-int " d-cache-block-size" property | ||||
| 	8 encode-int " d-cache-sets" property | ||||
| 	d# 32768 encode-int " d-cache-size" property | ||||
| 	d# 32 encode-int " i-cache-block-size" property | ||||
| 	8 encode-int " i-cache-sets" property | ||||
| 	d# 32768 encode-int " i-cache-size" property | ||||
| 	" " encode-string " cache-unified" property | ||||
| 	2 encode-int " i-tlb-sets" property | ||||
| 	d# 128 encode-int " i-tlb-size" property | ||||
| 	2 encode-int " d-tlb-sets" property | ||||
| 	d# 128 encode-int " d-tlb-size" property | ||||
| 	" " encode-string " tlb-split" property | ||||
| 	2 encode-int " tlb-sets" property | ||||
| 	d# 256 encode-int " tlb-size" property | ||||
| 	" " encode-string " performance-monitor" property | ||||
| 	" " encode-string " graphics" property | ||||
| 	4 encode-int " reservation-granule-size" property | ||||
|         d# 25000000 encode-int " timebase-frequency" property | ||||
|         d# 300000000 encode-int " clock-frequency" property | ||||
|         d# 66000000 encode-int " bus-frequency" property | ||||
|         h# 88201 encode-int " cpu-version" property | ||||
| 	0 encode-int " reg" property | ||||
| finish-device | ||||
|  | ||||
| " /pci" find-device | ||||
| 	h# 01000000 encode-int 0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 80000000 encode-int encode+ 0 encode-int encode+  | ||||
| 	  h# 01000000 encode-int encode+  | ||||
| 	h# 02000000 encode-int encode+ 0 encode-int encode+ 0 encode-int encode+  | ||||
| 	  h# C0000000 encode-int encode+ 0 encode-int encode+  | ||||
| 	  h# 08000000 encode-int encode+  | ||||
| 	" ranges" property | ||||
| 	" IBM,CPC710" model | ||||
| 	h# FF5F7700 encode-int " 8259-interrupt-acknowledge" property | ||||
| 	h# 0000F800 encode-int 0 encode-int encode+ 0 encode-int encode+  | ||||
| 	  7 encode-int encode+ | ||||
| 	  " interrupt-map-mask" property | ||||
| 	1 encode-int " #interrupt-cells" property | ||||
| 	h# 80000000 encode-int " system-dma-base" property | ||||
| 	d# 33333333 encode-int " clock-frequency" property | ||||
| 	" " encode-string " primary-bridge" property | ||||
| 	0 encode-int " pci-bridge-number" property | ||||
| 	h# FF500000 encode-int h# 100000 encode-int encode+ " reg" property | ||||
| 	0 encode-int 0 encode-int encode+ " bus-range" property | ||||
|  | ||||
| new-device | ||||
| 	" ide" device-name | ||||
| 	" ide" device-type | ||||
| 	" WINBOND,82C553" model | ||||
| 	h# 28 encode-int " max-latency" property | ||||
| 	h# 2 encode-int " min-grant" property | ||||
| 	h# 1 encode-int " devsel-speed" property | ||||
| 	h# 0 encode-int " subsystem-vendor-id" property | ||||
| 	h# 0 encode-int " subsystem-id" property | ||||
| 	h# 1018A encode-int " class-code" property | ||||
| 	h# 5 encode-int " revision-id" property | ||||
| 	h# 105 encode-int " device-id" property | ||||
| 	h# 10AD encode-int " vendor-id" property | ||||
| 	h# 1003110 encode-int 0 encode-int encode+ h# 10020 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003114 encode-int 0 encode-int encode+ h# 10030 encode-int encode+ | ||||
| 	  h# 4 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003118 encode-int 0 encode-int encode+ h# 10040 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 100311C encode-int 0 encode-int encode+ h# 10034 encode-int encode+ | ||||
| 	  h# 4 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003120 encode-int 0 encode-int encode+ h# 10050 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003124 encode-int 0 encode-int encode+ h# 10060 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  " assigned-addresses" property | ||||
| 	h# 3100 encode-int 0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003110 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003114 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 4 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003118 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 100311C encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 4 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003120 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003124 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  " reg" property | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
| 	" ethernet" device-name | ||||
| 	" network" device-type | ||||
| 	" AMD,79C973" model | ||||
| 	h# 3800 encode-int 0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  " reg" property | ||||
| finish-device | ||||
|  | ||||
| " /pci/isa" find-device | ||||
| 	0 0 " assigned-addresses" property | ||||
| 	0 0 " ranges" property | ||||
| 	0 encode-int " slot-names" property | ||||
| 	d# 8333333 encode-int " clock-frequency" property | ||||
| 	0 encode-int " eisa-slots" property | ||||
| 	2 encode-int " #interrupt-cells" property | ||||
| 	" W83C553F" encode-string " compatible" property | ||||
| 	" WINBOND,82C553" model | ||||
| 	0 encode-int " max-latency" property | ||||
| 	0 encode-int " min-grant" property | ||||
| 	1 encode-int " devsel-speed" property | ||||
| 	0 encode-int " subsystem-vendor-id" property | ||||
| 	0 encode-int " subsystem-id" property | ||||
| 	h# 60100 encode-int " class-code" property | ||||
| 	h# 10 encode-int " revision-id" property | ||||
| 	h# 565 encode-int " device-id" property | ||||
| 	h# 10AD encode-int " vendor-id" property | ||||
| 	h# 3000 encode-int 0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  0 encode-int encode+ 0 encode-int encode+ " reg" property | ||||
|  | ||||
| new-device | ||||
| 	" rtc" device-name | ||||
| 	" rtc" device-type | ||||
| 	" DS17285S" model | ||||
| 	" MC146818" encode-string | ||||
| 	" DS17285S" encode-string encode+ | ||||
| 	" pnpPNP,b00" encode-string encode+ " compatible" property | ||||
| 	8 encode-int 0 encode-int encode+ " interrupts" property | ||||
| 	h# 70 encode-int 1 encode-int encode+ | ||||
| 	  2 encode-int encode+ " reg" property | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
| 	" interrupt-controller" device-name | ||||
| 	" interrupt-controller" device-type | ||||
| 	" 8259" model | ||||
| 	" " encode-string " interrupt-controller" property | ||||
| 	2 encode-int " #interrupt-cells" property | ||||
| 	1 encode-int  | ||||
| 	2 encode-int encode+ | ||||
| 	3 encode-int encode+ | ||||
| 	6 encode-int encode+ | ||||
| 	  " reserved-interrupts" property | ||||
| 	" 8259" encode-string | ||||
| 	  " chrp,iic" encode-string encode+  | ||||
| 	  " compatible" property | ||||
| 	h# 20 encode-int 1 encode-int encode+ | ||||
| 	  2 encode-int encode+ " reg" property | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
| 	" serial" device-name | ||||
| 	" serial" device-type | ||||
| 	" no" encode-string " ctsrts" property | ||||
| 	" no" encode-string " xon" property | ||||
| 	" no" encode-string " parity" property | ||||
| 	d# 115200 encode-int " bps" property | ||||
| 	1 encode-int " stop-bits" property | ||||
| 	8 encode-int " data-bits" property | ||||
| 	h# 70800 encode-int " divisor" property | ||||
| 	h# 708000 encode-int " clock-frequency" property | ||||
| 	4 encode-int 0 encode-int encode+ " interrupts" property | ||||
| 	h# 3F8 encode-int 1 encode-int encode+ | ||||
| 	  8 encode-int encode+ " reg" property | ||||
| finish-device | ||||
|  | ||||
| " /pci" find-device | ||||
| 	" /pci/isa/interrupt-controller" find-dev if  | ||||
| 		encode-int " interrupt-parent" property  | ||||
| 	then | ||||
| 	h# 3800 encode-int 0 encode-int encode+  | ||||
| 	  0 encode-int encode+ 1 encode-int encode+ | ||||
| 	  " /pci/isa/interrupt-controller" find-dev if  | ||||
| 		encode-int encode+ | ||||
| 	  then | ||||
| 	  h# 0C encode-int encode+ 1 encode-int encode+ | ||||
| 	  " interrupt-map" property | ||||
|  | ||||
| " /pci/isa" find-device | ||||
| 	" /pci/isa/interrupt-controller" find-dev if  | ||||
| 		encode-int " interrupt-parent" property  | ||||
| 	then | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ /packages | ||||
| \ ------------------------------------------------------------- | ||||
|  | ||||
| " /packages" find-device | ||||
|  | ||||
| 	" packages" device-name | ||||
| 	external | ||||
| 	\ allow packages to be opened with open-dev | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
|  | ||||
| \ /packages/terminal-emulator | ||||
| new-device | ||||
| 	" terminal-emulator" device-name | ||||
| 	external | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
| 	\ : write ( addr len -- actual ) | ||||
| 	\	dup -rot type | ||||
| 	\ ; | ||||
| finish-device | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ The END | ||||
| \ ------------------------------------------------------------- | ||||
| device-end | ||||
|  | ||||
							
								
								
									
										42
									
								
								arch/ppc/briq/vfd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								arch/ppc/briq/vfd.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 17:29:43 greg> | ||||
|  *   Time-stamp: <2004/08/28 17:29:43 greg> | ||||
|  *    | ||||
|  *	<vfd.c> | ||||
|  *	 | ||||
|  *	Simple text console | ||||
|  *    | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "briq/briq.h" | ||||
|  | ||||
| static int vfd_is_open; | ||||
|  | ||||
| static int | ||||
| vfd_init( void )  | ||||
| { | ||||
| 	vfd_is_open = 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| vfd_close( void )  | ||||
| { | ||||
| } | ||||
|  | ||||
| int | ||||
| vfd_draw_str( const char *str ) | ||||
| { | ||||
| 	if (!vfd_is_open) | ||||
| 		vfd_init(); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										217
									
								
								arch/ppc/build.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								arch/ppc/build.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,217 @@ | ||||
| <?xml version="1.0"?> | ||||
| <build condition="PPC"> | ||||
|  | ||||
|  <dictionary name="openbios-briq" init="openbios" target="forth" condition="BRIQ"> | ||||
|   <object source="ppc.fs"/> | ||||
|   <object source="briq/tree.fs"/> | ||||
|   <object source="briq/briq.fs"/> | ||||
|  </dictionary> | ||||
|   | ||||
|   <dictionary name="openbios-pearpc" init="openbios" target="forth" condition="PEARPC"> | ||||
|   <object source="ppc.fs"/> | ||||
|   <object source="pearpc/tree.fs"/> | ||||
|   <object source="pearpc/pearpc.fs"/> | ||||
|  </dictionary> | ||||
|   | ||||
|  <dictionary name="openbios-mol" init="openbios" target="forth" condition="MOL"> | ||||
|   <object source="ppc.fs"/> | ||||
|   <object source="mol/tree.fs"/> | ||||
|   <object source="mol/mol.fs"/> | ||||
|  </dictionary> | ||||
|   | ||||
|  <!-- HACK ALERT --> | ||||
|   | ||||
|  <executable name="target/include/briq-dict.h" target="target" condition="BRIQ"> | ||||
|   <rule><![CDATA[ | ||||
| 	@echo "static const char forth_dictionary[] = {" > $@ | ||||
| 	@cat $< | hexdump -ve '1/0 "\t" 8/1 "0x%02x, " 1/0 "\n"' \ | ||||
| 					| sed 's/0x  ,//g' >> $@ | ||||
| 	@echo "};" >> $@ | ||||
|   ]]></rule> | ||||
|   <external-object source="openbios-briq.dict"/> | ||||
|  </executable> | ||||
|   | ||||
|  <executable name="target/arch/ppc/briq/kernel.o" target="target" condition="BRIQ"> | ||||
|   <rule><![CDATA[ | ||||
| 	$(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ arch/ppc/briq/kernel.c | ||||
|   ]]></rule> | ||||
|   <external-object source="target/include/briq-dict.h"/> | ||||
|  </executable> | ||||
|   | ||||
|   | ||||
|  <executable name="target/include/pearpc-dict.h" target="target" condition="PEARPC"> | ||||
|   <rule><![CDATA[ | ||||
| 	@echo "static const char forth_dictionary[] = {" > $@ | ||||
| 	@cat $< | hexdump -ve '1/0 "\t" 8/1 "0x%02x, " 1/0 "\n"' \ | ||||
| 					| sed 's/0x  ,//g' >> $@ | ||||
| 	@echo "};" >> $@ | ||||
|   ]]></rule> | ||||
|   <external-object source="openbios-pearpc.dict"/> | ||||
|  </executable> | ||||
|   | ||||
|  <executable name="target/arch/ppc/pearpc/kernel.o" target="target" condition="PEARPC"> | ||||
|   <rule><![CDATA[ | ||||
| 	$(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ arch/ppc/pearpc/kernel.c | ||||
|   ]]></rule> | ||||
|   <external-object source="target/include/pearpc-dict.h"/> | ||||
|  </executable> | ||||
|  | ||||
|   | ||||
|  <executable name="target/include/mol-dict.h" target="target" condition="MOL"> | ||||
|   <rule><![CDATA[ | ||||
| 	@echo "static const char forth_dictionary[] = {" > $@ | ||||
| 	@cat $< | hexdump -ve '1/0 "\t" 8/1 "0x%02x, " 1/0 "\n"' \ | ||||
| 					| sed 's/0x  ,//g' >> $@ | ||||
| 	@echo "};" >> $@ | ||||
|   ]]></rule> | ||||
|   <external-object source="openbios-mol.dict"/> | ||||
|  </executable> | ||||
|   | ||||
|  <executable name="target/arch/ppc/mol/kernel.o" target="target" condition="MOL"> | ||||
|   <rule><![CDATA[ | ||||
| 	$(CC) $$EXTRACFLAGS $(CFLAGS) $(INCLUDES) -c -o $@ arch/ppc/mol/kernel.c | ||||
|   ]]></rule> | ||||
|   <external-object source="target/include/mol-dict.h"/> | ||||
|  </executable> | ||||
|   | ||||
|  <!-- END OF HACK ALERT --> | ||||
|   | ||||
|  <library name="briq" target="target" type="static" condition="BRIQ"> | ||||
|   <object source="misc.S"> | ||||
|    <rule><![CDATA[ | ||||
| 	$(CPP) -D__ASSEMBLY__ $(INCLUDES) $< | $(M4) -s $(M4_NO_GNU) | tr ';' '\n' > $@.s | ||||
| 	$(AS) $@.s $(AS_FLAGS) -o $@ | ||||
|    ]]></rule> | ||||
|   </object> | ||||
|   <object source="ofmem.c"/> | ||||
|   <object source="briq/briq.c" flags="-Iarch/ppc"/> | ||||
|   <object source="briq/init.c" flags="-Iarch/ppc"/> | ||||
|   <external-object source="target/arch/ppc/briq/kernel.o"/> | ||||
|   <object source="briq/main.c" flags="-Iarch/ppc"/> | ||||
|   <object source="briq/methods.c" flags="-Iarch/ppc"/> | ||||
|   <object source="briq/tree.c" flags="-Iarch/ppc"/> | ||||
|   <object source="briq/vfd.c" flags="-Iarch/ppc"/> | ||||
|  </library> | ||||
|   | ||||
|  <library name="pearpc" target="target" type="static" condition="PEARPC"> | ||||
|   <object source="misc.S"> | ||||
|    <rule><![CDATA[ | ||||
| 	$(CPP) -D__ASSEMBLY__ $(INCLUDES) $< | $(M4) -s $(M4_NO_GNU) | tr ';' '\n' > $@.s | ||||
| 	$(AS) $@.s $(AS_FLAGS) -o $@ | ||||
|    ]]></rule> | ||||
|   </object> | ||||
|   <object source="ofmem.c"/> | ||||
|   <object source="pearpc/pearpc.c" flags="-Iarch/ppc"/> | ||||
|   <object source="pearpc/init.c" flags="-Iarch/ppc"/> | ||||
|   <external-object source="target/arch/ppc/pearpc/kernel.o"/> | ||||
|   <object source="pearpc/main.c" flags="-Iarch/ppc"/> | ||||
|   <object source="pearpc/methods.c" flags="-Iarch/ppc"/> | ||||
|   <object source="pearpc/tree.c" flags="-Iarch/ppc"/> | ||||
|   <object source="pearpc/vfd.c" flags="-Iarch/ppc"/> | ||||
|   <!-- taken from mol: generalize --> | ||||
|   <object source="pearpc/console.c" flags="-Iarch/ppc"/> | ||||
|  </library> | ||||
|   | ||||
|   | ||||
|  <library name="mol" target="target" type="static" condition="MOL"> | ||||
|   <object source="misc.S"> | ||||
|    <rule><![CDATA[ | ||||
| 	$(CPP) -D__ASSEMBLY__ $(INCLUDES) $< | $(M4) -s $(M4_NO_GNU) | tr ';' '\n' > $@.s | ||||
| 	$(AS) $@.s $(AS_FLAGS) -o $@ | ||||
|    ]]></rule> | ||||
|   </object> | ||||
|   <object source="ofmem.c"/> | ||||
|   <object source="mol/init.c" flags="-Iarch/ppc"/> | ||||
|   <object source="mol/main.c" flags="-Iarch/ppc"/> | ||||
|   <object source="mol/mol.c" flags="-Iarch/ppc"/> | ||||
|   <object source="mol/console.c" flags="-Iarch/ppc"/> | ||||
|   <object source="mol/osi-blk.c" flags="-Iarch/ppc"/> | ||||
|   <object source="mol/osi-scsi.c" flags="-Iarch/ppc"/> | ||||
|   <object source="mol/pseudodisk.c" flags="-Iarch/ppc"/> | ||||
|   <object source="mol/methods.c" flags="-Iarch/ppc"/> | ||||
|   <object source="mol/prom.c" flags="-Iarch/ppc"/> | ||||
|   <object source="mol/tree.c" flags="-Iarch/ppc"/> | ||||
|   <external-object source="target/arch/ppc/mol/kernel.o"/> | ||||
|  </library> | ||||
|   | ||||
|  <executable name="openbios-briq.elf" target="target" condition="BRIQ"> | ||||
|   <rule> | ||||
| 	$(LD) -g -Ttext=0x01e01000 -Bstatic $^ $(shell $(CC) -print-libgcc-file-name) -o $@ | ||||
| 	$(NM) $@ | sort > $(ODIR)/openbios-briq.syms | ||||
| 	cp $@ $@.nostrip | ||||
| 	$(STRIP) $@ | ||||
|   </rule> | ||||
|   <object source="start.S"> | ||||
|    <rule><![CDATA[ | ||||
| 	$(CPP) -D__ASSEMBLY__ $(INCLUDES) $< | $(M4) -s $(M4_NO_GNU) | tr ';' '\n' > $@.s | ||||
| 	$(AS) $@.s $(AS_FLAGS) -o $@ | ||||
|    ]]></rule> | ||||
|   </object> | ||||
|   <object source="timebase.S"> | ||||
|    <rule><![CDATA[ | ||||
| 	$(CPP) -D__ASSEMBLY__ $(INCLUDES) $< | $(M4) -s $(M4_NO_GNU) | tr ';' '\n' > $@.s | ||||
| 	$(AS) $@.s $(AS_FLAGS) -o $@ | ||||
|    ]]></rule> | ||||
|   </object> | ||||
|   <external-object source="libbriq.a"/> | ||||
|   <external-object source="libbootstrap.a"/> | ||||
|   <external-object source="libmodules.a"/> | ||||
|   <external-object source="libdrivers.a"/> | ||||
|   <external-object source="liblibc.a"/> | ||||
|   <external-object source="libfs.a"/> | ||||
|  </executable> | ||||
|   | ||||
|   | ||||
|  <executable name="openbios-pearpc.elf" target="target" condition="PEARPC"> | ||||
|   <rule> | ||||
| 	$(LD) -g -Ttext=0x01e01000 -Bstatic $^ $(shell $(CC) -print-libgcc-file-name) -o $@ | ||||
| 	$(NM) $@ | sort > $(ODIR)/openbios-pearpc.syms | ||||
| 	cp $@ $@.nostrip | ||||
| 	$(STRIP) $@ | ||||
|   </rule> | ||||
|   <object source="start.S"> | ||||
|    <rule><![CDATA[ | ||||
| 	$(CPP) -D__ASSEMBLY__ $(INCLUDES) $< | $(M4) -s $(M4_NO_GNU) | tr ';' '\n' > $@.s | ||||
| 	$(AS) $@.s $(AS_FLAGS) -o $@ | ||||
|    ]]></rule> | ||||
|   </object> | ||||
|   <object source="timebase.S"> | ||||
|    <rule><![CDATA[ | ||||
| 	$(CPP) -D__ASSEMBLY__ $(INCLUDES) $< | $(M4) -s $(M4_NO_GNU) | tr ';' '\n' > $@.s | ||||
| 	$(AS) $@.s $(AS_FLAGS) -o $@ | ||||
|    ]]></rule> | ||||
|   </object> | ||||
|   <external-object source="libpearpc.a"/> | ||||
|   <external-object source="libbootstrap.a"/> | ||||
|   <external-object source="libmodules.a"/> | ||||
|   <external-object source="libdrivers.a"/> | ||||
|   <external-object source="liblibc.a"/> | ||||
|   <external-object source="libfs.a"/> | ||||
|  </executable> | ||||
|   | ||||
|  | ||||
|   | ||||
|  <executable name="openbios-mol.elf" target="target" condition="MOL"> | ||||
|   <rule> | ||||
| 	$(LD) -g -Ttext=0x01e01000 -Bstatic $^ $(shell $(CC) -print-libgcc-file-name) -o $@ | ||||
| 	$(NM) $@ | sort > $(ODIR)/openbios-mol.syms | ||||
| 	cp $@ $@.nostrip | ||||
| 	$(STRIP) $@ | ||||
|  | ||||
|   </rule> | ||||
|   <object source="start.S"> | ||||
|    <rule><![CDATA[ | ||||
| 	$(CPP) -D__ASSEMBLY__ $(INCLUDES) $< | $(M4) -s $(M4_NO_GNU) | tr ';' '\n' > $@.s | ||||
| 	$(AS) $@.s $(AS_FLAGS) -o $@ | ||||
|    ]]></rule> | ||||
|   </object> | ||||
|   <external-object source="libmol.a"/> | ||||
|   <external-object source="libbootstrap.a"/> | ||||
|   <external-object source="libmodules.a"/> | ||||
|   <external-object source="libdrivers.a"/> | ||||
|   <external-object source="liblibc.a"/> | ||||
|   <external-object source="libfs.a"/> | ||||
|  </executable> | ||||
|   | ||||
| </build> | ||||
|  | ||||
							
								
								
									
										48
									
								
								arch/ppc/defconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								arch/ppc/defconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| # | ||||
| # Automatically generated make config: don't edit | ||||
| # | ||||
| CONFIG_PPC=y | ||||
| CONFIG_MOL=y | ||||
| # CONFIG_MPC107 is not set | ||||
| # CONFIG_NO_ARCH is not set | ||||
|  | ||||
| # | ||||
| # Build hosted UNIX Binary | ||||
| # | ||||
| CONFIG_HOST_UNIX=y | ||||
| # CONFIG_PLUGIN_PCI is not set | ||||
|  | ||||
| # | ||||
| # Kernel Debugging | ||||
| # | ||||
| CONFIG_DEBUG=y | ||||
| CONFIG_DEBUG_BOOT=y | ||||
| # CONFIG_DEBUG_DSTACK is not set | ||||
| # CONFIG_DEBUG_RSTACK is not set | ||||
| # CONFIG_DEBUG_DICTIONARY is not set | ||||
| # CONFIG_DEBUG_INTERNAL is not set | ||||
| # CONFIG_DEBUG_INTERPRETER is not set | ||||
| CONFIG_DEBUG_CONSOLE=y | ||||
| CONFIG_DEBUG_CONSOLE_SERIAL=y | ||||
| CONFIG_SERIAL_PORT=1 | ||||
| CONFIG_SERIAL_SPEED=115200 | ||||
| CONFIG_DEBUG_CONSOLE_VGA=y | ||||
|  | ||||
| # | ||||
| # Packages | ||||
| # | ||||
| # CONFIG_PKG_DEBLOCKER is not set | ||||
| # CONFIG_PKG_DISKLABEL is not set | ||||
| # CONFIG_PKG_OBP_TFTP is not set | ||||
| # CONFIG_PKG_TERMINAL_EMULATOR is not set | ||||
|  | ||||
| # | ||||
| # Module Configuration | ||||
| # | ||||
| CONFIG_DEBLOCKER=y | ||||
| CONFIG_DISK_LABEL=y | ||||
| CONFIG_PART_SUPPORT=y | ||||
| CONFIG_MAC_PARTS=y | ||||
| CONFIG_FS=y | ||||
| CONFIG_HFS=y | ||||
| CONFIG_HFSP=y | ||||
							
								
								
									
										106
									
								
								arch/ppc/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								arch/ppc/kernel.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2003/10/25 14:07:17 samuel> | ||||
|  *   Time-stamp: <2004/08/28 17:48:19 stepan> | ||||
|  *    | ||||
|  *	<kernel.c> | ||||
|  *	 | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *   Copyright (C) 2003, 2004 Stefan Reinauer | ||||
|  *    | ||||
|  *   Based upon unix.c (from OpenBIOS): | ||||
|  * | ||||
|  *   Copyright (C) 2003 Patrick Mauritz, Stefan Reinauer | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "dict.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "openbios/stack.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "libc/string.h" | ||||
| #include "kernel.h" | ||||
|  | ||||
| #define MEMORY_SIZE	(256*1024)	/* 256K ram for hosted system */ | ||||
| #define DICTIONARY_SIZE	(512*1024)	/* 128K for the dictionary   */ | ||||
|  | ||||
| extern unsigned char 	*dict; | ||||
| extern cell 		dicthead; | ||||
| static ucell 		*memory; | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	F U N C T I O N S						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| void | ||||
| exception( int errcode ) | ||||
| { | ||||
| 	/* no-op */ | ||||
| } | ||||
|  | ||||
| int | ||||
| forth_segv_handler( char *segv_addr ) | ||||
| { | ||||
| 	ucell addr = 0xdeadbeef; | ||||
|  | ||||
| 	if( PC >= (ucell) dict && PC <= (ucell) dict + dicthead ) | ||||
| 		addr = *(ucell *) PC; | ||||
|  | ||||
| 	printk("panic: segmentation violation at %x\n", (int)segv_addr); | ||||
| 	printk("dict=0x%x here=0x%x(dict+0x%x) pc=0x%x(dict+0x%x)\n", | ||||
| 	       (int)dict, (int)(dict + dicthead), dicthead,  | ||||
| 	       PC, PC - (ucell) dict); | ||||
| 	printk("dstackcnt=%d rstackcnt=%d instruction=%x\n", | ||||
| 	       dstackcnt, rstackcnt, addr); | ||||
|  | ||||
| #ifdef DEBUG_DSTACK | ||||
| 	printdstack(); | ||||
| #endif | ||||
| #ifdef DEBUG_RSTACK | ||||
| 	printrstack(); | ||||
| #endif | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| /*  | ||||
|  * allocate memory and prepare engine for memory management. | ||||
|  */ | ||||
|  | ||||
| static void | ||||
| init_memory( void ) | ||||
| { | ||||
| 	memory = malloc(MEMORY_SIZE); | ||||
| 	if( !memory ) | ||||
| 		panic("panic: not enough memory on host system.\n"); | ||||
|  | ||||
| 	/* we push start and end of memory to the stack | ||||
| 	 * so that it can be used by the forth word QUIT | ||||
| 	 * to initialize the memory allocator | ||||
| 	 */ | ||||
|  | ||||
| 	PUSH( (ucell)memory ); | ||||
| 	PUSH( (ucell)memory + MEMORY_SIZE ); | ||||
| } | ||||
|  | ||||
| int | ||||
| initialize_forth( void ) | ||||
| { | ||||
| 	dict = malloc(DICTIONARY_SIZE); | ||||
| 	load_dictionary( forth_dictionary, sizeof(forth_dictionary) ); | ||||
|  | ||||
| 	PUSH_xt( bind_noname_func(arch_of_init) ); | ||||
| 	fword("PREPOST-initializer"); | ||||
|  | ||||
| 	PC = (ucell)findword("initialize-of"); | ||||
| 	if( PC ) { | ||||
| 		init_memory(); | ||||
| 		enterforth((xt_t)PC); | ||||
| 		free( memory ); | ||||
| 	} | ||||
| 	free( dict ); | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										41
									
								
								arch/ppc/kernel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								arch/ppc/kernel.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 17:50:12 stepan> | ||||
|  *   Time-stamp: <2004/08/28 17:50:12 stepan> | ||||
|  *    | ||||
|  *	<kernel.h> | ||||
|  *    | ||||
|  *   Copyright (C) 2004 Stefan Reinauer | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #ifndef __KERNEL_H__ | ||||
| #define __KERNEL_H__ | ||||
|  | ||||
| /* misc.c */ | ||||
| extern void		fatal_error( const char *str ); | ||||
| extern void		exit( int status ); | ||||
|  | ||||
| /* start.S */ | ||||
| extern void 		flush_icache_range( char *start, char *stop ); | ||||
| extern char		of_rtas_start[], of_rtas_end[]; | ||||
|  | ||||
| /* methods.c */ | ||||
| extern void		node_methods_init( void ); | ||||
|  | ||||
| /* main.c */ | ||||
| extern void 		boot( void ); | ||||
|  | ||||
| /* init.c */ | ||||
| extern void		entry( void ); | ||||
| extern void 		arch_of_init( void ); | ||||
| extern int		get_bool_res( const char *str ); | ||||
|  | ||||
| /* tree.c */ | ||||
| extern void		devtree_init( void ); | ||||
|  | ||||
|  | ||||
| #endif   /* __KERNEL_H__ */ | ||||
							
								
								
									
										76
									
								
								arch/ppc/misc.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								arch/ppc/misc.S
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2002/10/20 15:54:50 samuel> | ||||
|  *   Time-stamp: <2002/10/20 15:57:21 samuel> | ||||
|  *    | ||||
|  *	<misc.S> | ||||
|  *	 | ||||
|  *	Low-level stuff | ||||
|  *    | ||||
|  *   Copyright (C) 2002, 2003 Samuel Rydh (samuel@ibrium.se) | ||||
|  * | ||||
|  *   Based upon misc.S from the the linux kernel with the following | ||||
|  *   copyrights: | ||||
|  * | ||||
|  *   Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org), | ||||
|  *   Cort Dougan (cort@cs.nmt.edu), Paul Mackerras | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| changequote([[[[[,]]]]]) [[[[[  /* shield includes from m4-expansion */ | ||||
| #include "asm/asmdefs.h" | ||||
| #include "asm/processor.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Extended precision shifts. | ||||
|  *  | ||||
|  * Updated to be valid for shift counts from 0 to 63 inclusive. | ||||
|  * -- Gabriel | ||||
|  * | ||||
|  * R3/R4 has 64 bit value | ||||
|  * R5    has shift count | ||||
|  * result in R3/R4 | ||||
|  * | ||||
|  *  ashrdi3: arithmetic right shift (sign propagation)	     | ||||
|  *  lshrdi3: logical right shift	 | ||||
|  *  ashldi3: left shift | ||||
|  */ | ||||
| GLOBL(__ashrdi3):	 | ||||
| 	subfic	r6,r5,32	 | ||||
| 	srw	r4,r4,r5	# LSW = count > 31 ? 0 : LSW >> count | ||||
| 	addi	r7,r5,32	# could be xori, or addi with -32 | ||||
| 	slw	r6,r3,r6	# t1 = count > 31 ? 0 : MSW << (32-count) | ||||
| 	rlwinm	r8,r7,0,32	# t3 = (count < 32) ? 32 : 0 | ||||
| 	sraw	r7,r3,r7	# t2 = MSW >> (count-32) | ||||
| 	or	r4,r4,r6	# LSW |= t1 | ||||
| 	slw	r7,r7,r8	# t2 = (count < 32) ? 0 : t2 | ||||
| 	sraw	r3,r3,r5	# MSW = MSW >> count | ||||
| 	or	r4,r4,r7	# LSW |= t2 | ||||
| 	blr | ||||
|  | ||||
| GLOBL(__ashldi3):	 | ||||
| 	subfic	r6,r5,32	 | ||||
| 	slw	r3,r3,r5	# MSW = count > 31 ? 0 : MSW << count | ||||
| 	addi	r7,r5,32	# could be xori, or addi with -32 | ||||
| 	srw	r6,r4,r6	# t1 = count > 31 ? 0 : LSW >> (32-count) | ||||
| 	slw	r7,r4,r7	# t2 = count < 32 ? 0 : LSW << (count-32) | ||||
| 	or	r3,r3,r6	# MSW |= t1 | ||||
| 	slw	r4,r4,r5	# LSW = LSW << count | ||||
| 	or	r3,r3,r7	# MSW |= t2 | ||||
| 	blr | ||||
|  | ||||
| GLOBL(__lshrdi3):	 | ||||
| 	subfic	r6,r5,32	 | ||||
| 	srw	r4,r4,r5	# LSW = count > 31 ? 0 : LSW >> count | ||||
| 	addi	r7,r5,32	# could be xori, or addi with -32 | ||||
| 	slw	r6,r3,r6	# t1 = count > 31 ? 0 : MSW << (32-count) | ||||
| 	srw	r7,r3,r7	# t2 = count < 32 ? 0 : MSW >> (count-32) | ||||
| 	or	r4,r4,r6	# LSW |= t1 | ||||
| 	srw	r3,r3,r5	# MSW = MSW >> count | ||||
| 	or	r4,r4,r7	# LSW |= t2  | ||||
| 	blr | ||||
| 	 | ||||
							
								
								
									
										76
									
								
								arch/ppc/mmutypes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								arch/ppc/mmutypes.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2002/01/13 13:53:14 samuel> | ||||
|  *   Time-stamp: <2002/01/27 19:56:11 samuel> | ||||
|  *    | ||||
|  *	<mmutypes.h> | ||||
|  *	 | ||||
|  *	MMU definitions | ||||
|  *    | ||||
|  *   Most of these declarations originate from the Linux Kernel | ||||
|  * | ||||
|  *   Copyright (C) 2002 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #ifndef _H_MMUTYPES | ||||
| #define _H_MMUTYPES | ||||
|  | ||||
| /* Hardware Page Table Entry */ | ||||
| typedef struct mPTE { | ||||
| 	unsigned long v:1;	/* Entry is valid */ | ||||
| 	unsigned long vsid:24;	/* Virtual segment identifier */ | ||||
| 	unsigned long h:1;	/* Hash algorithm indicator */ | ||||
| 	unsigned long api:6;	/* Abbreviated page index */ | ||||
|  | ||||
| 	unsigned long rpn:20;	/* Real (physical) page number */ | ||||
| 	unsigned long    :3;	/* Unused */ | ||||
| 	unsigned long r:1;	/* Referenced */ | ||||
| 	unsigned long c:1;	/* Changed */ | ||||
| 	unsigned long w:1;	/* Write-thru cache mode */ | ||||
| 	unsigned long i:1;	/* Cache inhibited */ | ||||
| 	unsigned long m:1;	/* Memory coherence */ | ||||
| 	unsigned long g:1;	/* Guarded */ | ||||
| 	unsigned long  :1;	/* Unused */ | ||||
| 	unsigned long pp:2;	/* Page protection */ | ||||
| } mPTE_t; | ||||
|  | ||||
|  | ||||
| typedef struct _mBATU {		/* Upper part of BAT (all except 601) */ | ||||
|         unsigned long bepi:15;	/* Effective page index (virtual address) */ | ||||
|         unsigned long :4;	/* Unused */ | ||||
|         unsigned long bl:11;	/* Block size mask */ | ||||
|         unsigned long vs:1;	/* Supervisor valid */ | ||||
|         unsigned long vp:1;	/* User valid */ | ||||
| } mBATU; | ||||
|  | ||||
| typedef struct _mBATL {		/* Lower part of BAT (all except 601) */ | ||||
|         unsigned long brpn:15;	/* Real page index (physical address) */ | ||||
|         unsigned long :10;	/* Unused */ | ||||
|         unsigned long w:1;	/* Write-thru cache */ | ||||
|         unsigned long i:1;	/* Cache inhibit */ | ||||
|         unsigned long m:1;	/* Memory coherence */ | ||||
|         unsigned long g:1;	/* Guarded (MBZ in IBAT) */ | ||||
|         unsigned long :1;	/* Unused */ | ||||
|         unsigned long pp:2;	/* Page access protections */ | ||||
| } mBATL; | ||||
|  | ||||
| typedef struct _mBAT { | ||||
|         mBATU batu;		/* Upper register */ | ||||
|         mBATL batl;		/* Lower register */ | ||||
| } mBAT; | ||||
|  | ||||
| typedef struct _mSEGREG { | ||||
|         unsigned long t:1;      /* Normal or I/O  type */ | ||||
|         unsigned long ks:1;     /* Supervisor 'key' (normally 0) */ | ||||
|         unsigned long kp:1;     /* User 'key' (normally 1) */ | ||||
|         unsigned long n:1;      /* No-execute */ | ||||
|         unsigned long :4;       /* Unused */ | ||||
|         unsigned long vsid:24;  /* Virtual Segment Identifier */ | ||||
| } mSEGREG; | ||||
|  | ||||
|  | ||||
| #endif   /* _H_MMUTYPES */ | ||||
							
								
								
									
										32
									
								
								arch/ppc/mol/console.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								arch/ppc/mol/console.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2002/10/29 18:59:05 samuel> | ||||
|  *   Time-stamp: <2003/12/28 22:51:11 samuel> | ||||
|  *    | ||||
|  *	<console.c> | ||||
|  *	 | ||||
|  *	Simple text console | ||||
|  *    | ||||
|  *   Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *   Copyright (C) 2005 Stefan Reinauer <stepan@openbios.org> | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "libc/diskio.h" | ||||
| #include "osi_calls.h" | ||||
| #include "ofmem.h" | ||||
| #include "mol/mol.h" | ||||
| #include "boothelper_sh.h" | ||||
| #include "video_sh.h" | ||||
|  | ||||
| #define openbios_GetFBInfo(x) OSI_GetFBInfo(x) | ||||
|  | ||||
| #include "../../../modules/video.c" | ||||
| #include "../../../modules/console.c" | ||||
|  | ||||
|  | ||||
							
								
								
									
										112
									
								
								arch/ppc/mol/init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								arch/ppc/mol/init.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | ||||
| /*  | ||||
|  *   Creation Date: <1999/11/16 00:49:26 samuel> | ||||
|  *   Time-stamp: <2004/04/12 16:26:50 samuel> | ||||
|  *    | ||||
|  *	<init.c> | ||||
|  *	 | ||||
|  *	Initialization | ||||
|  *    | ||||
|  *   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Samuel & David Rydh  | ||||
|  #      (samuel@ibrium.se, dary@lindesign.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "mol/mol.h" | ||||
| #include "ofmem.h" | ||||
| #include "mol/prom.h" | ||||
| #include "openbios-version.h" | ||||
| #include "osi_calls.h" | ||||
| #include "boothelper_sh.h" | ||||
|  | ||||
| extern void unexpected_excep( int vector ); | ||||
|  | ||||
| int | ||||
| get_bool_res( const char *res ) | ||||
| { | ||||
| 	char buf[8], *p; | ||||
|  | ||||
| 	p = BootHGetStrRes( res, buf, sizeof(buf) ); | ||||
| 	if( !p ) | ||||
| 		return -1; | ||||
| 	if( !strcasecmp(p,"true") || !strcasecmp(p,"yes") || !strcasecmp(p,"1") ) | ||||
| 		return 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| unexpected_excep( int vector ) | ||||
| { | ||||
| 	printk("MOL panic: Unexpected exception %x\n", vector ); | ||||
| 	for( ;; ) | ||||
| 		; | ||||
| } | ||||
|  | ||||
| void | ||||
| entry( void ) | ||||
| { | ||||
| 	printk("\n"); | ||||
| 	printk("=============================================================\n"); | ||||
| 	printk("OpenBIOS %s [%s]\n", OPENBIOS_RELEASE, OPENBIOS_BUILD_DATE ); | ||||
| 	 | ||||
| 	ofmem_init(); | ||||
| 	initialize_forth(); | ||||
| 	/* won't return */ | ||||
|  | ||||
| 	printk("of_startup returned!\n"); | ||||
| 	for( ;; ) | ||||
| 		; | ||||
| } | ||||
|  | ||||
| static void | ||||
| setenv( char *env, char *value ) | ||||
| { | ||||
| 	push_str( value ); | ||||
| 	push_str( env ); | ||||
| 	fword("$setenv"); | ||||
| } | ||||
|  | ||||
| void | ||||
| arch_of_init( void ) | ||||
| { | ||||
| 	mol_phandle_t ph; | ||||
| 	int autoboot; | ||||
| 	 | ||||
| 	devtree_init(); | ||||
| 	node_methods_init(); | ||||
| 	nvram_init(); | ||||
| 	modules_init(); | ||||
| 	pseudodisk_init(); | ||||
| 	osiblk_init(); | ||||
| 	osiscsi_init(); | ||||
| 	init_video(); | ||||
|  | ||||
| 	if( (ph=prom_find_device("/rtas")) == -1 ) | ||||
| 		printk("Warning: No /rtas node\n"); | ||||
| 	else { | ||||
| 		ulong size = 0x1000; | ||||
| 		while( size < (ulong)of_rtas_end - (ulong)of_rtas_start ) | ||||
| 			size *= 2; | ||||
| 		prom_set_prop( ph, "rtas-size", (char*)&size, sizeof(size) ); | ||||
| 	} | ||||
|  | ||||
| 	/* tweak boot settings */ | ||||
| 	autoboot = !!get_bool_res("autoboot"); | ||||
| 	if( !autoboot ) | ||||
| 		printk("Autobooting disabled - dropping into OpenFirmware\n"); | ||||
| 	setenv("auto-boot?", autoboot ? "true" : "false" ); | ||||
| 	setenv("boot-command", "molboot"); | ||||
|  | ||||
| 	if( get_bool_res("tty-interface") == 1 ) | ||||
| 		fword("activate-tty-interface"); | ||||
|  | ||||
| 	/* hack */ | ||||
| 	device_end(); | ||||
| 	bind_func("molboot", boot ); | ||||
| } | ||||
							
								
								
									
										17
									
								
								arch/ppc/mol/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								arch/ppc/mol/kernel.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:03:25 stepan> | ||||
|  *   Time-stamp: <2004/08/28 18:03:25 stepan> | ||||
|  *    | ||||
|  *	<mol/kernel.c> | ||||
|  *	 | ||||
|  *   Copyright (C) 2004 Stefan Reinauer | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "mol-dict.h" | ||||
| #include "../kernel.c" | ||||
|  | ||||
							
								
								
									
										369
									
								
								arch/ppc/mol/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										369
									
								
								arch/ppc/mol/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,369 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2002/10/02 22:24:24 samuel> | ||||
|  *   Time-stamp: <2004/03/27 01:57:55 samuel> | ||||
|  *    | ||||
|  *	<main.c> | ||||
|  *	 | ||||
|  *	 | ||||
|  *    | ||||
|  *   Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "openbios/elfload.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "libc/diskio.h" | ||||
| #include "libc/vsprintf.h" | ||||
| #include "mol/mol.h" | ||||
| #include "ofmem.h" | ||||
| #include "osi_calls.h" | ||||
| #include "ablk_sh.h" | ||||
| #include "boothelper_sh.h" | ||||
|  | ||||
|  | ||||
| static void	patch_newworld_rom( char *start, size_t size ); | ||||
| static void	newworld_timer_hack( char *start, size_t size ); | ||||
|  | ||||
| static void | ||||
| transfer_control_to_elf( ulong entry ) | ||||
| { | ||||
| 	extern void call_elf( ulong entry ); | ||||
| 	printk("Starting ELF boot loader\n"); | ||||
| 	call_elf( entry ); | ||||
|  | ||||
| 	fatal_error("call_elf returned unexpectedly\n"); | ||||
| } | ||||
|  | ||||
| static int | ||||
| load_elf_rom( ulong *entry, int fd ) | ||||
| { | ||||
| 	int i, lszz_offs, elf_offs; | ||||
| 	char buf[128], *addr; | ||||
| 	Elf_ehdr ehdr; | ||||
| 	Elf_phdr *phdr; | ||||
| 	size_t s; | ||||
|  | ||||
| 	printk("Loading '%s' from '%s'\n", get_file_path(fd), | ||||
| 	       get_volume_name(fd) ); | ||||
|  | ||||
| 	/* the ELF-image (usually) starts at offset 0x4000 */ | ||||
| 	if( (elf_offs=find_elf(fd)) < 0 ) { | ||||
| 		printk("----> %s is not an ELF image\n", buf ); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 	if( !(phdr=elf_readhdrs(fd, elf_offs, &ehdr)) ) | ||||
| 		fatal_error("elf_readhdrs failed\n"); | ||||
|  | ||||
| 	*entry = ehdr.e_entry; | ||||
|  | ||||
| 	/* load segments. Compressed ROM-image assumed to be located immediately | ||||
| 	 * after the last segment */ | ||||
| 	lszz_offs = elf_offs; | ||||
| 	for( i=0; i<ehdr.e_phnum; i++ ) { | ||||
| 		/* p_memsz, p_flags */ | ||||
| 		s = MIN( phdr[i].p_filesz, phdr[i].p_memsz ); | ||||
| 		seek_io( fd, elf_offs + phdr[i].p_offset ); | ||||
|  | ||||
| 		/* printk("filesz: %08lX memsz: %08lX p_offset: %08lX p_vaddr %08lX\n",  | ||||
| 		   phdr[i].p_filesz, phdr[i].p_memsz, phdr[i].p_offset, | ||||
| 		   phdr[i].p_vaddr ); */ | ||||
|  | ||||
| 		if( phdr[i].p_vaddr != phdr[i].p_paddr ) | ||||
| 			printk("WARNING: ELF segment virtual addr != physical addr\n"); | ||||
| 		lszz_offs = MAX( lszz_offs, elf_offs + phdr[i].p_offset + phdr[i].p_filesz ); | ||||
| 		if( !s ) | ||||
| 			continue; | ||||
| 		if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) | ||||
| 			fatal_error("Claim failed!\n"); | ||||
|  | ||||
| 		addr = (char*)phdr[i].p_vaddr; | ||||
| 		if( read_io(fd, addr, s) != s ) | ||||
| 			fatal_error("read failed\n"); | ||||
|  | ||||
| 		/* patch CODE segment */ | ||||
| 		if( *entry >= phdr[i].p_vaddr && *entry < phdr[i].p_vaddr + s ) { | ||||
| 			patch_newworld_rom( (char*)phdr[i].p_vaddr, s ); | ||||
| 			newworld_timer_hack( (char*)phdr[i].p_vaddr, s ); | ||||
| 		} | ||||
| 		flush_icache_range( addr, addr+s ); | ||||
|  | ||||
| 		/* printk("ELF ROM-section loaded at %08lX (size %08lX)\n",  | ||||
| 		   (ulong)phdr[i].p_vaddr, (ulong)phdr[i].p_memsz );*/ | ||||
| 	} | ||||
| 	free( phdr ); | ||||
| 	return lszz_offs; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	newworld ROM loading						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #define ROM_BASE	0x1100000		/* where we decide to put things */ | ||||
|  | ||||
| /* fix bug present in the 2.4 and the 3.0 Apple ROM */ | ||||
| static void | ||||
| patch_newworld_rom( char *start, size_t size ) | ||||
| { | ||||
| 	int s; | ||||
| 	ulong mark[] = { 0x7c7d1b78, 		/* mr r29,r3 */ | ||||
| 			 0x7c9c2378,		/* mr r28,r4 */ | ||||
| 			 0x7cc33378,		/* mr r3,r6 */ | ||||
| 			 0x7c864214,		/* add r4,r6,r8   <------ BUG -- */ | ||||
| 			 0x80b10000,		/* lwz r5,0(r17) */ | ||||
| 			 0x38a500e8 };		/* addi r5,r5,232 */ | ||||
|  | ||||
| 	/* Correcting add r4,r6,r8  ---->  addi r4,r6,8 */ | ||||
| 	for( s=0; s<size-sizeof(mark); s+=4 ) | ||||
| 		if( memcmp( start+s, mark, sizeof(mark)) == 0 ) { | ||||
| 			printk("FIXING ROM BUG @ %X!\n", s+12); | ||||
| 			((ulong*)(start+s))[3] = 0x38860008;	/* addi r4,r6,8 */ | ||||
| 		} | ||||
| } | ||||
|  | ||||
| /* This hack is only needed on machines with a timebase slower than 12.5 MHz | ||||
|  * (50 MHz bus frequency). Typically only old, accelerated machines fall | ||||
|  * into this category. The cause of the problem is an overflow in Apple's | ||||
|  * calibration routine. | ||||
|  */ | ||||
| static void | ||||
| newworld_timer_hack( char *start, size_t size ) | ||||
| { | ||||
| 	int s; | ||||
| 	ulong mark[] = { 0x7d0000a6, 0x5507045e, 0x7ce00124, 0x4c00012c, | ||||
| 			 0x38e00000, 0x3c80000f, 0x6084ffff, 0x98830c00, | ||||
| 			 0x7c0006ac, 0x98830a00, 0x7c0006ac, 0x7c9603a6, | ||||
| 			 0x4c00012c, 0x7cb602a6, 0x2c050000, 0x4181fff8, | ||||
| 			 0x7c0004ac, 0x88830a00, 0x7c0006ac, 0x88a30800, | ||||
| 			 0x7c0006ac, 0x88c30a00, 0x7c0006ac, 0x7c043040, | ||||
| 			 0x40a2ffe4, 0x5085442e, 0x7ca500d0, 0x54a5043e, | ||||
| 			 0x7c053840, 0x7ca72b78, 0x4082ff9c, 0x7ca32b78, | ||||
| 			 0x7d000124, 0x4c00012c, 0x4e800020 | ||||
| 	}; | ||||
|  | ||||
| 	/* return #via ticks corresponding to 0xfffff DEC ticks (VIA frequency == 47/60 MHz) */ | ||||
| 	for( s=0; s < size-sizeof(mark); s+=4 ) { | ||||
| 		if( !memcmp( start+s, mark, sizeof(mark)) ) { | ||||
| 			extern char timer_calib_start[], timer_calib_end[]; | ||||
| 			extern ulong nw_dec_calibration; | ||||
| 			int hz = OSI_UsecsToMticks(1000); | ||||
| 			nw_dec_calibration = OSI_MticksToUsecs(0xfffff*47)/60; | ||||
| 			memcpy( start + s, timer_calib_start, timer_calib_end - timer_calib_start ); | ||||
|  | ||||
| 			printk("Timer calibration fix: %d.%02d MHz [%ld]\n",  | ||||
| 			       hz/1000, (hz/10)%100, nw_dec_calibration ); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static ulong | ||||
| load_newworld_rom( int fd ) | ||||
| { | ||||
| 	int lszz_offs, lszz_size; | ||||
| 	ulong entry, data[2]; | ||||
| 	phandle_t ph; | ||||
| 	 | ||||
| 	lszz_offs = load_elf_rom( &entry, fd ); | ||||
| 	seek_io( fd, -1 ); | ||||
| 	lszz_size = tell(fd) - lszz_offs; | ||||
| 	seek_io( fd, lszz_offs ); | ||||
|  | ||||
| 	/* printk("Compressed ROM image: offset %08X, size %08X loaded at %08x\n",  | ||||
| 	   lszz_offs, lszz_size, ROM_BASE ); */ | ||||
|  | ||||
| 	if( ofmem_claim(ROM_BASE, lszz_size, 0) == -1 ) | ||||
| 		fatal_error("Claim failure (lszz)!\n"); | ||||
| 	 | ||||
| 	read_io( fd, (char*)ROM_BASE, lszz_size ); | ||||
| 	 | ||||
| 	/* Fix the /rom/macos/AAPL,toolbox-image,lzss property (phys, size) */ | ||||
| #if 0 | ||||
| 	if( (ph=prom_create_node("/rom/macos/")) == -1 ) | ||||
| 		fatal_error("Failed creating /rom/macos/"); | ||||
| #else | ||||
| 	ph = find_dev("/rom/macos"); | ||||
| #endif | ||||
| 	data[0] = ROM_BASE; | ||||
| 	data[1] = lszz_size; | ||||
| 	set_property( ph, "AAPL,toolbox-image,lzss", (char*)data, sizeof(data) ); | ||||
|  | ||||
| 	/* The 7.8 rom (MacOS 9.2) uses AAPL,toolbox-parcels instead of  | ||||
| 	 * AAPL,toolbox-image,lzss. It probably doesn't hurt to have it | ||||
| 	 * always present (we don't have an easy way to determine ROM version...) | ||||
| 	 */ | ||||
| 	set_property( ph, "AAPL,toolbox-parcels", (char*)data, sizeof(data) ); | ||||
| 	return entry; | ||||
| } | ||||
|  | ||||
| static int | ||||
| search_nwrom( int fd, int fast ) | ||||
| { | ||||
| 	char *s, buf[128]; | ||||
| 	int found = 0; | ||||
| 	 | ||||
| 	if( fast ) { | ||||
| 		int ind; | ||||
| 		found = !reopen( fd, "\\\\:tbxi" ); | ||||
| 		for( ind=0; !found && (s=BootHGetStrResInd("macos_rompath", buf, sizeof(buf), ind++, 0)) ; ) | ||||
| 			found = !reopen( fd, s ); | ||||
| 		for( ind=0; !found && (s=BootHGetStrResInd("macos_rompath_", buf, sizeof(buf), ind++, 0)) ; ) | ||||
| 			found = !reopen( fd, s ); | ||||
| 	} else { | ||||
| 		printk("Searching %s for a 'Mac OS ROM' file\n", get_volume_name(fd) ); | ||||
| 		if( !(found=reopen_nwrom(fd)) ) { | ||||
| 			printk(" \n**** HINT ***************************************************\n"); | ||||
| 			printk("*  The booting can be speeded up by adding the line\n"); | ||||
| 			printk("*      macos_rompath: '%s'\n", get_file_path(fd) ); | ||||
| 			printk("*  to the /etc/mol/molrc.macos (recommended).\n"); | ||||
| 			printk("*************************************************************\n \n"); | ||||
| 		} | ||||
| 	} | ||||
| 	return found; | ||||
| } | ||||
|  | ||||
| static void | ||||
| encode_bootpath( const char *spec, const char *args ) | ||||
| { | ||||
| 	phandle_t chosen_ph = find_dev("/chosen"); | ||||
| 	set_property( chosen_ph, "bootpath", spec, strlen(spec)+1 );	 | ||||
| 	set_property( chosen_ph, "bootargs", args, strlen(args)+1 );	 | ||||
| } | ||||
|  | ||||
| static char * | ||||
| newworld_load( const char *node_path, const char *spec, int do_search ) | ||||
| { | ||||
| 	char *p, *entry, buf[80]; | ||||
| 	int fd, len; | ||||
|  | ||||
| 	if( (fd=open_io(spec)) == -1 ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	if( !search_nwrom(fd, do_search) ) { | ||||
| 		close_io(fd); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	printk("Boot Disk: %s [%s]\n", spec, get_fstype(fd) ); | ||||
|  | ||||
| 	entry = (char*)load_newworld_rom( fd ); | ||||
|  | ||||
| #if 1 | ||||
| 	PUSH_ih( get_ih_from_fd(fd) ); | ||||
| 	fword("get-instance-path"); | ||||
| 	len = POP(); | ||||
| 	p = (char*)POP(); | ||||
| 	buf[0] = 0; | ||||
| 	if( len < sizeof(buf) ) { | ||||
| 		memcpy( buf, p, len ); | ||||
| 		buf[len] =0; | ||||
| 	} | ||||
| 	strcat( buf, "/x@:" ); | ||||
| 	printk("boot_path: %s\n", buf ); | ||||
| 	encode_bootpath( buf, "" ); | ||||
| #endif | ||||
| 	close_io( fd ); | ||||
| 	return entry; | ||||
| } | ||||
|  | ||||
| static void | ||||
| newworld_startup( void ) | ||||
| { | ||||
| 	int i, j, bootunit, type, fd; | ||||
| 	ablk_disk_info_t info; | ||||
| 	char *entry = NULL; | ||||
| 	char spec[80]; | ||||
| 	phandle_t ph; | ||||
|  | ||||
| 	char path[]="/pci/pci-bridge/mol-blk"; | ||||
| 	if( !(ph=find_dev(path)) ) | ||||
| 		fatal_error("MOLBlockDriver node not found\n"); | ||||
|  | ||||
| 	/* user-specified newworld ROMs take precedence */ | ||||
| 	if( (fd=open_io("pseudo:,nwrom")) >= 0 ) { | ||||
| 		entry = (char*)load_newworld_rom( fd ); | ||||
| 		close_io( fd ); | ||||
| 	} | ||||
|  | ||||
| 	/* determine boot volume */ | ||||
| 	for( bootunit=-1, type=0; bootunit==-1 && type<3 ; type++ ) { | ||||
| 		for( i=0; !OSI_ABlkDiskInfo(0, i, &info) ; i++ ) { | ||||
| 			if( type<=1 && !(info.flags & ABLK_BOOT_HINT) ) | ||||
| 				continue; | ||||
| 			if( type>1 && (info.flags & ABLK_BOOT_HINT) ) | ||||
| 				continue; | ||||
|  | ||||
| 			for( j=0; !entry && j<32; j++ ) { | ||||
| 				sprintf( spec, "%s/disk@%x:%d", path, i, j ); | ||||
| 				entry = newworld_load( path, spec, (!type || type==2) ); | ||||
| 			} | ||||
| 			if( entry ) { | ||||
| 				bootunit = i; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if( entry ) { | ||||
| 		OSI_ABlkBlessDisk( 0 /*channel*/, bootunit ); | ||||
|  | ||||
| 		update_nvram(); | ||||
| 		transfer_control_to_elf( (ulong)entry ); | ||||
| 		/* won't come here */ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	printk("\n--- No bootable disk was found! -----------------------------\n"); | ||||
| 	printk("If this is an oldworld machine, try booting from the MacOS\n"); | ||||
| 	printk("install CD and install MacOS from within MOL.\n"); | ||||
| 	printk("-------------------------------------------------------------\n"); | ||||
| 	exit(1); | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	yaboot booting							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static void | ||||
| yaboot_startup( void ) | ||||
| { | ||||
| 	const char *paths[] = { "pseudo:,ofclient", "pseudo:,yaboot", NULL }; | ||||
| 	ulong entry; | ||||
| 	int i, fd; | ||||
|  | ||||
| 	for( i=0; paths[i]; i++ ) { | ||||
| 		if( (fd=open_io(paths[i])) == -1 ) | ||||
| 			continue; | ||||
| 		(void) load_elf_rom( &entry, fd ); | ||||
| 		close_io( fd ); | ||||
| 		encode_bootpath( paths[i], "" ); | ||||
|  | ||||
| 		update_nvram(); | ||||
| 		transfer_control_to_elf( entry ); | ||||
| 		/* won't come here */ | ||||
| 	} | ||||
| 	printk("*** Boot failure! No secondary bootloader specified ***\n"); | ||||
| 	exit(1); | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	entry								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| void | ||||
| boot( void ) | ||||
| { | ||||
| 	fword("update-chosen"); | ||||
| 	if( find_dev("/mol-platform") ) | ||||
| 		yaboot_startup(); | ||||
| 	else | ||||
| 		newworld_startup(); | ||||
| } | ||||
							
								
								
									
										475
									
								
								arch/ppc/mol/methods.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										475
									
								
								arch/ppc/mol/methods.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,475 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2003/10/18 13:24:29 samuel> | ||||
|  *   Time-stamp: <2004/03/27 02:00:30 samuel> | ||||
|  *    | ||||
|  *	<methods.c> | ||||
|  *	 | ||||
|  *	Misc device node methods | ||||
|  *    | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "libc/string.h" | ||||
| #include "mol/mol.h" | ||||
| #include "ofmem.h" | ||||
| #include "mol/prom.h" | ||||
| #include "osi_calls.h" | ||||
| #include "kbd_sh.h" | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	Power Management						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( powermgt, INSTALL_OPEN, 0, "/pci/pci-bridge/mac-io/power-mgt" ); | ||||
|  | ||||
| /* ( -- ) */ | ||||
| static void  | ||||
| set_hybernot_flag( void ) | ||||
| { | ||||
| } | ||||
|  | ||||
| NODE_METHODS( powermgt ) = { | ||||
| 	{ "set-hybernot-flag",	set_hybernot_flag	}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	RTAS (run-time abstraction services)				*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( rtas, INSTALL_OPEN, 0, "+/rtas" ); | ||||
|  | ||||
| /* ( physbase -- rtas_callback ) */ | ||||
| static void | ||||
| rtas_instantiate( void ) | ||||
| { | ||||
| 	int physbase = POP(); | ||||
| 	int s=0x1000, size = (int)of_rtas_end - (int)of_rtas_start; | ||||
| 	ulong virt; | ||||
| 	 | ||||
| 	while( s < size ) | ||||
| 		s += 0x1000; | ||||
| 	virt = ofmem_claim_virt( 0, s, 0x1000 ); | ||||
| 	ofmem_map( physbase, virt, s, -1 ); | ||||
| 	memcpy( (char*)virt, of_rtas_start, size ); | ||||
|  | ||||
| 	printk("RTAS instantiated at %08x\n", physbase ); | ||||
| 	flush_icache_range( (char*)virt, (char*)virt + size ); | ||||
|  | ||||
| 	PUSH( physbase ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( rtas ) = { | ||||
| 	{ "instantiate",	rtas_instantiate }, | ||||
| 	{ "instantiate-rtas",	rtas_instantiate }, | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	stdout								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( video_stdout, INSTALL_OPEN, 0, "Tdisplay" ); | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| stdout_write( void ) | ||||
| { | ||||
| 	int len = POP(); | ||||
| 	char *addr = (char*)POP(); | ||||
| 	char *s = malloc( len + 1 ); | ||||
|  | ||||
| 	strncpy_nopad( s, addr, len ); | ||||
| 	s[len]=0; | ||||
| 	 | ||||
| 	/* printk( "%s", s ); */ | ||||
| 	console_draw_str( s ); | ||||
| 	free( s ); | ||||
|  | ||||
| 	PUSH( len ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( video_stdout ) = { | ||||
| 	{ "write",	stdout_write	}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	tty								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( tty, INSTALL_OPEN, 0, "+/mol/mol-tty" ); | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| tty_read( void ) | ||||
| { | ||||
| 	int ch, len = POP(); | ||||
| 	char *p = (char*)POP(); | ||||
| 	int ret=0; | ||||
|  | ||||
| 	if( len > 0 ) { | ||||
| 		ret = 1; | ||||
| 		ch = OSI_TTYGetc(); | ||||
| 		if( ch >= 0 ) { | ||||
| 			*p = ch; | ||||
| 		} else { | ||||
| 			ret = 0; | ||||
| 			OSI_USleep(1); | ||||
| 		} | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| tty_write( void ) | ||||
| { | ||||
| 	int i, len = POP(); | ||||
| 	char *p = (char*)POP(); | ||||
| 	for( i=0; i<len; i++ ) | ||||
| 		OSI_TTYPutc( *p++ ); | ||||
| 	RET( len ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( tty ) = { | ||||
| 	{ "read",	tty_read	}, | ||||
| 	{ "write",	tty_write	}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	keyboard							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| typedef struct { | ||||
| 	int	cntrl; | ||||
| 	int	shift; | ||||
| 	int	meta; | ||||
| 	int	alt; | ||||
| 	int	save_key; | ||||
| 	char 	keytable[32]; | ||||
| } kbd_state_t; | ||||
|  | ||||
| static const uchar adb_ascii_table[128] =  | ||||
| 	/* 0x00 */	"asdfhgzxcv`bqwer" | ||||
| 	/* 0x10 */	"yt123465=97-80]o" | ||||
| 	/* 0x20 */	"u[ip\nlj'k;\\,/nm." | ||||
| 	/* 0x30 */	"\t <\b \e          " | ||||
| 	/* 0x40 */	" . * +     /  - " | ||||
| 	/* 0x50 */	" =01234567 89   " | ||||
| 	/* 0x60 */	"                " | ||||
| 	/* 0x70 */	"                "; | ||||
|  | ||||
| static const uchar adb_shift_table[128] =  | ||||
| 	/* 0x00 */	"ASDFHGZXCV~BQWER" | ||||
| 	/* 0x10 */	"YT!@#$^%+(&_*)}O" | ||||
| 	/* 0x20 */	"U{IP\nLJ\"K:|<?NM>" | ||||
| 	/* 0x30 */	"\t <\b \e          " | ||||
| 	/* 0x40 */	" . * +     /  - " | ||||
| 	/* 0x50 */	" =01234567 89   " | ||||
| 	/* 0x60 */	"                " | ||||
| 	/* 0x70 */	"                "; | ||||
|  | ||||
| DECLARE_NODE( kbd, INSTALL_OPEN, sizeof(kbd_state_t),  | ||||
|       "/psuedo-hid/keyboard", | ||||
|       "/mol/mol-keyboard", | ||||
|       "/mol/keyboard" | ||||
| ); | ||||
|  | ||||
| /* ( -- keymap ) (?) */ | ||||
| /* should return a pointer to an array with 32 bytes (256 bits) */ | ||||
| static void | ||||
| kbd_get_key_map( kbd_state_t *ks ) | ||||
| { | ||||
| 	/* printk("met_kbd_get_key_map\n"); */ | ||||
|  | ||||
| 	/* keytable[5] = 0x40; */ | ||||
| 	PUSH( (int)ks->keytable ); | ||||
| } | ||||
|  | ||||
| /* ( buf len --- actlen ) */ | ||||
| static void | ||||
| kbd_read( kbd_state_t *ks ) | ||||
| { | ||||
| 	int ret=0, len = POP(); | ||||
| 	char *p = (char*)POP(); | ||||
| 	int key; | ||||
| 	 | ||||
| 	if( !p || !len ) { | ||||
| 		PUSH( -1 ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if( ks->save_key ) { | ||||
| 		*p = ks->save_key; | ||||
| 		ks->save_key = 0; | ||||
| 		RET( 1 ); | ||||
| 	} | ||||
| 	OSI_USleep(1);	/* be nice */  | ||||
|  | ||||
| 	for( ; (key=OSI_GetAdbKey()) >= 0 ; ) { | ||||
| 		int code = (key & 0x7f); | ||||
| 		int down = !(key & 0x80); | ||||
| 		 | ||||
| 		if( code == 0x36 /* ctrl */ ) { | ||||
| 			ks->cntrl = down; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if( code == 0x38 /* shift */ || code == 0x7b) { | ||||
| 			ks->shift = down; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if( code == 0x37 /* command */ ) { | ||||
| 			ks->meta = down; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if( code == 0x3a /* alt */ ) { | ||||
| 			ks->alt = down; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if( !down ) | ||||
| 			continue; | ||||
|  | ||||
| 		ret = 1; | ||||
| 		if( ks->shift ) | ||||
| 			key = adb_shift_table[ key & 0x7f ]; | ||||
| 		else | ||||
| 			key = adb_ascii_table[ key & 0x7f ]; | ||||
|  | ||||
| 		if( ks->meta ) { | ||||
| 			ks->save_key = key; | ||||
| 			key = 27; | ||||
| 		} else if( ks->cntrl ) { | ||||
| 			key = key - 'a' + 1; | ||||
| 		} | ||||
| 		*p = key; | ||||
| 		if( !*p ) | ||||
| 			*p = 'x'; | ||||
| 		break; | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( kbd ) = { | ||||
| 	{ "read",		kbd_read		}, | ||||
| 	{ "get-key-map",	kbd_get_key_map		}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	client interface 'quiesce'					*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( ciface, 0, 0, "/packages/client-iface" ); | ||||
|  | ||||
| /* ( -- ) */ | ||||
| static void | ||||
| ciface_quiesce( ulong args[], ulong ret[] )  | ||||
| { | ||||
| #if 0 | ||||
| 	ulong msr; | ||||
| 	/* This seems to be the correct thing to do - but I'm not sure */ | ||||
| 	asm volatile("mfmsr %0" : "=r" (msr) : ); | ||||
| 	msr &= ~(MSR_IR | MSR_DR); | ||||
| 	asm volatile("mtmsr %0" :: "r" (msr) ); | ||||
| #endif | ||||
| 	printk("=============================================================\n\n"); | ||||
| 	prom_close(); | ||||
|  | ||||
| 	OSI_KbdCntrl( kKbdCntrlSuspend ); | ||||
| } | ||||
|  | ||||
| /* ( -- ms ) */ | ||||
| static void | ||||
| ciface_milliseconds( ulong args[], ulong ret[] )  | ||||
| { | ||||
| 	static ulong mticks=0, usecs=0; | ||||
| 	ulong t; | ||||
|          | ||||
| 	asm volatile("mftb %0" : "=r" (t) : ); | ||||
| 	if( mticks ) | ||||
| 		usecs += OSI_MticksToUsecs( t-mticks ); | ||||
| 	mticks = t; | ||||
|  | ||||
| 	PUSH( usecs/1000 ); | ||||
| } | ||||
|  | ||||
|  | ||||
| NODE_METHODS( ciface ) = { | ||||
| 	{ "quiesce",		ciface_quiesce		}, | ||||
| 	{ "milliseconds",	ciface_milliseconds	}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	MMU/memory methods						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( memory, INSTALL_OPEN, 0, "/memory" ); | ||||
| DECLARE_NODE( mmu, INSTALL_OPEN, 0, "/cpus/@0" ); | ||||
| DECLARE_NODE( mmu_ciface, 0, 0, "/packages/client-iface" ); | ||||
|  | ||||
|  | ||||
| /* ( phys size align --- base ) */ | ||||
| static void | ||||
| mem_claim( void ) | ||||
| { | ||||
| 	int align = POP(); | ||||
| 	int size = POP(); | ||||
| 	int phys = POP(); | ||||
| 	int ret = ofmem_claim_phys( phys, size, align ); | ||||
| 	 | ||||
| 	if( ret == -1 ) { | ||||
| 		printk("MEM: claim failure\n"); | ||||
| 		throw( -13 ); | ||||
| 		return; | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( phys size --- ) */ | ||||
| static void | ||||
| mem_release( void ) | ||||
| { | ||||
| 	POP(); POP(); | ||||
| } | ||||
|  | ||||
| /* ( phys size align --- base ) */ | ||||
| static void | ||||
| mmu_claim( void ) | ||||
| { | ||||
| 	int align = POP(); | ||||
| 	int size = POP(); | ||||
| 	int phys = POP(); | ||||
| 	int ret = ofmem_claim_virt( phys, size, align ); | ||||
|  | ||||
| 	if( ret == -1 ) { | ||||
| 		printk("MMU: CLAIM failure\n"); | ||||
| 		throw( -13 ); | ||||
| 		return; | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( phys size --- ) */ | ||||
| static void | ||||
| mmu_release( void ) | ||||
| { | ||||
| 	POP(); POP(); | ||||
| } | ||||
|  | ||||
| /* ( phys virt size mode -- [ret???] ) */ | ||||
| static void  | ||||
| mmu_map( void ) | ||||
| { | ||||
| 	int mode = POP(); | ||||
| 	int size = POP(); | ||||
| 	int virt = POP(); | ||||
| 	int phys = POP(); | ||||
| 	int ret; | ||||
| 	 | ||||
| 	/* printk("mmu_map: %x %x %x %x\n", phys, virt, size, mode ); */ | ||||
| 	ret = ofmem_map( phys, virt, size, mode ); | ||||
|  | ||||
| 	if( ret ) { | ||||
| 		printk("MMU: map failure\n"); | ||||
| 		throw( -13 ); | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* ( virt size -- ) */ | ||||
| static void | ||||
| mmu_unmap( void ) | ||||
| { | ||||
| 	POP(); POP(); | ||||
| } | ||||
|  | ||||
| /* ( virt -- false | phys mode true ) */ | ||||
| static void | ||||
| mmu_translate( void ) | ||||
| { | ||||
| 	ulong mode; | ||||
| 	int virt = POP(); | ||||
| 	int phys = ofmem_translate( virt, &mode ); | ||||
|  | ||||
| 	if( phys == -1 ) { | ||||
| 		PUSH( 0 ); | ||||
| 	} else { | ||||
| 		PUSH( phys ); | ||||
| 		PUSH( (int)mode ); | ||||
| 		PUSH( -1 ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* ( virt size align -- baseaddr|-1 ) */ | ||||
| static void | ||||
| ciface_claim( void ) | ||||
| { | ||||
| 	int align = POP(); | ||||
| 	int size = POP(); | ||||
| 	int virt = POP(); | ||||
| 	int ret = ofmem_claim( virt, size, align ); | ||||
|  | ||||
| 	/* printk("ciface_claim: %08x %08x %x\n", virt, size, align ); */ | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( virt size -- ) */ | ||||
| static void | ||||
| ciface_release( void ) | ||||
| { | ||||
| 	POP(); | ||||
| 	POP(); | ||||
| } | ||||
|  | ||||
|  | ||||
| NODE_METHODS( memory ) = { | ||||
| 	{ "claim",		mem_claim		}, | ||||
| 	{ "release",		mem_release		}, | ||||
| }; | ||||
|  | ||||
| NODE_METHODS( mmu ) = { | ||||
| 	{ "claim",		mmu_claim		}, | ||||
| 	{ "release",		mmu_release		}, | ||||
| 	{ "map",		mmu_map			}, | ||||
| 	{ "unmap",		mmu_unmap		}, | ||||
| 	{ "translate",		mmu_translate		}, | ||||
| }; | ||||
|  | ||||
| NODE_METHODS( mmu_ciface ) = { | ||||
| 	{ "claim",		ciface_claim		}, | ||||
| 	{ "release",		ciface_release		}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	init								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| void | ||||
| node_methods_init( void ) | ||||
| { | ||||
| 	REGISTER_NODE( rtas ); | ||||
| 	REGISTER_NODE( powermgt ); | ||||
| 	REGISTER_NODE( kbd ); | ||||
| 	REGISTER_NODE( video_stdout ); | ||||
| 	REGISTER_NODE( ciface ); | ||||
| 	REGISTER_NODE( memory ); | ||||
| 	REGISTER_NODE( mmu ); | ||||
| 	REGISTER_NODE( mmu_ciface ); | ||||
|  | ||||
| 	if( OSI_CallAvailable(OSI_TTY_GETC) ) | ||||
| 		REGISTER_NODE( tty ); | ||||
|  | ||||
| 	OSI_KbdCntrl( kKbdCntrlActivate ); | ||||
| } | ||||
							
								
								
									
										166
									
								
								arch/ppc/mol/mol.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								arch/ppc/mol/mol.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,166 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2003/12/19 18:46:21 samuel> | ||||
|  *   Time-stamp: <2004/04/12 16:27:12 samuel> | ||||
|  *    | ||||
|  *	<mol.c> | ||||
|  *	 | ||||
|  *	 | ||||
|  *    | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "libc/vsprintf.h" | ||||
| #include "libc/string.h" | ||||
| #include "mol/mol.h" | ||||
| #include "osi_calls.h" | ||||
| #include <stdarg.h> | ||||
|  | ||||
| void | ||||
| exit( int status ) | ||||
| { | ||||
| 	OSI_Exit(); | ||||
| } | ||||
|  | ||||
| void | ||||
| fatal_error( const char *err ) | ||||
| { | ||||
| 	printk("Fatal error: %s\n", err ); | ||||
| 	OSI_Exit(); | ||||
| } | ||||
|  | ||||
| void | ||||
| panic( const char *err ) | ||||
| { | ||||
| 	printk("Panic: %s\n", err ); | ||||
| 	OSI_Exit(); | ||||
|  | ||||
| 	/* won't come here... this keeps the gcc happy */ | ||||
| 	for( ;; ) | ||||
| 		; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	print using OSI interface					*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static int do_indent; | ||||
|  | ||||
| int | ||||
| printk( const char *fmt, ... ) | ||||
| { | ||||
| 	char *p, buf[1024];	/* XXX: no buffer overflow protection... */ | ||||
| 	va_list args; | ||||
| 	int i; | ||||
|  | ||||
| 	va_start(args, fmt); | ||||
| 	i=vsprintf(buf,fmt,args); | ||||
| 	va_end(args); | ||||
|  | ||||
| 	for( p=buf; *p; p++ ) { | ||||
| 		if( *p == '\n' ) | ||||
| 			do_indent = 0; | ||||
| 		if( do_indent++ == 1 ) { | ||||
| 			OSI_PutC( '>' ); | ||||
| 			OSI_PutC( '>' ); | ||||
| 			OSI_PutC( ' ' ); | ||||
| 		} | ||||
| 		OSI_PutC( *p ); | ||||
| 	} | ||||
| 	return i; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	TTY iface							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static int ttychar = -1; | ||||
|  | ||||
| static int | ||||
| tty_avail( void ) | ||||
| { | ||||
| 	return OSI_CallAvailable( OSI_TTY_GETC ); | ||||
| } | ||||
|  | ||||
| int | ||||
| availchar( void ) | ||||
| { | ||||
| 	if( !tty_avail() ) | ||||
| 		return 0; | ||||
| 	 | ||||
| 	if( ttychar < 0 ) | ||||
| 		ttychar = OSI_TTYGetc(); | ||||
| 	if( ttychar < 0 ) | ||||
| 		OSI_USleep(1); | ||||
| 	return (ttychar >= 0); | ||||
| } | ||||
|  | ||||
| int | ||||
| getchar( void ) | ||||
| { | ||||
| 	int ch; | ||||
|  | ||||
| 	if( !tty_avail() ) | ||||
| 		return 0; | ||||
|  | ||||
| 	if( ttychar < 0 ) | ||||
| 		return OSI_TTYGetc(); | ||||
| 	ch = ttychar; | ||||
| 	ttychar = -1; | ||||
| 	return ch; | ||||
| } | ||||
|  | ||||
| int | ||||
| putchar( int c ) | ||||
| { | ||||
| 	printk("%c", c ); | ||||
|  | ||||
| 	if( tty_avail() ) | ||||
| 		OSI_TTYPutc( c ); | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	MOL specific stuff						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| int | ||||
| arch_nvram_size( void ) | ||||
| { | ||||
| 	return OSI_NVRamSize(); | ||||
| } | ||||
|  | ||||
| void | ||||
| arch_nvram_put( char *buf ) | ||||
| { | ||||
| 	int i, size = arch_nvram_size(); | ||||
|  | ||||
| 	for( i=0; i<size; i++ ) | ||||
| 		OSI_WriteNVRamByte( i, buf[i] ); | ||||
| } | ||||
|  | ||||
| void | ||||
| arch_nvram_get( char *buf ) | ||||
| { | ||||
| 	int i, size = arch_nvram_size(); | ||||
|  | ||||
| 	/* support for zapping the nvram */ | ||||
| 	if( get_bool_res("zap_nvram") == 1 ) { | ||||
| 		memset( buf, 0, size ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	for( i=0; i<size; i++ ) | ||||
| 		buf[i] = OSI_ReadNVRamByte( i ); | ||||
| } | ||||
|  | ||||
							
								
								
									
										107
									
								
								arch/ppc/mol/mol.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								arch/ppc/mol/mol.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------------------- | ||||
| \ initialization | ||||
| \ ------------------------------------------------------------------------- | ||||
|  | ||||
| : make-openable ( path ) | ||||
|   find-dev if | ||||
|     begin ?dup while | ||||
|       \ install trivial open and close methods | ||||
|       dup active-package! is-open | ||||
|       parent | ||||
|     repeat | ||||
|   then | ||||
| ; | ||||
|  | ||||
| : preopen ( chosen-str node-path ) | ||||
|   2dup make-openable | ||||
|    | ||||
|   " /chosen" find-device | ||||
|   open-dev ?dup if | ||||
|     encode-int 2swap property | ||||
|   else | ||||
|     2drop | ||||
|   then | ||||
| ; | ||||
|  | ||||
| \ preopen device nodes (and store the ihandles under /chosen) | ||||
| :noname | ||||
|   " memory" " /memory" preopen | ||||
|   " mmu" " /cpus/@0" preopen | ||||
|   " stdout" " /packages/mol-stdout" preopen | ||||
|   " stdin" " keyboard" preopen | ||||
|   " nvram" " /pci/pci-bridge/mac-io/nvram" preopen | ||||
|   " nvram" " /mol/nvram" preopen | ||||
|  | ||||
| ; SYSTEM-initializer | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------------------- | ||||
| \ device tree fixing | ||||
| \ ------------------------------------------------------------------------- | ||||
|  | ||||
| \ add decode-address methods | ||||
| : (make-decodable) ( phandle -- ) | ||||
|  | ||||
|     dup " #address-cells" rot get-package-property 0= if | ||||
|       decode-int nip nip | ||||
|       over " decode-unit" rot find-method if 2drop else | ||||
|         ( save phandle ncells ) | ||||
|        | ||||
|         over active-package! | ||||
|         case | ||||
|           1 of ['] parse-hex " decode-unit" is-xt-func endof | ||||
|           3 of | ||||
|             " bus-range" active-package get-package-property 0= if | ||||
|               decode-int nip nip | ||||
|               ['] encode-unit-pci " encode-unit" is-xt-func | ||||
|               " decode-unit" is-func-begin | ||||
|                 ['] (lit) , , | ||||
|                 ['] decode-unit-pci-bus , | ||||
|               is-func-end | ||||
|             then | ||||
|           endof | ||||
|         endcase | ||||
|       then | ||||
|     then | ||||
|     drop | ||||
| ; | ||||
|      | ||||
| : tree-fixes ( -- ) | ||||
|   active-package | ||||
|    | ||||
|   iterate-tree-begin | ||||
|   begin ?dup while | ||||
|  | ||||
|     dup (make-decodable) | ||||
|      | ||||
|     iterate-tree | ||||
|   repeat | ||||
|  | ||||
|   active-package! | ||||
| ; | ||||
|  | ||||
| \ use the tty interface if available | ||||
| : activate-tty-interface | ||||
|   " /mol/mol-tty" find-dev if drop | ||||
|     " /mol/mol-tty" " input-device" $setenv | ||||
|     " /mol/mol-tty" " output-device" $setenv | ||||
|   then | ||||
| ; | ||||
|  | ||||
| :noname | ||||
|   " keyboard" input | ||||
| ; CONSOLE-IN-initializer | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------------------- | ||||
| \ pre-booting | ||||
| \ ------------------------------------------------------------------------- | ||||
|  | ||||
| : update-chosen | ||||
|   " /chosen" find-device | ||||
|   stdin @ encode-int " stdin" property | ||||
|   stdout @ encode-int " stdout" property | ||||
|   device-end | ||||
| ; | ||||
							
								
								
									
										44
									
								
								arch/ppc/mol/mol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								arch/ppc/mol/mol.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2003/12/20 00:20:12 samuel> | ||||
|  *   Time-stamp: <2004/03/27 01:52:50 samuel> | ||||
|  *    | ||||
|  *	<mol.h> | ||||
|  *	 | ||||
|  *	 | ||||
|  *    | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #ifndef _H_MOL | ||||
| #define _H_MOL | ||||
|  | ||||
| /* video.c */ | ||||
| extern void		init_video( void ); | ||||
| extern int		video_get_res( int *w, int *h ); | ||||
| extern void		draw_pixel( int x, int y, int colind ); | ||||
| extern void		set_color( int index, ulong color ); | ||||
|  | ||||
| /* console.c */ | ||||
| extern int		console_draw_str( const char *str ); | ||||
| extern void		console_close( void ); | ||||
|  | ||||
| /* pseudodisk.c */ | ||||
| extern void		pseudodisk_init( void ); | ||||
|  | ||||
| /* osi-blk.c */ | ||||
| extern void		osiblk_init( void ); | ||||
|  | ||||
| /* osi-scsi.c */ | ||||
| extern void		osiscsi_init( void ); | ||||
|  | ||||
| /* pseudofs.c */ | ||||
| extern void		pseudofs_init( void ); | ||||
|  | ||||
| #include "../kernel.h" | ||||
|  | ||||
| #endif   /* _H_MOL */ | ||||
							
								
								
									
										119
									
								
								arch/ppc/mol/osi-blk.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								arch/ppc/mol/osi-blk.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,119 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2003/12/07 19:08:33 samuel> | ||||
|  *   Time-stamp: <2004/01/07 19:38:36 samuel> | ||||
|  *    | ||||
|  *	<osi-blk.c> | ||||
|  *	 | ||||
|  *	OSI-block interface | ||||
|  *    | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "mol/mol.h" | ||||
| #include "osi_calls.h" | ||||
|  | ||||
| typedef struct { | ||||
| 	int	unit; | ||||
| 	int	channel; | ||||
| } osiblk_data_t; | ||||
|  | ||||
|  | ||||
| DECLARE_NODE( osiblk, INSTALL_OPEN, sizeof(osiblk_data_t), | ||||
| 	      "/pci/pci-bridge/mol-blk/disk", "/mol/mol-blk" ); | ||||
|  | ||||
|  | ||||
| static void | ||||
| osiblk_open( osiblk_data_t *pb ) | ||||
| { | ||||
| 	phandle_t ph; | ||||
|  | ||||
| 	fword("my-unit"); | ||||
| 	pb->unit = POP(); | ||||
| 	pb->channel = 0;	/* FIXME */ | ||||
|  | ||||
| 	selfword("open-deblocker"); | ||||
|  | ||||
| 	/* interpose disk-label */ | ||||
| 	ph = find_dev("/packages/disk-label"); | ||||
| 	fword("my-args"); | ||||
| 	PUSH_ph( ph ); | ||||
| 	fword("interpose"); | ||||
|  | ||||
| 	/* printk("osi-blk: open %d\n", pb->unit ); */ | ||||
| 	PUSH( -1 ); | ||||
| } | ||||
|  | ||||
| static void | ||||
| osiblk_close( osiblk_data_t *pb ) | ||||
| { | ||||
| 	selfword("close-deblocker"); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ( buf blk nblks -- actual ) */ | ||||
| static void | ||||
| osiblk_read_blocks( osiblk_data_t *pb ) | ||||
| { | ||||
| 	int i, n = POP(); | ||||
| 	int blk = POP(); | ||||
| 	char *dest = (char*)POP(); | ||||
| 	 | ||||
| 	/* printk("osiblk_read_blocks %x block=%d n=%d\n", (int)dest, blk, n ); */ | ||||
|  | ||||
| 	for( i=0; i<n; ) { | ||||
| 		char buf[4096]; | ||||
| 		int m = MIN( n-i, sizeof(buf)/512 ); | ||||
|  | ||||
| 		if( OSI_ABlkSyncRead(pb->channel, pb->unit, blk+i, (int)buf, m*512) < 0 ) { | ||||
| 			printk("SyncRead: error\n"); | ||||
| 			RET(0); | ||||
| 		} | ||||
| 		memcpy( dest, buf, m * 512 ); | ||||
| 		i += m; | ||||
| 		dest += m * 512; | ||||
| 	} | ||||
| 	PUSH( n ); | ||||
| } | ||||
|  | ||||
| /* ( -- bs ) */ | ||||
| static void | ||||
| osiblk_block_size( osiblk_data_t *pb ) | ||||
| { | ||||
| 	PUSH( 512 ); | ||||
| } | ||||
|  | ||||
| /* ( -- maxbytes ) */ | ||||
| static void | ||||
| osiblk_max_transfer( osiblk_data_t *pb ) | ||||
| { | ||||
| 	PUSH( 1024*1024 ); | ||||
| } | ||||
|  | ||||
| static void | ||||
| osiblk_initialize( osiblk_data_t *pb ) | ||||
| { | ||||
| 	fword("is-deblocker"); | ||||
| } | ||||
|  | ||||
|  | ||||
| NODE_METHODS( osiblk ) = { | ||||
| 	{ NULL,			osiblk_initialize	}, | ||||
| 	{ "open",		osiblk_open		}, | ||||
| 	{ "close",		osiblk_close		}, | ||||
| 	{ "read-blocks",	osiblk_read_blocks	}, | ||||
| 	{ "block-size",		osiblk_block_size	}, | ||||
| 	{ "max-transfer",	osiblk_max_transfer	}, | ||||
| }; | ||||
|  | ||||
| void | ||||
| osiblk_init( void ) | ||||
| { | ||||
| 	REGISTER_NODE( osiblk ); | ||||
| } | ||||
							
								
								
									
										271
									
								
								arch/ppc/mol/osi-scsi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								arch/ppc/mol/osi-scsi.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,271 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2003/12/11 21:23:54 samuel> | ||||
|  *   Time-stamp: <2004/01/07 19:38:45 samuel> | ||||
|  *    | ||||
|  *	<osi-scsi.c> | ||||
|  *	 | ||||
|  *	SCSI device node | ||||
|  *    | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "mol/mol.h" | ||||
| #include "scsi_sh.h" | ||||
| #include "osi_calls.h" | ||||
|  | ||||
| #define MAX_TARGETS	32 | ||||
|  | ||||
| typedef struct { | ||||
| 	int		probed; | ||||
| 	int		valid;		/* a useable device found */ | ||||
|  | ||||
| 	int		is_cd; | ||||
| 	int		blocksize; | ||||
| } target_info_t; | ||||
|  | ||||
| static target_info_t 	scsi_devs[ MAX_TARGETS ]; | ||||
|  | ||||
| typedef struct { | ||||
| 	int		target; | ||||
| 	target_info_t	*info; | ||||
| } instance_data_t; | ||||
|  | ||||
|  | ||||
| DECLARE_NODE( scsi, INSTALL_OPEN, sizeof(instance_data_t), | ||||
| 	      "/pci/pci-bridge/mol-scsi/sd", "/mol/mol-scsi/sd" ); | ||||
|  | ||||
|  | ||||
| static int | ||||
| scsi_cmd_( instance_data_t *sd, const char *cmd, int cmdlen, char *dest, | ||||
| 	   int len, int prelen, int postlen ) | ||||
| { | ||||
| 	char prebuf[4096], postbuf[4096]; | ||||
| 	scsi_req_t r[2];	/* the [2] is a hack to get space for the sg-list */ | ||||
| 	char sb[32]; | ||||
|  | ||||
| 	/* memset( dest, 0, len ); */ | ||||
|  | ||||
| 	if( (uint)prelen > sizeof(prebuf) || (uint)postlen > sizeof(postbuf) ) { | ||||
| 		printk("bad pre/post len %d %d\n", prelen, postlen ); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	memset( r, 0, sizeof(r[0]) ); | ||||
| 	r->lun = 0; | ||||
| 	r->target = sd->target; | ||||
| 	r->is_write = 0; | ||||
| 	memcpy( r->cdb, cmd, cmdlen ); | ||||
| 	r->client_addr = (int)&r; | ||||
| 	r->cdb_len = cmdlen; | ||||
| 	r->sense[0].base = (int)&sb; | ||||
| 	r->sense[0].size = sizeof(sb); | ||||
| 	r->size = prelen + len + postlen; | ||||
| 	r->n_sg = 3; | ||||
| 	r->sglist.n_el = 3; | ||||
| 	r->sglist.vec[0].base = (int)prebuf; | ||||
| 	r->sglist.vec[0].size = prelen; | ||||
| 	r->sglist.vec[1].base = (int)dest; | ||||
| 	r->sglist.vec[1].size = len; | ||||
| 	r->sglist.vec[2].base = (int)postbuf; | ||||
| 	r->sglist.vec[2].size = postlen; | ||||
|  | ||||
| 	if( OSI_SCSISubmit((int)&r) ) { | ||||
| 		printk("OSI_SCSISubmit: error!\n"); | ||||
| 		return 1; | ||||
| 	} | ||||
| 	while( !OSI_SCSIAck() ) | ||||
| 		OSI_USleep( 10 ); | ||||
|  | ||||
| 	if( r->adapter_status ) | ||||
| 		return -1; | ||||
| 	if( r->scsi_status ) | ||||
| 		return ((sb[2] & 0xf) << 16) | (sb[12] << 8) | sb[13]; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int | ||||
| scsi_cmd( instance_data_t *sd, const char *cmd, int cmdlen ) | ||||
| { | ||||
| 	return scsi_cmd_( sd, cmd, cmdlen, NULL, 0, 0, 0 ); | ||||
| } | ||||
|  | ||||
| /* ( buf blk nblks -- actual ) */ | ||||
| static void | ||||
| scsi_read_blocks( instance_data_t *sd ) | ||||
| { | ||||
| 	int nblks = POP(); | ||||
| 	int blk = POP(); | ||||
| 	char *dest = (char*)POP(); | ||||
| 	unsigned char cmd[10]; | ||||
| 	int len = nblks * sd->info->blocksize; | ||||
| 	 | ||||
| 	memset( dest, 0, len ); | ||||
|  | ||||
| 	/* printk("READ: blk: %d length %d\n", blk, len ); */ | ||||
| 	memset( cmd, 0, sizeof(cmd) ); | ||||
| 	cmd[0] = 0x28; /* READ_10 */ | ||||
| 	cmd[2] = blk >> 24; | ||||
| 	cmd[3] = blk >> 16; | ||||
| 	cmd[4] = blk >> 8; | ||||
| 	cmd[5] = blk; | ||||
| 	cmd[7] = nblks >> 8; | ||||
| 	cmd[8] = nblks; | ||||
|  | ||||
| 	if( scsi_cmd_(sd, cmd, 10, dest, len, 0, 0) ) { | ||||
| 		printk("read: scsi_cmd failed\n"); | ||||
| 		RET( -1 ); | ||||
| 	} | ||||
| 	PUSH( nblks ); | ||||
| } | ||||
|  | ||||
| static int | ||||
| inquiry( instance_data_t *sd ) | ||||
| { | ||||
| 	char inquiry_cmd[6] = { 0x12, 0, 0, 0, 32, 0 }; | ||||
| 	char start_stop_unit_cmd[6] = { 0x1b, 0, 0, 0, 1, 0 }; | ||||
| 	char test_unit_ready_cmd[6] = { 0x00, 0, 0, 0, 0, 0 }; | ||||
| 	char prev_allow_medium_removal[6] = { 0x1e, 0, 0, 0, 1, 0 }; | ||||
| 	char set_cd_speed_cmd[12] = { 0xbb, 0, 0xff, 0xff, 0xff, 0xff, | ||||
| 				      0, 0, 0, 0, 0, 0 }; | ||||
| 	target_info_t *info = &scsi_devs[sd->target]; | ||||
| 	char ret[32]; | ||||
| 	int i, sense; | ||||
|  | ||||
| 	if( sd->target >= MAX_TARGETS ) | ||||
| 		return -1; | ||||
| 	sd->info = info; | ||||
|  | ||||
| 	if( info->probed ) | ||||
| 		return info->valid ? 0:-1; | ||||
| 	info->probed = 1; | ||||
|  | ||||
| 	if( (sense=scsi_cmd_(sd, inquiry_cmd, 6, ret, 2, 0, 0)) ) { | ||||
| 		if( sense < 0 ) | ||||
| 			return -1; | ||||
| 		printk("INQUIRY failed\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* medium present? */ | ||||
| 	if( (scsi_cmd(sd, test_unit_ready_cmd, 6) >> 8) == 0x23a ) { | ||||
| 		printk("no media\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	info->is_cd = 0; | ||||
| 	info->blocksize = 512; | ||||
|  | ||||
| 	if( ret[0] == 5 /* CD/DVD */ ) { | ||||
| 		info->blocksize = 2048; | ||||
| 		info->is_cd = 1; | ||||
|  | ||||
| 		scsi_cmd( sd, prev_allow_medium_removal, 6 ); | ||||
| 		scsi_cmd( sd, set_cd_speed_cmd, 12 ); | ||||
| 		scsi_cmd( sd, start_stop_unit_cmd, 6 ); | ||||
|  | ||||
| 	} else if( ret[0] == 0 /* DISK */ ) { | ||||
| 		scsi_cmd( sd, test_unit_ready_cmd, 6 ); | ||||
| 		scsi_cmd( sd, start_stop_unit_cmd, 6 ); | ||||
| 	} else { | ||||
| 		/* don't boot from this device (could be a scanner :-)) */ | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	/* wait for spin-up (or whatever) to complete */ | ||||
| 	for( i=0; ; i++ ) { | ||||
| 		if( i > 300 ) { | ||||
| 			printk("SCSI timeout (sense %x)\n", sense ); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		sense = scsi_cmd( sd, test_unit_ready_cmd, 6 ); | ||||
| 		if( (sense & 0xf0000) == 0x20000 ) { | ||||
| 			OSI_USleep( 10000 ); | ||||
| 			continue; | ||||
| 		} | ||||
| 		break; | ||||
| 	}  | ||||
|  | ||||
| 	info->valid = 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* ( -- success? ) */ | ||||
| static void | ||||
| scsi_open( instance_data_t *sd ) | ||||
| { | ||||
| 	static int once = 0; | ||||
| 	phandle_t ph; | ||||
|  | ||||
| 	fword("my-unit"); | ||||
| 	sd->target = POP(); | ||||
|  | ||||
| 	if( !once ) { | ||||
| 		once++; | ||||
| 		OSI_SCSIControl( SCSI_CTRL_INIT, 0 ); | ||||
| 	} | ||||
|  | ||||
| 	/* obtiain device information */ | ||||
| 	if( inquiry(sd) ) | ||||
| 		RET(0); | ||||
|  | ||||
| 	selfword("open-deblocker"); | ||||
|  | ||||
| 	/* interpose disk-label */ | ||||
| 	ph = find_dev("/packages/disk-label"); | ||||
| 	fword("my-args"); | ||||
| 	PUSH_ph( ph ); | ||||
| 	fword("interpose"); | ||||
|  | ||||
| 	PUSH( -1 ); | ||||
| } | ||||
|  | ||||
| /* ( -- ) */ | ||||
| static void | ||||
| scsi_close( instance_data_t *pb ) | ||||
| { | ||||
| 	selfword("close-deblocker"); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ( -- bs ) */ | ||||
| static void | ||||
| scsi_block_size( instance_data_t *sd ) | ||||
| { | ||||
| 	PUSH( sd->info->blocksize ); | ||||
| } | ||||
|  | ||||
| /* ( -- maxbytes ) */ | ||||
| static void | ||||
| scsi_max_transfer( instance_data_t *sd ) | ||||
| { | ||||
| 	PUSH( 1024*1024 ); | ||||
| } | ||||
|  | ||||
| static void | ||||
| scsi_initialize( instance_data_t *sd ) | ||||
| { | ||||
| 	fword("is-deblocker"); | ||||
| } | ||||
|  | ||||
|  | ||||
| NODE_METHODS( scsi ) = { | ||||
| 	{ NULL,			scsi_initialize	}, | ||||
| 	{ "open",		scsi_open		}, | ||||
| 	{ "close",		scsi_close		}, | ||||
| 	{ "read-blocks",	scsi_read_blocks	}, | ||||
| 	{ "block-size",		scsi_block_size	}, | ||||
| 	{ "max-transfer",	scsi_max_transfer	}, | ||||
| }; | ||||
|  | ||||
| void | ||||
| osiscsi_init( void ) | ||||
| { | ||||
| 	REGISTER_NODE( scsi ); | ||||
| } | ||||
							
								
								
									
										177
									
								
								arch/ppc/mol/prom.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								arch/ppc/mol/prom.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,177 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2002/10/03 20:55:02 samuel> | ||||
|  *   Time-stamp: <2002/10/29 13:00:23 samuel> | ||||
|  *    | ||||
|  *	<prom.c> | ||||
|  *	 | ||||
|  *	oftree interface | ||||
|  *    | ||||
|  *   Copyright (C) 2002, 2003 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "osi_calls.h" | ||||
| #include "mol/prom.h" | ||||
|  | ||||
| /* OSI_PromClose (free linux side device tree) */ | ||||
| int | ||||
| prom_close( void ) | ||||
| { | ||||
| 	return OSI_PromIface( kPromClose, 0 ); | ||||
| } | ||||
|  | ||||
| /* ret: 0 no more peers, -1 if error */ | ||||
| mol_phandle_t | ||||
| prom_peer( mol_phandle_t phandle ) | ||||
| { | ||||
| 	return OSI_PromIface( kPromPeer, phandle ); | ||||
| } | ||||
|  | ||||
| /* ret: 0 no child, -1 if error */ | ||||
| mol_phandle_t | ||||
| prom_child( mol_phandle_t phandle ) | ||||
| { | ||||
| 	return OSI_PromIface( kPromChild, phandle ); | ||||
| } | ||||
|  | ||||
| /* ret: 0 if root node, -1 if error */ | ||||
| mol_phandle_t | ||||
| prom_parent( mol_phandle_t phandle ) | ||||
| { | ||||
| 	return OSI_PromIface( kPromParent, phandle ); | ||||
| } | ||||
|  | ||||
| /* ret: -1 error */ | ||||
| int | ||||
| prom_package_to_path( mol_phandle_t phandle, char *buf, long buflen ) | ||||
| { | ||||
| 	return OSI_PromIface2( kPromPackageToPath, phandle, (int)buf, buflen ); | ||||
| } | ||||
|  | ||||
| /* ret: -1 error */ | ||||
| int | ||||
| prom_get_prop_len( mol_phandle_t phandle, const char *name ) | ||||
| { | ||||
| 	return OSI_PromIface1( kPromGetPropLen, phandle, (int)name ); | ||||
| } | ||||
|  | ||||
| /* ret: prop len or -1 if error */ | ||||
| int | ||||
| prom_get_prop( mol_phandle_t phandle, const char *name, char *buf, long buflen ) | ||||
| { | ||||
| 	return OSI_PromIface3( kPromGetProp, phandle, (int)name, (int)buf, buflen ); | ||||
| } | ||||
|  | ||||
| /* ret: prop len or -1 if error */ | ||||
| int | ||||
| prom_get_prop_by_path( const char *path, const char *name, char *buf, long buflen )  | ||||
| { | ||||
| 	mol_phandle_t ph = prom_find_device(path); | ||||
| 	return (ph != -1)? prom_get_prop( ph, name, buf, buflen) : -1; | ||||
| } | ||||
|  | ||||
| /* ret: -1 error, 0 last prop, 1 otherwise */ | ||||
| int | ||||
| prom_next_prop( mol_phandle_t phandle, const char *prev, char *buf ) | ||||
| { | ||||
| 	return OSI_PromIface2( kPromNextProp, phandle, (int)prev, (int)buf ); | ||||
| } | ||||
|  | ||||
| /* ret: -1 if error */ | ||||
| int | ||||
| prom_set_prop( mol_phandle_t phandle, const char *name, char *buf, long buflen ) | ||||
| { | ||||
| 	return OSI_PromIface3( kPromSetProp, phandle, (int)name, (int)buf, buflen ); | ||||
| } | ||||
|  | ||||
| /* ret: -1 if error */ | ||||
| mol_phandle_t | ||||
| prom_create_node( const char *path ) | ||||
| { | ||||
| 	return OSI_PromPathIface( kPromCreateNode, path ); | ||||
| } | ||||
|  | ||||
| /* ret: -1 if not found */ | ||||
| mol_phandle_t | ||||
| prom_find_device( const char *path ) | ||||
| { | ||||
| 	mol_phandle_t ph; | ||||
| 	char buf2[256], ch, *p; | ||||
|  | ||||
| 	if( !path ) | ||||
| 		return -1; | ||||
| 	 | ||||
| 	if( (ph=OSI_PromPathIface( kPromFindDevice, path )) != -1 ) | ||||
| 		return ph; | ||||
| 	else if( path[0] == '/' ) | ||||
| 		return -1; | ||||
| 	 | ||||
| 	/* might be an alias */ | ||||
| 	if( !(p=strpbrk(path, "@:/")) ) | ||||
| 		p = (char*)path + strlen(path); | ||||
|  | ||||
| 	ch = *p; | ||||
| 	*p = 0; | ||||
| 	if( (ph=prom_get_prop(prom_find_device("/aliases"), path, buf2, sizeof(buf2))) == -1 ) | ||||
| 		return -1; | ||||
| 	*p = ch; | ||||
| 	strncat( buf2, p, sizeof(buf2) ); | ||||
|  | ||||
| 	if( buf2[0] != '/' ) { | ||||
| 		printk("Error: aliases must be absolute!\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	ph = OSI_PromPathIface( kPromFindDevice, buf2 );	 | ||||
| 	return ph; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	search the tree for nodes with matching device_type		*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static mol_phandle_t | ||||
| prom_find_device_type_( mol_phandle_t ph, const char *type, int *icount, int index ) | ||||
| { | ||||
| 	char buf[64]; | ||||
| 	int ph2; | ||||
|  | ||||
| 	if( ph == -1 || !ph ) | ||||
| 		return -1; | ||||
| 	if( prom_get_prop( ph, "device_type", buf, sizeof(buf)) > 0 ) | ||||
| 		if( !strcmp(buf, type) ) | ||||
| 			if( (*icount)++ == index ) | ||||
| 				return ph; | ||||
| 	if( (ph2=prom_find_device_type_( prom_peer(ph), type, icount, index )) != -1 ) | ||||
| 		return ph2; | ||||
| 	if( (ph2=prom_find_device_type_( prom_child(ph), type, icount, index )) != -1 ) | ||||
| 		return ph2; | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| mol_phandle_t | ||||
| prom_find_device_type( const char *type, int index ) | ||||
| { | ||||
| 	int count = 0; | ||||
| 	return prom_find_device_type_( prom_peer(0), type, &count, index ); | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	device tree tweaking						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| /* -1 if error */ | ||||
| int | ||||
| prom_change_phandle( mol_phandle_t old_ph, mol_phandle_t new_ph ) | ||||
| { | ||||
| 	return OSI_PromIface1( kPromChangePHandle, old_ph, (int)new_ph ); | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										47
									
								
								arch/ppc/mol/prom.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								arch/ppc/mol/prom.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2002/10/03 21:07:27 samuel> | ||||
|  *   Time-stamp: <2003/10/22 22:45:26 samuel> | ||||
|  *    | ||||
|  *	<prom.h> | ||||
|  *	 | ||||
|  *	device tree interface | ||||
|  *    | ||||
|  *   Copyright (C) 2002, 2003 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #ifndef _H_PROM | ||||
| #define _H_PROM | ||||
|  | ||||
| /* Note 1: MOL uses -1 as the invalid phandle while OpenFirmware uses 0 as the | ||||
|  * invalid phandle (it is also the root node). | ||||
|  * | ||||
|  * Note 2: phandles might be negative. For instance, phandles originating from | ||||
|  * a real Open Firmware tree might look like 0xff123000 (a ROM address)... | ||||
|  */ | ||||
|  | ||||
| typedef enum { kGetRootPhandle=0 } mol_phandle_t;	/* must promote to int */ | ||||
|  | ||||
| extern int			prom_close( void ); | ||||
|  | ||||
| extern mol_phandle_t		prom_peer( mol_phandle_t phandle ); | ||||
| extern mol_phandle_t		prom_child( mol_phandle_t phandle ); | ||||
| extern mol_phandle_t		prom_parent( mol_phandle_t phandle ); | ||||
| extern int			prom_package_to_path( mol_phandle_t phandle, char *buf, long buflen ); | ||||
| extern int			prom_get_prop_len( mol_phandle_t phandle, const char *name ); | ||||
| extern int			prom_get_prop( mol_phandle_t phandle, const char *name, char *buf, long buflen ); | ||||
| extern int			prom_get_prop_by_path( const char *path, const char *name, char *buf, long buflen ); | ||||
| extern int			prom_next_prop( mol_phandle_t phandle, const char *prev, char *buf ); | ||||
| extern int			prom_set_prop( mol_phandle_t phandle, const char *name, char *buf, long buflen ); | ||||
| extern mol_phandle_t		prom_create_node( const char *path ); | ||||
| extern mol_phandle_t		prom_find_device( const char *path ); | ||||
|  | ||||
| extern mol_phandle_t		prom_find_device_type( const char *type, int index ); | ||||
|  | ||||
| extern int			prom_change_phandle( mol_phandle_t old_ph, mol_phandle_t new_ph ); | ||||
|  | ||||
| #endif   /* _H_PROM */ | ||||
							
								
								
									
										178
									
								
								arch/ppc/mol/pseudodisk.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								arch/ppc/mol/pseudodisk.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,178 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2003/11/26 16:55:47 samuel> | ||||
|  *   Time-stamp: <2004/01/07 19:41:54 samuel> | ||||
|  *    | ||||
|  *	<pseudodisk.c> | ||||
|  *	 | ||||
|  *	pseudodisk (contains files exported from linux) | ||||
|  *    | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "osi_calls.h" | ||||
| #include "libc/string.h" | ||||
| #include "ofmem.h" | ||||
| #include "mol/prom.h" | ||||
| #include "mol/mol.h" | ||||
| #include "osi_calls.h" | ||||
| #include "pseudofs_sh.h" | ||||
|  | ||||
| typedef struct { | ||||
| 	int	seekpos; | ||||
| 	int	fd; | ||||
| 	char	*myargs; | ||||
| 	char	*name; | ||||
| 	int	size; | ||||
| } pdisk_data_t; | ||||
|  | ||||
|  | ||||
| DECLARE_NODE( pdisk, INSTALL_OPEN, sizeof(pdisk_data_t), "/mol/pseudo-disk/disk" ); | ||||
|  | ||||
| static void | ||||
| pdisk_open( pdisk_data_t *pb ) | ||||
| { | ||||
| 	char *ep, *name = NULL; | ||||
| 	int part; | ||||
|  | ||||
| 	pb->myargs = my_args_copy(); | ||||
| 	/* printk("pdisk-open: %s\n", pb->myargs ); */ | ||||
|  | ||||
| 	part = strtol( pb->myargs, &ep, 10 ); | ||||
| 	if( *ep ) { | ||||
| 		if( (name=strchr(pb->myargs, ',')) ) { | ||||
| 			*name = 0; | ||||
| 			name++; | ||||
| 		} else { | ||||
| 			name = pb->myargs; | ||||
| 		} | ||||
| 	} | ||||
| 	if( part ) | ||||
| 		goto err; | ||||
|  | ||||
| 	if( !name || !strlen(name) ) | ||||
| 		pb->fd = -1; | ||||
| 	else { | ||||
| 		if( (pb->fd=PseudoFSOpen(name)) < 0 ) | ||||
| 			goto err; | ||||
| 		pb->size = PseudoFSGetSize( pb->fd ); | ||||
| 	} | ||||
| 	pb->name = name; | ||||
| 	RET( -1 ); | ||||
|  err: | ||||
| 	free( pb->myargs ); | ||||
| 	RET(0); | ||||
| } | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| pdisk_read( pdisk_data_t *pb ) | ||||
| { | ||||
| 	int len = POP(); | ||||
| 	char *dest = (char*)POP(); | ||||
| 	int cnt; | ||||
| 	 | ||||
| 	if( pb->fd < 0 ) { | ||||
| 		memset( dest, 0, len ); | ||||
| 		PUSH(len); | ||||
| 		return; | ||||
| 	} | ||||
| 	/* dest is not "mol-DMA" safe (might have a nontrivial mapping) */ | ||||
| 	for( cnt=0; cnt<len; ) { | ||||
| 		char buf[2048]; | ||||
| 		int n = MIN( len-cnt, sizeof(buf) ); | ||||
|  | ||||
| 		n = PseudoFSRead( pb->fd, pb->seekpos, buf, n ); | ||||
| 		if( n <= 0 ) | ||||
| 			break; | ||||
|  | ||||
| 		memcpy( dest+cnt, buf, n ); | ||||
| 		cnt += n; | ||||
| 		pb->seekpos += n; | ||||
| 	} | ||||
| 	PUSH( cnt ); | ||||
| } | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| pdisk_write( pdisk_data_t *pb ) | ||||
| { | ||||
| 	POP(); POP(); PUSH(-1); | ||||
| 	printk("pdisk write\n"); | ||||
| } | ||||
|  | ||||
| /* ( pos.lo pos.hi -- status ) */ | ||||
| static void | ||||
| pdisk_seek( pdisk_data_t *pb ) | ||||
| { | ||||
| 	int pos_lo; | ||||
| 	POP(); | ||||
| 	pos_lo = POP(); | ||||
|  | ||||
| 	if( pb->fd >= 0 ) { | ||||
| 		if( pos_lo == -1 ) | ||||
| 			pos_lo = pb->size; | ||||
| 	} | ||||
| 	 | ||||
| 	pb->seekpos = pos_lo; | ||||
| 	 | ||||
| 	PUSH(0);	/* ??? */ | ||||
| } | ||||
|  | ||||
| /* ( -- pos.d ) */ | ||||
| static void | ||||
| pdisk_tell( pdisk_data_t *pb ) | ||||
| { | ||||
| 	DPUSH( pb->seekpos ); | ||||
| } | ||||
|  | ||||
| /* ( -- cstr ) */ | ||||
| static void | ||||
| pdisk_get_path( pdisk_data_t *pb ) | ||||
| { | ||||
| 	PUSH( (int)pb->name ); | ||||
| } | ||||
|  | ||||
| /* ( -- cstr ) */ | ||||
| static void | ||||
| pdisk_get_fstype( pdisk_data_t *pb ) | ||||
| { | ||||
| 	PUSH( (int)"PSEUDO" ); | ||||
| } | ||||
|  | ||||
| /* ( -- cstr ) */ | ||||
| static void | ||||
| pdisk_volume_name( pdisk_data_t *pb ) | ||||
| { | ||||
| 	PUSH( (int)"Virtual Volume" ); | ||||
| } | ||||
|  | ||||
| static void | ||||
| pdisk_block_size( pdisk_data_t *pb ) | ||||
| { | ||||
| 	PUSH(1); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( pdisk ) = { | ||||
| 	{ "open",		pdisk_open		}, | ||||
| 	{ "read",		pdisk_read		}, | ||||
| 	{ "write",		pdisk_write		}, | ||||
| 	{ "seek",		pdisk_seek		}, | ||||
| 	{ "tell",		pdisk_tell		}, | ||||
| 	{ "block-size",		pdisk_block_size	}, | ||||
| 	{ "get-path",		pdisk_get_path          }, | ||||
| 	{ "get-fstype",		pdisk_get_fstype        }, | ||||
| 	{ "volume-name",	pdisk_volume_name	}, | ||||
| }; | ||||
|  | ||||
| void | ||||
| pseudodisk_init( void ) | ||||
| { | ||||
| 	REGISTER_NODE( pdisk ); | ||||
| } | ||||
							
								
								
									
										165
									
								
								arch/ppc/mol/tree.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								arch/ppc/mol/tree.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,165 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2003/11/18 14:55:05 samuel> | ||||
|  *   Time-stamp: <2004/03/27 02:03:55 samuel> | ||||
|  *    | ||||
|  *	<tree.c> | ||||
|  *	 | ||||
|  *	device tree setup | ||||
|  *    | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "mol/mol.h" | ||||
| #include "mol/prom.h" | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	copy device tree						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static void | ||||
| copy_node( mol_phandle_t molph ) | ||||
| { | ||||
| 	char name[40], path[80]; | ||||
| 	int exists; | ||||
| 	phandle_t ph; | ||||
| 	 | ||||
| 	if( !molph ) | ||||
| 		return; | ||||
|  | ||||
| 	prom_package_to_path( molph, path, sizeof(path) ); | ||||
|  | ||||
| 	/* don't copy /options node */ | ||||
| 	if( !strcmp("/options", path) ) { | ||||
| 		copy_node( prom_peer(molph) ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	exists = 1; | ||||
| 	if( !(ph=find_dev(path)) ) { | ||||
| 		exists = 0; | ||||
| 		fword("new-device"); | ||||
| 		ph = get_cur_dev(); | ||||
| 	} | ||||
| 	activate_dev( ph ); | ||||
|  | ||||
| 	name[0] = 0; | ||||
| 	while( prom_next_prop(molph, name, name) > 0 ) { | ||||
| 		int len = prom_get_prop_len( molph, name ); | ||||
| 		char *p; | ||||
| #if 0 | ||||
| 		if( len > 0x1000 ) { | ||||
| 			printk("prop to large (%d)\n", len ); | ||||
| 			continue; | ||||
| 		} | ||||
| #endif | ||||
| 		/* don't copy /chosen/{stdin,stdout} (XXX: ugly hack...) */ | ||||
| 		if( !strcmp("/chosen", path) ) | ||||
| 			if( !strcmp("stdio", name) || !strcmp("stdout", name) ) | ||||
| 				continue; | ||||
|  | ||||
| 		p = malloc( len ); | ||||
| 		prom_get_prop( molph, name, p, len ); | ||||
| 		set_property( ph, name, p, len ); | ||||
| 		free( p ); | ||||
| 	} | ||||
|  | ||||
| 	set_int_property( ph, "MOL,phandle", molph ); | ||||
| 	copy_node( prom_child(molph) ); | ||||
| 	 | ||||
| 	if( !exists ) | ||||
| 		fword("finish-device"); | ||||
| 	else | ||||
| 		activate_device(".."); | ||||
|  | ||||
| 	copy_node( prom_peer(molph) ); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	device tree cloning and tweaking				*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static phandle_t | ||||
| translate_molph( mol_phandle_t molph ) | ||||
| { | ||||
| 	static mol_phandle_t cached_molph; | ||||
| 	static phandle_t cached_ph; | ||||
| 	phandle_t ph=0; | ||||
|  | ||||
| 	if( cached_molph == molph ) | ||||
| 		return cached_ph; | ||||
|  | ||||
| 	while( (ph=dt_iterate(ph)) ) | ||||
| 		if( get_int_property(ph, "MOL,phandle", NULL) == molph ) | ||||
| 			break; | ||||
| 	cached_molph = molph; | ||||
| 	cached_ph = ph; | ||||
|  | ||||
| 	if( !ph ) | ||||
| 		printk("failed to translate molph\n"); | ||||
| 	return ph; | ||||
| } | ||||
|  | ||||
| static void | ||||
| fix_phandles( void ) | ||||
| { | ||||
| 	static char *pnames[] = { "interrupt-parent", "interrupt-controller", NULL } ; | ||||
| 	int len, *map; | ||||
| 	phandle_t ph=0; | ||||
| 	char **pp; | ||||
|  | ||||
| 	while( (ph=dt_iterate(ph)) ) { | ||||
| 		for( pp=pnames; *pp; pp++ ) { | ||||
| 			phandle_t *p = (phandle_t*)get_property( ph, *pp, &len ); | ||||
| 			if( len == 4 ) | ||||
| 				*p = translate_molph( *(int*)p ); | ||||
| 		} | ||||
|  | ||||
| 		/* need to fix interrupt map properties too */ | ||||
| 		if( (map=(int*)get_property(ph, "interrupt-map", &len)) ) { | ||||
| 			int i, acells = get_int_property(ph, "#address-cells", NULL); | ||||
| 			int icells = get_int_property(ph, "#interrupt-cells", NULL); | ||||
| 			 | ||||
| 			len /= sizeof(int); | ||||
| 			for( i=0; i<len; i++ ) { | ||||
| 				phandle_t ch_ph; | ||||
| 				int ch_acells, ch_icells; | ||||
|  | ||||
| 				i += acells + icells; | ||||
| 				if( !(ch_ph=translate_molph(map[i])) ) | ||||
| 					break; | ||||
| 				map[i] = (int)ch_ph; | ||||
| 				ch_acells = get_int_property(ch_ph, "#address-cells", NULL); | ||||
| 				ch_icells = get_int_property(ch_ph, "#interrupt-cells", NULL); | ||||
| 				i += ch_acells + icells; | ||||
| 			} | ||||
| 			if( i != len ) | ||||
| 				printk("interrupt map fixing failure\n"); | ||||
| 		} | ||||
| 	} | ||||
| 	/* delete MOL,phandle properties */ | ||||
| 	for( ph=0; (ph=dt_iterate(ph)) ; ) {	 | ||||
| 		push_str("MOL,phandle"); | ||||
| 		PUSH_ph(ph); | ||||
| 		fword("(delete-property)"); | ||||
| 	} | ||||
| 	fword("device-end"); | ||||
| } | ||||
|  | ||||
| void | ||||
| devtree_init( void ) | ||||
| { | ||||
| 	activate_device("/"); | ||||
| 	copy_node( prom_peer(0) ); | ||||
| 	fix_phandles(); | ||||
| 	fword("tree-fixes"); | ||||
| } | ||||
							
								
								
									
										104
									
								
								arch/ppc/mol/tree.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								arch/ppc/mol/tree.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | ||||
|  | ||||
| : int-property ( val name -- ) | ||||
| 	rot encode-int 2swap property | ||||
| ; | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ device-tree | ||||
| \ ------------------------------------------------------------- | ||||
|  | ||||
| " /" find-device | ||||
|  | ||||
|   " device-tree" device-name | ||||
| 	" bootrom" device-type | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ /memory | ||||
| \ ------------------------------------------------------------- | ||||
|  | ||||
| new-device | ||||
|   " memory" device-name | ||||
| 	\ 12230 encode-int " reg" property | ||||
| 	external | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
| 	\ claim ( phys size align -- base ) | ||||
| 	\ release ( phys size -- ) | ||||
| finish-device | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ /mol/ | ||||
| \ ------------------------------------------------------------- | ||||
|  | ||||
| new-device | ||||
| 	" mol" device-name | ||||
| 	1 " #address-cells" int-property | ||||
| 	0 " #size-cells" int-property | ||||
|  | ||||
| 	external | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
|  | ||||
| new-device | ||||
|   " test" device-name | ||||
|  | ||||
| 	external | ||||
|   : open | ||||
| 		." /mol/test opened" cr | ||||
| 		" argument-str" " ipose" find-package drop interpose | ||||
| 		true | ||||
|   ; | ||||
| finish-device | ||||
| finish-device | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ /cpus/ | ||||
| \ ------------------------------------------------------------- | ||||
|  | ||||
| new-device | ||||
| 	" cpus" device-name | ||||
| 	1 " #address-cells" int-property | ||||
| 	0 " #size-cells" int-property | ||||
|  | ||||
| 	external | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
| 	: decode-unit parse-hex ; | ||||
|  | ||||
| finish-device | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ /packages | ||||
| \ ------------------------------------------------------------- | ||||
|  | ||||
| " /packages" find-device | ||||
|  | ||||
| 	" packages" device-name | ||||
| 	external | ||||
| 	\ allow packages to be opened with open-dev | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
|  | ||||
| \ /packages/mol-stdout | ||||
| new-device | ||||
| 	" mol-stdout" device-name | ||||
| 	external | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
| 	: write ( addr len -- actual ) | ||||
| 		dup -rot type | ||||
| 	; | ||||
| finish-device | ||||
|  | ||||
| \ XXXXXXXXXXXXXXXXXXXXXXX TESTING | ||||
| " /" find-device | ||||
| new-device | ||||
|   " test" device-name | ||||
| finish-device | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ The END | ||||
| \ ------------------------------------------------------------- | ||||
| device-end | ||||
|  | ||||
							
								
								
									
										705
									
								
								arch/ppc/ofmem.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										705
									
								
								arch/ppc/ofmem.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,705 @@ | ||||
| /*  | ||||
|  *   Creation Date: <1999/11/07 19:02:11 samuel> | ||||
|  *   Time-stamp: <2004/01/07 19:42:36 samuel> | ||||
|  *    | ||||
|  *	<ofmem.c> | ||||
|  *	 | ||||
|  *	OF Memory manager | ||||
|  *    | ||||
|  *   Copyright (C) 1999-2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *   Copyright (C) 2004 Stefan Reinauer | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| /* TODO: Clean up MOLisms in a decent way */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "libc/string.h" | ||||
| #include "ofmem.h" | ||||
| #include "kernel.h" | ||||
| #ifdef I_WANT_MOLISMS | ||||
| #include "mol/prom.h" | ||||
| #include "mol/mol.h" | ||||
| #endif | ||||
| #include "mmutypes.h" | ||||
| #include "asm/processor.h" | ||||
| #ifdef I_WANT_MOLISMS | ||||
| #include "osi_calls.h" | ||||
| #endif | ||||
|  | ||||
| #define BIT(n)		(1U<<(31-(n))) | ||||
|  | ||||
| /* called from assembly */ | ||||
| extern void	dsi_exception( void ); | ||||
| extern void	isi_exception( void ); | ||||
| extern void	setup_mmu( ulong code_base, ulong code_size, ulong ramsize ); | ||||
|  | ||||
| /**************************************************************** | ||||
|  * Memory usage (before of_quiesce is called) | ||||
|  * | ||||
|  *			Physical | ||||
|  * | ||||
|  *	0x00000000	Exception vectors	 | ||||
|  *	0x00004000	Free space | ||||
|  *	0x01e00000	Open Firmware (us) | ||||
|  *	0x01f00000	OF allocations | ||||
|  *	0x01ff0000	PTE Hash | ||||
|  *	0x02000000-	Free space | ||||
|  * | ||||
|  * Allocations grow downwards from 0x01e00000  | ||||
|  * | ||||
|  ****************************************************************/ | ||||
|  | ||||
| #define HASH_SIZE		(2 << 15) | ||||
| #define SEGR_BASE		0x400		/* segment number range to use */ | ||||
|  | ||||
| #define FREE_BASE_1		0x00004000 | ||||
| #define OF_CODE_START		0x01e00000 | ||||
| /* #define OF_MALLOC_BASE	0x01f00000 */ | ||||
| extern char _end[]; | ||||
| #define OF_MALLOC_BASE		_end | ||||
|  | ||||
| #define HASH_BASE		(0x02000000 - HASH_SIZE) | ||||
| #define FREE_BASE_2		0x02000000 | ||||
|  | ||||
| #define RAMSIZE			0x02000000	/* XXXXXXXXXXXXXXXXXXX FIXME XXXXXXXXXXXXXXX */ | ||||
|  | ||||
| typedef struct alloc_desc { | ||||
| 	struct alloc_desc 	*next; | ||||
| 	int			size;			/* size (including) this struct */ | ||||
| } alloc_desc_t; | ||||
|  | ||||
| typedef struct mem_range { | ||||
| 	struct mem_range	*next; | ||||
| 	ulong			start; | ||||
| 	ulong			size; | ||||
| } range_t; | ||||
|  | ||||
| typedef struct trans { | ||||
| 	struct trans		*next; | ||||
| 	ulong			virt;			/* chain is sorted by virt */ | ||||
| 	ulong			size; | ||||
| 	ulong			phys; | ||||
| 	int			mode; | ||||
| } translation_t; | ||||
|  | ||||
| static struct { | ||||
| 	char 			*next_malloc; | ||||
| 	alloc_desc_t		*mfree;			/* list of free malloc blocks */ | ||||
|  | ||||
| 	range_t			*phys_range; | ||||
| 	range_t			*virt_range; | ||||
|  | ||||
| 	translation_t		*trans;			/* this is really a translation_t */ | ||||
| } ofmem; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	OF private allocations						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| void * | ||||
| malloc( int size )  | ||||
| { | ||||
| 	alloc_desc_t *d, **pp; | ||||
| 	char *ret; | ||||
|  | ||||
| 	if( !size ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	if( !ofmem.next_malloc ) | ||||
| 		ofmem.next_malloc = (char*)OF_MALLOC_BASE; | ||||
| 	 | ||||
| 	if( size & 3 ) | ||||
| 		size += 4 - (size & 3); | ||||
| 	size += sizeof(alloc_desc_t); | ||||
| 	 | ||||
| 	/* look in the freelist */ | ||||
| 	for( pp=&ofmem.mfree; *pp && (**pp).size < size; pp = &(**pp).next ) | ||||
| 		; | ||||
|  | ||||
| 	/* waste at most 4K by taking an entry from the freelist */ | ||||
| 	if( *pp && (**pp).size < size + 0x1000 ) { | ||||
| 		ret = (char*)*pp + sizeof(alloc_desc_t); | ||||
| 		memset( ret, 0, (**pp).size - sizeof(alloc_desc_t) ); | ||||
| 		*pp = (**pp).next; | ||||
| 		return ret; | ||||
| 	} | ||||
|  | ||||
| 	if( (ulong)ofmem.next_malloc + size > HASH_BASE ) { | ||||
| 		printk("out of malloc memory (%x)!\n", size ); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	d = (alloc_desc_t*) ofmem.next_malloc; | ||||
| 	ofmem.next_malloc += size; | ||||
|  | ||||
| 	d->next = NULL; | ||||
| 	d->size = size; | ||||
|  | ||||
| 	ret = (char*)d + sizeof(alloc_desc_t); | ||||
| 	memset( ret, 0, size - sizeof(alloc_desc_t) ); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| void | ||||
| free( void *ptr ) | ||||
| { | ||||
| 	alloc_desc_t **pp, *d; | ||||
|  | ||||
| 	/* it is legal to free NULL pointers (size zero allocations) */ | ||||
| 	if( !ptr ) | ||||
| 		return; | ||||
| 	 | ||||
| 	d = (alloc_desc_t*)(ptr - sizeof(alloc_desc_t)); | ||||
| 	d->next = ofmem.mfree; | ||||
|  | ||||
| 	/* insert in the (sorted) freelist */ | ||||
| 	for( pp=&ofmem.mfree; *pp && (**pp).size < d->size ; pp = &(**pp).next ) | ||||
| 		; | ||||
| 	d->next = *pp; | ||||
| 	*pp = d; | ||||
| } | ||||
|  | ||||
| void * | ||||
| realloc( void *ptr, size_t size )  | ||||
| { | ||||
| 	alloc_desc_t *d = (alloc_desc_t*)(ptr - sizeof(alloc_desc_t)); | ||||
| 	char *p; | ||||
| 	 | ||||
| 	if( !ptr ) | ||||
| 		return malloc( size ); | ||||
| 	if( !size ) { | ||||
| 		free( ptr ); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	p = malloc( size ); | ||||
| 	memcpy( p, ptr, MIN(d->size - sizeof(alloc_desc_t),size) ); | ||||
| 	free( ptr ); | ||||
| 	return p; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	debug 								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #if 0 | ||||
| static void | ||||
| print_range( range_t *r, char *str ) | ||||
| { | ||||
| 	printk("--- Range %s ---\n", str ); | ||||
| 	for( ; r; r=r->next ) | ||||
| 		printk("%08lx - %08lx\n", r->start, r->start + r->size -1 ); | ||||
| 	printk("\n"); | ||||
| } | ||||
|  | ||||
| static void | ||||
| print_phys_range()  | ||||
| { | ||||
| 	print_range( ofmem.phys_range, "phys" ); | ||||
| } | ||||
|  | ||||
| static void | ||||
| print_virt_range()  | ||||
| { | ||||
| 	print_range( ofmem.virt_range, "virt" ); | ||||
| } | ||||
|  | ||||
| static void | ||||
| print_trans( void ) | ||||
| { | ||||
| 	translation_t *t = ofmem.trans; | ||||
|  | ||||
| 	printk("--- Translations ---\n"); | ||||
| 	for( ; t; t=t->next ) | ||||
| 		printk("%08lx -> %08lx [size %lx]\n", t->virt, t->phys, t->size ); | ||||
| 	printk("\n"); | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	misc								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static inline int | ||||
| def_memmode( ulong phys ) | ||||
| { | ||||
| 	/* XXX: Guard bit not set as it should! */ | ||||
| 	if( phys < 0x80000000 || phys >= 0xffc00000 ) | ||||
| 		return 0x02;	/*0xa*/	/* wim GxPp */ | ||||
| 	return 0x6a;		/* WIm GxPp, I/O */ | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	client interface						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static int | ||||
| is_free( ulong ea, ulong size, range_t *r ) | ||||
| { | ||||
| 	if( size == 0 ) | ||||
| 		return 1; | ||||
| 	for( ; r ; r=r->next ) { | ||||
| 		if( r->start + r->size - 1 >= ea && r->start <= ea ) | ||||
| 			return 0; | ||||
| 		if( r->start >= ea && r->start <= ea + size - 1 ) | ||||
| 			return 0; | ||||
| 	} | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static void | ||||
| add_entry_( ulong ea, ulong size, range_t **r ) | ||||
| { | ||||
| 	range_t *nr; | ||||
| 	 | ||||
| 	for( ; *r && (**r).start < ea; r=&(**r).next ) | ||||
| 		; | ||||
| 	nr = (range_t*)malloc( sizeof(range_t) ); | ||||
| 	nr->next = *r; | ||||
| 	nr->start = ea; | ||||
| 	nr->size = size; | ||||
| 	*r = nr; | ||||
| } | ||||
|  | ||||
| static int | ||||
| add_entry( ulong ea, ulong size, range_t **r ) | ||||
| { | ||||
| 	if( !is_free( ea, size, *r ) ) { | ||||
| 		printk("add_entry: range not free!\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	add_entry_( ea, size, r ); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void | ||||
| join_ranges( range_t **rr ) | ||||
| { | ||||
| 	range_t *n, *r = *rr; | ||||
| 	while( r ) { | ||||
| 		if( !(n=r->next) ) | ||||
| 			break; | ||||
|  | ||||
| 		if( r->start + r->size - 1 >= n->start -1 ) { | ||||
| 			int s = n->size + (n->start - r->start - r->size); | ||||
| 			if( s > 0 ) | ||||
| 				r->size += s; | ||||
| 			r->next = n->next; | ||||
| 			free( n ); | ||||
| 			continue; | ||||
| 		} | ||||
| 		r=r->next; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void | ||||
| fill_range( ulong ea, int size, range_t **rr ) | ||||
| { | ||||
| 	add_entry_( ea, size, rr ); | ||||
| 	join_ranges( rr ); | ||||
| } | ||||
|  | ||||
| static ulong | ||||
| find_area( ulong align, ulong size, range_t *r, ulong min, ulong max, int reverse ) | ||||
| { | ||||
| 	ulong base = min; | ||||
| 	range_t *r2; | ||||
| 	 | ||||
| 	if( (align & (align-1)) ) { | ||||
| 		printk("bad alignment %ld\n", align); | ||||
| 		align = 0x1000; | ||||
| 	} | ||||
| 	if( !align ) | ||||
| 		align = 0x1000; | ||||
| 	 | ||||
| 	base = reverse ? max - size : min; | ||||
| 	r2 = reverse ? NULL : r; | ||||
| 	 | ||||
| 	for( ;; ) { | ||||
| 		if( !reverse ) { | ||||
| 			base = (base + align - 1) & ~(align-1); | ||||
| 			if( base < min ) | ||||
| 				base = min; | ||||
| 			if( base + size - 1 >= max -1 ) | ||||
| 				break; | ||||
| 		} else { | ||||
| 			if( base > max - size ) | ||||
| 				base = max - size; | ||||
| 			base -= base & (align-1); | ||||
| 		} | ||||
| 		if( is_free( base, size, r ) ) | ||||
| 			return base; | ||||
|  | ||||
| 		if( !reverse ) { | ||||
| 			if( !r2 ) | ||||
| 				break; | ||||
| 			base = r2->start + r2->size; | ||||
| 			r2 = r2->next; | ||||
| 		} else { | ||||
| 			range_t *rp; | ||||
| 			for( rp=r; rp && rp->next != r2 ; rp=rp->next ) | ||||
| 				; | ||||
| 			r2 = rp; | ||||
| 			if( !r2 ) | ||||
| 				break; | ||||
| 			base = r2->start - size; | ||||
| 		} | ||||
| 	} | ||||
| 	return (ulong)-1; | ||||
| } | ||||
|  | ||||
| static ulong | ||||
| ofmem_claim_phys_( ulong phys, ulong size, ulong align, int min, int max, int reverse ) | ||||
| { | ||||
| 	if( !align ) { | ||||
| 		if( !is_free( phys, size, ofmem.phys_range ) ) { | ||||
| 			printk("Non-free physical memory claimed!\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		add_entry( phys, size, &ofmem.phys_range ); | ||||
| 		return phys; | ||||
| 	} | ||||
| 	phys = find_area( align, size, ofmem.phys_range, min, max, reverse ); | ||||
| 	if( phys == (ulong)-1 ) { | ||||
| 		printk("ofmem_claim_phys - out of space\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	add_entry( phys, size, &ofmem.phys_range ); | ||||
| 	return phys; | ||||
| } | ||||
|  | ||||
| /* if align != 0, phys is ignored. Returns -1 on error */ | ||||
| ulong | ||||
| ofmem_claim_phys( ulong phys, ulong size, ulong align ) | ||||
| { | ||||
| 	/* printk("+ ofmem_claim phys %08lx %lx %ld\n", phys, size, align ); */ | ||||
| 	return ofmem_claim_phys_( phys, size, align, 0, RAMSIZE, 0 ); | ||||
| } | ||||
|  | ||||
| static ulong | ||||
| ofmem_claim_virt_( ulong virt, ulong size, ulong align, int min, int max, int reverse ) | ||||
| { | ||||
| 	if( !align ) { | ||||
| 		if( !is_free( virt, size, ofmem.virt_range ) ) { | ||||
| 			printk("Non-free physical memory claimed!\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		add_entry( virt, size, &ofmem.virt_range ); | ||||
| 		return virt; | ||||
| 	} | ||||
| 	 | ||||
| 	virt = find_area( align, size, ofmem.virt_range, min, max, reverse ); | ||||
| 	if( virt == (ulong)-1 ) { | ||||
| 		printk("ofmem_claim_virt - out of space\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	add_entry( virt, size, &ofmem.virt_range ); | ||||
| 	return virt; | ||||
| } | ||||
|  | ||||
| ulong | ||||
| ofmem_claim_virt( ulong virt, ulong size, ulong align ) | ||||
| { | ||||
| 	/* printk("+ ofmem_claim virt %08lx %lx %ld\n", virt, size, align ); */ | ||||
| 	return ofmem_claim_virt_( virt, size, align, RAMSIZE, 0x80000000, 0 ); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* allocate both physical and virtual space and add a translation */ | ||||
| ulong | ||||
| ofmem_claim( ulong addr, ulong size, ulong align ) | ||||
| { | ||||
| 	ulong virt, phys; | ||||
| 	ulong offs = addr & 0xfff; | ||||
|  | ||||
| 	/* printk("+ ofmem_claim %08lx %lx %ld\n", addr, size, align ); */ | ||||
| 	virt = phys = 0; | ||||
| 	if( !align ) { | ||||
| 		if( is_free(addr, size, ofmem.virt_range) && is_free(addr, size, ofmem.phys_range) ) { | ||||
| 			ofmem_claim_phys_( addr, size, 0, 0, 0, 0 ); | ||||
| 			ofmem_claim_virt_( addr, size, 0, 0, 0, 0 ); | ||||
| 			virt = phys = addr; | ||||
| 		} else { | ||||
| 			printk("**** ofmem_claim failure ***!\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} else { | ||||
| 		if( align < 0x1000 ) | ||||
| 			align = 0x1000; | ||||
| 		phys = ofmem_claim_phys_( addr, size, align, 0, RAMSIZE, 1 /* reverse */ ); | ||||
| 		virt = ofmem_claim_virt_( addr, size, align, 0, RAMSIZE, 1 /* reverse */ ); | ||||
| 		if( phys == (ulong)-1 || virt == (ulong)-1 ) { | ||||
| 			printk("ofmem_claim failed\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		/* printk("...phys = %08lX, virt = %08lX, size = %08lX\n", phys, virt, size ); */ | ||||
| 	} | ||||
|  | ||||
| 	/* align */ | ||||
| 	if( phys & 0xfff ) { | ||||
| 		size += (phys & 0xfff); | ||||
| 		virt -= (phys & 0xfff); | ||||
| 		phys &= ~0xfff; | ||||
| 	} | ||||
| 	if( size & 0xfff ) | ||||
| 		size = (size + 0xfff) & ~0xfff; | ||||
| 	 | ||||
| 	/* printk("...free memory found... phys: %08lX, virt: %08lX, size %lX\n", phys, virt, size ); */ | ||||
| 	ofmem_map( phys, virt, size, def_memmode(phys) ); | ||||
| 	return virt + offs; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	keep track of ea -> phys translations				*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static void | ||||
| split_trans( ulong virt ) | ||||
| { | ||||
| 	translation_t *t, *t2; | ||||
| 	 | ||||
| 	for( t=ofmem.trans; t; t=t->next ) { | ||||
| 		if( virt > t->virt && virt < t->virt + t->size-1 ) { | ||||
| 			t2 = (translation_t*)malloc( sizeof(translation_t) ); | ||||
| 			t2->virt = virt; | ||||
| 			t2->size = t->size - (virt - t->virt); | ||||
| 			t->size = virt - t->virt; | ||||
| 			t2->phys = t->phys + t->size; | ||||
| 			t2->mode = t->mode; | ||||
| 			t2->next = t->next; | ||||
| 			t->next = t2; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int | ||||
| map_page_range( ulong virt, ulong phys, ulong size, int mode ) | ||||
| { | ||||
| 	translation_t *t, **tt; | ||||
| 	 | ||||
| 	split_trans( virt ); | ||||
| 	split_trans( virt + size ); | ||||
|  | ||||
| 	/* detect remappings */ | ||||
| 	for( t=ofmem.trans; t; ) { | ||||
| 		if( virt == t->virt || (virt < t->virt && virt + size > t->virt )) { | ||||
| 			if( t->phys + virt - t->virt != phys ) { | ||||
| 				printk("mapping altered (ea %08lx)\n", t->virt ); | ||||
| 			} else if( t->mode != mode ){ | ||||
| 				printk("mapping mode altered\n"); | ||||
| 			} | ||||
| 			for( tt=&ofmem.trans; *tt != t ; tt=&(**tt).next ) | ||||
| 				; | ||||
| 			*tt = t->next; | ||||
| 			free((char*)t); | ||||
| 			t=ofmem.trans; | ||||
| 			continue; | ||||
| 		} | ||||
| 		t=t->next; | ||||
| 	} | ||||
| 	/* add mapping */ | ||||
| 	for( tt=&ofmem.trans; *tt && (**tt).virt < virt ; tt=&(**tt).next ) | ||||
| 		; | ||||
| 	t = (translation_t*)malloc( sizeof(translation_t) ); | ||||
| 	t->virt = virt; | ||||
| 	t->phys = phys; | ||||
| 	t->size = size; | ||||
| 	t->mode = mode; | ||||
| 	t->next = *tt; | ||||
| 	*tt = t; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| ofmem_map( ulong phys, ulong virt, ulong size, int mode ) | ||||
| { | ||||
| 	/* printk("+ofmem_map: %08lX --> %08lX (size %08lX, mode 0x%02X)\n",  | ||||
| 	   virt, phys, size, mode ); */ | ||||
|         | ||||
| 	if( (phys & 0xfff) || (virt & 0xfff) || (size & 0xfff) ) { | ||||
| 		printk("ofmem_map: Bad parameters (%08lX %08lX %08lX)\n", phys, virt, size ); | ||||
| 		phys &= ~0xfff; | ||||
| 		virt &= ~0xfff; | ||||
| 		size = (size + 0xfff) & ~0xfff; | ||||
| 	} | ||||
| #if 1 | ||||
| 	/* claim any unclaimed virtual memory in the range */ | ||||
| 	fill_range( virt, size, &ofmem.virt_range ); | ||||
| 	/* hmm... we better claim the physical range too */ | ||||
| 	fill_range( phys, size, &ofmem.phys_range ); | ||||
| #endif | ||||
| 	//printk("map_page_range %08lx -> %08lx %08lx\n", virt, phys, size ); | ||||
| 	map_page_range( virt, phys, size, (mode==-1)? def_memmode(phys) : mode ); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* virtual -> physical. */ | ||||
| ulong | ||||
| ofmem_translate( ulong virt, ulong *mode ) | ||||
| { | ||||
| 	translation_t *t; | ||||
| 	 | ||||
| 	for( t=ofmem.trans; t && t->virt <= virt ; t=t->next ) { | ||||
| 		ulong offs; | ||||
| 		if( t->virt + t->size - 1 < virt ) | ||||
| 			continue; | ||||
| 		offs = virt - t->virt; | ||||
| 		*mode = t->mode; | ||||
| 		return t->phys + offs; | ||||
| 	} | ||||
|  | ||||
| 	//printk("ofmem_translate: no translation defined (%08lx)\n", virt); | ||||
| 	//print_trans(); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| /* release memory allocated by ofmem_claim */ | ||||
| void | ||||
| ofmem_release( ulong virt, ulong size ) | ||||
| { | ||||
| 	/* printk("ofmem_release unimplemented (%08lx, %08lx)\n", virt, size ); */ | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	page fault handler						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static ulong | ||||
| ea_to_phys( ulong ea, int *mode ) | ||||
| { | ||||
| 	ulong phys; | ||||
|  | ||||
| 	/* hardcode our translation needs */ | ||||
| 	if( ea >= OF_CODE_START && ea < FREE_BASE_2 ) { | ||||
| 		*mode = def_memmode( ea ); | ||||
| 		return ea; | ||||
| 	} | ||||
| 	if( (phys=ofmem_translate(ea, (ulong*)mode)) == (ulong)-1 ) { | ||||
| #ifdef I_WANT_MOLISMS | ||||
| 		if( ea != 0x80816c00 ) | ||||
| 			printk("ea_to_phys: no translation for %08lx, using 1-1\n", ea ); | ||||
| #endif | ||||
| 		phys = ea; | ||||
| 		*mode = def_memmode( phys ); | ||||
|  | ||||
| #ifdef I_WANT_MOLISMS | ||||
| 		forth_segv_handler( (char*)ea ); | ||||
| 		OSI_Debugger(1); | ||||
| #endif | ||||
| 		/* print_virt_range(); */ | ||||
| 		/* print_phys_range(); */ | ||||
| 		/* print_trans(); */ | ||||
| 	} | ||||
| 	return phys; | ||||
| } | ||||
|  | ||||
| static void | ||||
| hash_page( ulong ea, ulong phys, int mode ) | ||||
| { | ||||
| 	static int next_grab_slot=0; | ||||
| 	ulong *upte, cmp, hash1; | ||||
| 	int i, vsid, found; | ||||
| 	mPTE_t *pp; | ||||
| 	 | ||||
| 	vsid = (ea>>28) + SEGR_BASE; | ||||
| 	cmp = BIT(0) | (vsid << 7) | ((ea & 0x0fffffff) >> 22); | ||||
|  | ||||
| 	hash1 = vsid; | ||||
| 	hash1 ^= (ea >> 12) & 0xffff; | ||||
| 	hash1 &= (HASH_SIZE-1) >> 6; | ||||
|  | ||||
| 	pp = (mPTE_t*)(HASH_BASE + (hash1 << 6)); | ||||
| 	upte = (ulong*)pp; | ||||
| 	 | ||||
| 	/* replace old translation */ | ||||
| 	for( found=0, i=0; !found && i<8; i++ ) | ||||
| 		if( cmp == upte[i*2] ) | ||||
| 			found=1; | ||||
|  | ||||
| 	/* otherwise use a free slot */ | ||||
| 	for( i=0; !found && i<8; i++ ) | ||||
| 		if( !pp[i].v ) | ||||
| 			found=1; | ||||
|  | ||||
| 	/* out of slots, just evict one */ | ||||
| 	if( !found ) { | ||||
| 		i = next_grab_slot + 1; | ||||
| 		next_grab_slot = (next_grab_slot + 1) % 8; | ||||
| 	} | ||||
| 	i--; | ||||
| 	upte[i*2] = cmp; | ||||
| 	upte[i*2+1] = (phys & ~0xfff) | mode; | ||||
|  | ||||
| 	asm volatile( "tlbie %0"  :: "r"(ea) ); | ||||
| } | ||||
|  | ||||
| void | ||||
| dsi_exception( void ) | ||||
| { | ||||
| 	ulong dar, dsisr; | ||||
| 	int mode; | ||||
|  | ||||
| 	asm volatile("mfdar %0" : "=r" (dar) : ); | ||||
| 	asm volatile("mfdsisr %0" : "=r" (dsisr) : );	 | ||||
| 	//printk("dsi-exception @ %08lx <%08lx>\n", dar, dsisr ); | ||||
| 	hash_page( dar, ea_to_phys(dar, &mode), mode ); | ||||
| } | ||||
|  | ||||
| void | ||||
| isi_exception( void ) | ||||
| { | ||||
| 	ulong nip, srr1; | ||||
| 	int mode; | ||||
|  | ||||
| 	asm volatile("mfsrr0 %0" : "=r" (nip) : ); | ||||
| 	asm volatile("mfsrr1 %0" : "=r" (srr1) : );	 | ||||
|  | ||||
| 	//printk("isi-exception @ %08lx <%08lx>\n", nip, srr1 ); | ||||
| 	hash_page( nip, ea_to_phys(nip, &mode), mode ); | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	init / cleanup							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| void | ||||
| setup_mmu( ulong code_base, ulong code_size, ulong ramsize ) | ||||
| { | ||||
| 	ulong sdr1 = HASH_BASE | ((HASH_SIZE-1) >> 16); | ||||
| 	ulong sr_base = (0x20 << 24) | SEGR_BASE; | ||||
| 	ulong msr; | ||||
| 	int i; | ||||
|  | ||||
| 	asm volatile("mtsdr1 %0" :: "r" (sdr1) ); | ||||
| 	for( i=0; i<16; i++ ) { | ||||
| 		int j = i << 28; | ||||
| 		asm volatile("mtsrin %0,%1" :: "r" (sr_base + i), "r" (j) ); | ||||
| 	} | ||||
| 	asm volatile("mfmsr %0" : "=r" (msr) : ); | ||||
| 	msr |= MSR_IR | MSR_DR; | ||||
| 	asm volatile("mtmsr %0" :: "r" (msr) ); | ||||
| } | ||||
|  | ||||
| void | ||||
| ofmem_init( void ) | ||||
| { | ||||
| 	/* In case we can't rely on memory being zero initialized */ | ||||
| 	memset(&ofmem, 0, sizeof(ofmem)); | ||||
|  | ||||
| 	ofmem_claim_phys( 0, FREE_BASE_1, 0 ); | ||||
| 	ofmem_claim_virt( 0, FREE_BASE_1, 0 ); | ||||
| 	ofmem_claim_phys( OF_CODE_START, FREE_BASE_2 - OF_CODE_START, 0 ); | ||||
| 	ofmem_claim_virt( OF_CODE_START, FREE_BASE_2 - OF_CODE_START, 0 ); | ||||
| } | ||||
							
								
								
									
										170
									
								
								arch/ppc/osi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								arch/ppc/osi.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,170 @@ | ||||
| /*  | ||||
|  *   Creation Date: <1999/03/18 03:19:43 samuel> | ||||
|  *   Time-stamp: <2003/12/26 16:58:19 samuel> | ||||
|  *    | ||||
|  *	<os_interface.h> | ||||
|  *	 | ||||
|  *	This file includes definitions for drivers | ||||
|  *	running in the "emulated" OS. (Mainly the 'sc' | ||||
|  *	mechanism of communicating) | ||||
|  *    | ||||
|  *   Copyright (C) 1999, 2000, 2001, 2002, 2003 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #ifndef _H_OSI | ||||
| #define _H_OSI | ||||
|  | ||||
| /* Magic register values loaded into r3 and r4 before the 'sc' assembly instruction */ | ||||
| #define OSI_SC_MAGIC_R3		0x113724FA | ||||
| #define OSI_SC_MAGIC_R4		0x77810F9B | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	Selectors (passed in r5)					*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #define OSI_CALL_AVAILABLE		0 | ||||
| #define OSI_DEBUGGER 			1	/* enter debugger */ | ||||
| /* obsolete OSI_LOG_STR 3 */ | ||||
| #define OSI_CMOUNT_DRV_VOL		4	/* conditionally mount driver volume */ | ||||
| /* obsolete OSI_SCSI_xxx 5-6 */ | ||||
| #define OSI_GET_GMT_TIME		7 | ||||
| #define OSI_MOUSE_CNTRL			8 | ||||
| #define OSI_GET_LOCALTIME		9	/* return time in secs from 01/01/04 */ | ||||
|  | ||||
| #define OSI_ENET_OPEN			10 | ||||
| #define OSI_ENET_CLOSE			11 | ||||
| #define OSI_ENET_GET_ADDR		12 | ||||
| #define OSI_ENET_GET_STATUS		13 | ||||
| #define OSI_ENET_CONTROL		14 | ||||
| #define OSI_ENET_ADD_MULTI		16 | ||||
| #define OSI_ENET_DEL_MULTI		17 | ||||
| #define OSI_ENET_GET_PACKET		18 | ||||
| #define OSI_ENET_SEND_PACKET		19 | ||||
|  | ||||
| #define OSI_OF_INTERFACE		20 | ||||
| #define OSI_OF_TRAP			21 | ||||
| #define OSI_OF_RTAS			22 | ||||
|  | ||||
| #define OSI_SCSI_CNTRL			23 | ||||
| #define OSI_SCSI_SUBMIT			24 | ||||
| #define OSI_SCSI_ACK			25 | ||||
|  | ||||
| #define OSI_GET_MOUSE			26	/* -- r3 status, r4-r8 mouse data */ | ||||
| #define OSI_ACK_MOUSE_IRQ		27	/* -- int */ | ||||
|  | ||||
| #define OSI_SET_VMODE			28	/* modeID, depth -- error */ | ||||
| #define OSI_GET_VMODE_INFO		29	/* mode, depth -- r3 status, r4-r9 pb */ | ||||
| #define OSI_GET_MOUSE_DPI		30	/* -- mouse_dpi */ | ||||
|  | ||||
| #define OSI_SET_VIDEO_POWER		31 | ||||
| #define OSI_GET_FB_INFO			32	/* void -- r3 status, r4-r8 video data */ | ||||
|  | ||||
| #define OSI_SOUND_WRITE			33 | ||||
| /* #define OSI_SOUND_FORMAT 34 */ | ||||
| #define OSI_SOUND_SET_VOLUME		35 | ||||
| #define OSI_SOUND_CNTL			36 | ||||
| /* obsolete OSI_SOUND call 37 */ | ||||
|  | ||||
| #define OSI_VIDEO_ACK_IRQ		38 | ||||
| #define OSI_VIDEO_CNTRL			39 | ||||
|  | ||||
| #define OSI_SOUND_IRQ_ACK		40 | ||||
| #define OSI_SOUND_START_STOP		41 | ||||
|  | ||||
| #define OSI_REGISTER_IRQ		42	/* reg_property[0] appl_int -- irq_cookie */ | ||||
| /* obsolete OSI_IRQ 43-46 */ | ||||
|  | ||||
| #define OSI_LOG_PUTC			47	/* char -- */ | ||||
|  | ||||
| #define OSI_KBD_CNTRL			50 | ||||
| #define OSI_GET_ADB_KEY			51	/* -- adb_keycode (keycode | keycode_id in r4) */ | ||||
|  | ||||
| #define OSI_WRITE_NVRAM_BYTE		52	/* offs, byte -- */ | ||||
| #define OSI_READ_NVRAM_BYTE		53	/* offs -- byte */ | ||||
|  | ||||
| #define OSI_EXIT			54 | ||||
|  | ||||
| #define OSI_KEYCODE_TO_ADB		55	/* (keycode | keycode_id) -- adb_keycode */ | ||||
| #define OSI_MAP_ADB_KEY			56	/* keycode, adbcode -- */ | ||||
| #define OSI_SAVE_KEYMAPPING		57	/* -- */ | ||||
| #define OSI_USLEEP			58	/* usecs -- */ | ||||
| #define OSI_SET_COLOR			59	/* index value -- */ | ||||
|  | ||||
| #define OSI_PIC_MASK_IRQ		60	/* irq -- */ | ||||
| #define OSI_PIC_UNMASK_IRQ		61	/* irq -- */ | ||||
| #define OSI_PIC_ACK_IRQ			62	/* irq mask_flag -- */ | ||||
| #define OSI_PIC_GET_ACTIVE_IRQ		63 | ||||
|  | ||||
| #define OSI_GET_COLOR			64	/* index -- value */ | ||||
|  | ||||
| /* 65-67 old ablk implementation */ | ||||
| #define OSI_IRQTEST			65 | ||||
|  | ||||
| #define OSI_ENET2_OPEN			68 | ||||
| #define OSI_ENET2_CLOSE			69 | ||||
| #define OSI_ENET2_CNTRL			70 | ||||
| #define OSI_ENET2_RING_SETUP		71 | ||||
| #define OSI_ENET2_KICK			72 | ||||
| #define OSI_ENET2_GET_HWADDR		73 | ||||
| #define OSI_ENET2_IRQ_ACK		74 | ||||
|  | ||||
| #define OSI_PROM_IFACE			76 | ||||
| #define  kPromClose		0 | ||||
| #define  kPromPeer		1 | ||||
| #define  kPromChild		2 | ||||
| #define  kPromParent		3 | ||||
| #define  kPromPackageToPath	4 | ||||
| #define  kPromGetPropLen	5 | ||||
| #define  kPromGetProp		6 | ||||
| #define  kPromNextProp		7 | ||||
| #define  kPromSetProp		8 | ||||
| #define  kPromChangePHandle	9 | ||||
|  | ||||
| #define OSI_PROM_PATH_IFACE		77 | ||||
| #define  kPromCreateNode	16 | ||||
| #define  kPromFindDevice	17 | ||||
|  | ||||
| #define OSI_BOOT_HELPER			78 | ||||
| #define  kBootHAscii2Unicode	32 | ||||
| #define  kBootHUnicode2Ascii	33 | ||||
| #define  kBootHGetStrResInd	34		/* key, buf, len -- buf */ | ||||
| #define  kBootHGetRAMSize	35		/* -- ramsize */ | ||||
|  | ||||
| #define OSI_ABLK_RING_SETUP		79 | ||||
| #define OSI_ABLK_CNTRL			80 | ||||
| #define OSI_ABLK_DISK_INFO		81 | ||||
| #define OSI_ABLK_KICK			82 | ||||
| #define OSI_ABLK_IRQ_ACK		83 | ||||
| #define OSI_ABLK_SYNC_READ		84 | ||||
| #define OSI_ABLK_SYNC_WRITE		85 | ||||
| #define OSI_ABLK_BLESS_DISK		86 | ||||
|  | ||||
| #define OSI_EMUACCEL			89	/* EMULATE_xxx, nip -- index */ | ||||
| #define OSI_MAPIN_MREGS			90	/* mphys */ | ||||
| #define OSI_NVRAM_SIZE			91 | ||||
|  | ||||
| #define OSI_MTICKS_TO_USECS		92 | ||||
| #define OSI_USECS_TO_MTICKS		93 | ||||
|  | ||||
| /* obsolete OSI_BLK 94-95 */ | ||||
|  | ||||
| #define OSI_PSEUDO_FS			96 | ||||
| #define  kPseudoFSOpen		1 | ||||
| #define  kPseudoFSClose		2 | ||||
| #define  kPseudoFSGetSize	3 | ||||
| #define  kPseudoFSRead		4 | ||||
| #define  kPseudoFSIndex2Name	5 | ||||
|  | ||||
| #define OSI_TTY_PUTC			97 | ||||
| #define OSI_TTY_GETC			98 | ||||
| #define OSI_TTY_IRQ_ACK			99 | ||||
|  | ||||
| #define NUM_OSI_SELECTORS		100	/* remember to increase this... */ | ||||
|  | ||||
| #endif   /* _H_OSI */ | ||||
							
								
								
									
										454
									
								
								arch/ppc/osi_calls.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										454
									
								
								arch/ppc/osi_calls.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,454 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2002/06/16 01:40:57 samuel> | ||||
|  *   Time-stamp: <2003/12/26 17:02:09 samuel> | ||||
|  *    | ||||
|  *	<osi_calls.h> | ||||
|  *	 | ||||
|  *	OSI call inlines | ||||
|  *    | ||||
|  *   Copyright (C) 2002, 2003 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #ifndef _H_OSI_CALLS | ||||
| #define _H_OSI_CALLS | ||||
|  | ||||
| #include "osi.h" | ||||
|  | ||||
| /* Old gcc versions have a limit on the number of registers used. | ||||
|  * Newer gcc versions (gcc 3.3) require that the clobber list does | ||||
|  * not overlap declared registers. | ||||
|  */ | ||||
| #if __GNUC__ == 2 || ( __GNUC__ == 3 && __GNUC_MINOR__ < 3 ) | ||||
| #define SHORT_REGLIST | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	OSI call instantiation macros					*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #define dreg(n)			__oc_##n __asm__ (#n) | ||||
| #define ir(n)			"r" (__oc_##n) | ||||
| #define rr(n)			"=r" (__oc_##n) | ||||
|  | ||||
| #define _oc_head( input_regs... )				\ | ||||
| {								\ | ||||
| 	int _ret=0;						\ | ||||
| 	{							\ | ||||
| 		register unsigned long dreg(r3);		\ | ||||
| 		register unsigned long dreg(r4);		\ | ||||
| 		register unsigned long dreg(r5)			\ | ||||
| 			,##input_regs ;  | ||||
|  | ||||
| #define _oc_syscall( number, extra_ret_regs... )		\ | ||||
| 		__oc_r3 = OSI_SC_MAGIC_R3;			\ | ||||
| 		__oc_r4 = OSI_SC_MAGIC_R4;			\ | ||||
| 		__oc_r5 = number;				\ | ||||
| 		__asm__ __volatile__ (				\ | ||||
| 		  "sc	" : rr(r3) ,## extra_ret_regs | ||||
|  | ||||
| #define _oc_input( regs... )					\ | ||||
| 		: ir(r3), ir(r4), ir(r5)			\ | ||||
| 		, ## regs					\ | ||||
| 		: "memory" ); | ||||
|  | ||||
| /* the tail memory clobber is necessary since we violate the strict | ||||
|  * aliasing rules when we return structs through the registers. | ||||
|  */ | ||||
| #define _oc_tail						\ | ||||
| 		asm volatile ( "" : : : "memory" );		\ | ||||
| 		_ret = __oc_r3;					\ | ||||
| 	}							\ | ||||
| 	return _ret;						\ | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	Alternatives 							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #ifdef SHORT_REGLIST | ||||
| #define _oc_syscall_r10w6( number, inputregs... )		\ | ||||
| 		__oc_r3 = OSI_SC_MAGIC_R3;			\ | ||||
| 		__oc_r4 = OSI_SC_MAGIC_R4;			\ | ||||
| 		__oc_r5 = number;				\ | ||||
| 		__asm__ __volatile__ (				\ | ||||
| 		  "sc			\n"			\ | ||||
| 		  "stw	4,0(10) 	\n"			\ | ||||
| 		  "stw	5,4(10) 	\n"			\ | ||||
| 		  "stw	6,8(10) 	\n"			\ | ||||
| 		  "stw	7,12(10) 	\n"			\ | ||||
| 		  "stw	8,16(10) 	\n"			\ | ||||
| 		  "stw	9,20(10) 	\n"			\ | ||||
| 		: rr(r3)					\ | ||||
| 		: ir(r3), ir(r4), ir(r5), ir(r10) 		\ | ||||
| 		  ,## inputregs 				\ | ||||
| 		: "memory",					\ | ||||
| 		   "r4", "r5", "r6", "r7", "r8", "r9" ); | ||||
| #endif		    | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	Common helper functions						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #define _osi_call0( type, name, number ) 			\ | ||||
| type name( void ) 						\ | ||||
| 	_oc_head()						\ | ||||
| 	_oc_syscall( number )					\ | ||||
| 	_oc_input()						\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #define _osi_call1( type, name, number, type1, arg1 ) 		\ | ||||
| type name( type1 arg1 ) 					\ | ||||
| 	_oc_head( dreg(r6) )					\ | ||||
| 	__oc_r6 = (ulong)arg1;					\ | ||||
| 	_oc_syscall( number )					\ | ||||
| 	_oc_input( ir(r6) )					\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #define _osi_call2( type, name, number, t1, a1, t2, a2 ) 	\ | ||||
| type name( t1 a1, t2 a2 ) 					\ | ||||
| 	_oc_head( dreg(r6), dreg(r7) )				\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	__oc_r7 = (ulong)a2;					\ | ||||
| 	_oc_syscall( number )					\ | ||||
| 	_oc_input( ir(r6), ir(r7) )				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #define _osi_call3( type, name, number, t1, a1, t2, a2, t3, a3 ) \ | ||||
| type name( t1 a1, t2 a2, t3 a3 ) 				\ | ||||
| 	_oc_head( dreg(r6), dreg(r7), dreg(r8) )		\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	__oc_r7 = (ulong)a2;					\ | ||||
| 	__oc_r8 = (ulong)a3;					\ | ||||
| 	_oc_syscall( number )					\ | ||||
| 	_oc_input( ir(r6), ir(r7), ir(r8) )			\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #define _osi_call4( type, name, number, t1, a1, t2, a2, t3, a3, t4, a4 ) \ | ||||
| type name( t1 a1, t2 a2, t3 a3, t4 a4 ) 			\ | ||||
| 	_oc_head( dreg(r6), dreg(r7), dreg(r8), dreg(r9) )	\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	__oc_r7 = (ulong)a2;					\ | ||||
| 	__oc_r8 = (ulong)a3;					\ | ||||
| 	__oc_r9 = (ulong)a4;					\ | ||||
| 	_oc_syscall( number )					\ | ||||
| 	_oc_input( ir(r6), ir(r7), ir(r8), ir(r9) )		\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #define _osi_call5( type, name, number, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5 ) \ | ||||
| type name( t1 a1, t2 a2, t3 a3, t4 a4, t5 a5 ) 				\ | ||||
| 	_oc_head( dreg(r6), dreg(r7), dreg(r8), dreg(r9), dreg(r10) )	\ | ||||
| 	__oc_r6 = (ulong)a1;						\ | ||||
| 	__oc_r7 = (ulong)a2;						\ | ||||
| 	__oc_r8 = (ulong)a3;						\ | ||||
| 	__oc_r9 = (ulong)a4;						\ | ||||
| 	__oc_r10 = (ulong)a5;						\ | ||||
| 	_oc_syscall( number )						\ | ||||
| 	_oc_input( ir(r6), ir(r7), ir(r8), ir(r9), ir(r10) )		\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #define _osi_call6( type, name, number, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6 ) \ | ||||
| type name( t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6 ) 				\ | ||||
| 	_oc_head( dreg(r6), dreg(r7), dreg(r8), dreg(r9), dreg(r10), dreg(r11) )\ | ||||
| 	__oc_r6 = (ulong)a1;						\ | ||||
| 	__oc_r7 = (ulong)a2;						\ | ||||
| 	__oc_r8 = (ulong)a3;						\ | ||||
| 	__oc_r9 = (ulong)a4;						\ | ||||
| 	__oc_r10 = (ulong)a5;						\ | ||||
| 	__oc_r11 = (ulong)a6;						\ | ||||
| 	_oc_syscall( number )						\ | ||||
| 	_oc_input( ir(r6), ir(r7), ir(r8), ir(r9), ir(r10), ir(r11) )	\ | ||||
| 	_oc_tail | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	Special 							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| /* r4 returned in retarg1 pointer */ | ||||
| #define _osi_call0_w1( type, name, number, type1, retarg1 ) 	\ | ||||
| type name( type1 retarg1 ) 					\ | ||||
| 	_oc_head()						\ | ||||
| 	_oc_syscall( number, rr(r4) )				\ | ||||
| 	_oc_input()						\ | ||||
| 	*retarg1 = __oc_r4;					\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #define _osi_call0_w2( type, name, number, type1, retarg1 ) 	\ | ||||
| type name( type1 retarg1 ) 					\ | ||||
| 	_oc_head()						\ | ||||
| 	_oc_syscall( number, rr(r4), rr(r5) )			\ | ||||
| 	_oc_input()						\ | ||||
| 	((ulong*)retarg1)[0] = __oc_r4;				\ | ||||
| 	((ulong*)retarg1)[1] = __oc_r5;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| /* r4-r8 returned in retarg1 pointer */ | ||||
| #define _osi_call0_w5( type, name, number, type1, retarg1 ) 	\ | ||||
| type name( type1 retarg1 ) 					\ | ||||
| 	_oc_head( dreg(r6), dreg(r7), dreg(r8) )		\ | ||||
| 	_oc_syscall( number, 					\ | ||||
| 		rr(r4), rr(r5), rr(r6), rr(r7), rr(r8) )	\ | ||||
| 	_oc_input()						\ | ||||
| 	((ulong*)retarg1)[0] = __oc_r4;				\ | ||||
| 	((ulong*)retarg1)[1] = __oc_r5;				\ | ||||
| 	((ulong*)retarg1)[2] = __oc_r6;				\ | ||||
| 	((ulong*)retarg1)[3] = __oc_r7;				\ | ||||
| 	((ulong*)retarg1)[4] = __oc_r8;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| /* r4 returned in retarg pointer */ | ||||
| #define _osi_call1_w1( type, name, number, t1, a1, t2, retarg ) \ | ||||
| type name( t1 a1, t2 retarg ) 					\ | ||||
| 	_oc_head( dreg(r6) )					\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	_oc_syscall( number, rr(r4) )				\ | ||||
| 	_oc_input( ir(r6) )					\ | ||||
| 	((ulong*)retarg)[0] = __oc_r4;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| /* r4,r5 returned in retarg1, retarg2 */ | ||||
| #define _osi_call1_w1w1( type, name, number, t1, a1, t2, retarg1, t3, retarg2 ) \ | ||||
| type name( t1 a1, t2 retarg1, t3 retarg2 )			\ | ||||
| 	_oc_head( dreg(r6) )					\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	_oc_syscall( number, rr(r4), rr(r5) )			\ | ||||
| 	_oc_input( ir(r6) )					\ | ||||
| 	((ulong*)retarg1)[0] = __oc_r4;				\ | ||||
| 	((ulong*)retarg2)[0] = __oc_r5;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| /* r4,r5 returned in retarg1, retarg2, retarg3 */ | ||||
| #define _osi_call1_w1w1w1( type, name, number, t1, a1, t2, retarg1, t3, retarg2, t4, retarg3 ) \ | ||||
| type name( t1 a1, t2 retarg1, t3 retarg2, t4 retarg3 )		\ | ||||
| 	_oc_head( dreg(r6) )					\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	_oc_syscall( number, rr(r4), rr(r5), rr(r6) )		\ | ||||
| 	_oc_input( ir(r6) )					\ | ||||
| 	((ulong*)retarg1)[0] = __oc_r4;				\ | ||||
| 	((ulong*)retarg2)[0] = __oc_r5;				\ | ||||
| 	((ulong*)retarg3)[0] = __oc_r6;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| /* r4,r5 returned in retarg pointer */ | ||||
| #define _osi_call1_w2( type, name, number, t1, a1, t2, retarg ) \ | ||||
| type name( t1 a1, t2 retarg ) 					\ | ||||
| 	_oc_head( dreg(r6) )					\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	_oc_syscall( number, rr(r4), rr(r5) )			\ | ||||
| 	_oc_input( ir(r6) )					\ | ||||
| 	((ulong*)retarg)[0] = __oc_r4;				\ | ||||
| 	((ulong*)retarg)[1] = __oc_r5;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| /* r4-r7 returned in retarg pointer */ | ||||
| #define _osi_call1_w4( type, name, number, t1, a1, t2, retarg ) \ | ||||
| type name( t1 a1, t2 retarg )					\ | ||||
| 	_oc_head( dreg(r6), dreg(r7) )				\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	_oc_syscall( number, rr(r4), rr(r5), rr(r6), rr(r7) )	\ | ||||
| 	_oc_input( ir(r6) )					\ | ||||
| 	((ulong*)retarg)[0] = __oc_r4;				\ | ||||
| 	((ulong*)retarg)[1] = __oc_r5;				\ | ||||
| 	((ulong*)retarg)[2] = __oc_r6;				\ | ||||
| 	((ulong*)retarg)[3] = __oc_r7;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
|  | ||||
| /* r4-r5 returned in retarg pointer */ | ||||
| #define _osi_call2_w2( type, name, number, t1, a1, t2, a2, t3, retarg ) \ | ||||
| type name( t1 a1, t2 a2, t3 retarg ) 				\ | ||||
| 	_oc_head( dreg(r6), dreg(r7) )				\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	__oc_r7 = (ulong)a2;					\ | ||||
| 	_oc_syscall( number, rr(r4), rr(r5) )			\ | ||||
| 	_oc_input( ir(r6), ir(r7) )				\ | ||||
| 	((ulong*)retarg)[0] = __oc_r4;				\ | ||||
| 	((ulong*)retarg)[1] = __oc_r5;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| /* r4-r7 returned in retarg pointer */ | ||||
| #define _osi_call2_w4( type, name, number, t1, a1, t2, a2, t3, retarg ) \ | ||||
| type name( t1 a1, t2 a2, t3 retarg ) 				\ | ||||
| 	_oc_head( dreg(r6), dreg(r7) )				\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	__oc_r7 = (ulong)a2;					\ | ||||
| 	_oc_syscall( number, rr(r4), rr(r5), rr(r6), rr(r7) )	\ | ||||
| 	_oc_input( ir(r6), ir(r7) )				\ | ||||
| 	((ulong*)retarg)[0] = __oc_r4;				\ | ||||
| 	((ulong*)retarg)[1] = __oc_r5;				\ | ||||
| 	((ulong*)retarg)[2] = __oc_r6;				\ | ||||
| 	((ulong*)retarg)[3] = __oc_r7;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #ifdef SHORT_REGLIST | ||||
| /* r4-r9 returned in retarg pointer */ | ||||
| #define _osi_call2_w6( type, name, number, t1, a1, t2, a2, t3, retarg ) \ | ||||
| type name( t1 a1, t2 a2, t3 retarg ) 				\ | ||||
| 	_oc_head( dreg(r6), dreg(r7), dreg(r10) )		\ | ||||
|         __oc_r6 = (ulong)a1;					\ | ||||
|         __oc_r7 = (ulong)a2;					\ | ||||
| 	__oc_r10 = (ulong)retarg;				\ | ||||
| 	_oc_syscall_r10w6( number, ir(r6), ir(r7) )		\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #else /* SHORT_REGLIST */ | ||||
|  | ||||
| /* r4-r9 returned in retarg pointer */ | ||||
| #define _osi_call2_w6( type, name, number, t1, a1, t2, a2, t3, retarg ) \ | ||||
| type name( t1 a1, t2 a2, t3 retarg ) 				\ | ||||
| 	_oc_head( dreg(r6), dreg(r7), dreg(r8), dreg(r9) )	\ | ||||
| 	__oc_r6 = (ulong)a1;					\ | ||||
| 	__oc_r7 = (ulong)a2;					\ | ||||
| 	_oc_syscall( number, rr(r4), rr(r5), rr(r6), rr(r7), rr(r8), rr(r9) )	\ | ||||
| 	_oc_input( ir(r6), ir(r7) )				\ | ||||
| 	((ulong*)retarg)[0] = __oc_r4;				\ | ||||
| 	((ulong*)retarg)[1] = __oc_r5;				\ | ||||
| 	((ulong*)retarg)[2] = __oc_r6;				\ | ||||
| 	((ulong*)retarg)[3] = __oc_r7;				\ | ||||
| 	((ulong*)retarg)[4] = __oc_r8;				\ | ||||
| 	((ulong*)retarg)[5] = __oc_r9;				\ | ||||
| 	_oc_tail | ||||
|  | ||||
| #endif /* SHORT_REGLIST */ | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	OSI call inlines						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static inline _osi_call1( int, OSI_CallAvailable, OSI_CALL_AVAILABLE, int, osi_num ); | ||||
|  | ||||
| static inline _osi_call1( int, OSI_PutC, OSI_LOG_PUTC, int, ch ); | ||||
|  | ||||
| static inline _osi_call1( int, OSI_Debugger, OSI_DEBUGGER, int, num ); | ||||
| static inline _osi_call0( int, OSI_Exit, OSI_EXIT ); | ||||
|  | ||||
| /* misc */ | ||||
| static inline _osi_call0( ulong, OSI_GetLocalTime, OSI_GET_LOCALTIME ); | ||||
| static inline _osi_call0( ulong, OSI_GetGMTTime, OSI_GET_GMT_TIME ); | ||||
| static inline _osi_call1( int, OSI_USleep, OSI_USLEEP, int, usecs ); | ||||
|  | ||||
| /* NVRAM */ | ||||
| static inline _osi_call0( int, OSI_NVRamSize, OSI_NVRAM_SIZE ); | ||||
| static inline _osi_call1( int, OSI_ReadNVRamByte, OSI_READ_NVRAM_BYTE, int, offs ); | ||||
| static inline _osi_call2( int, OSI_WriteNVRamByte, OSI_WRITE_NVRAM_BYTE, int, offs,  | ||||
| 			  unsigned char, ch ); | ||||
|  | ||||
| /* keyboard stuff */ | ||||
| static inline _osi_call0_w1( int, OSI_GetAdbKey2, OSI_GET_ADB_KEY, int *, raw_key ); | ||||
| static inline _osi_call1( int, OSI_KbdCntrl, OSI_KBD_CNTRL, int, cmd ); | ||||
|  | ||||
| static inline int OSI_GetAdbKey( void )  | ||||
| 	{ int dummy_raw_key; return OSI_GetAdbKey2( &dummy_raw_key ); } | ||||
| static inline _osi_call2( int, OSI_MapAdbKey, OSI_MAP_ADB_KEY, int, keycode, int, adbkey ) | ||||
| static inline _osi_call1( int, OSI_KeycodeToAdb, OSI_KEYCODE_TO_ADB, int, keycode ); | ||||
| static inline _osi_call0( int, OSI_SaveKeymapping, OSI_SAVE_KEYMAPPING ); | ||||
|  | ||||
| /* mouse support */ | ||||
| struct osi_mouse; | ||||
| static inline _osi_call0_w5( int, OSI_GetMouse, OSI_GET_MOUSE, struct osi_mouse *, ret ); | ||||
| static inline _osi_call0( int, OSI_GetMouseDPI, OSI_GET_MOUSE_DPI ); | ||||
|  | ||||
| /* video */ | ||||
| static inline _osi_call2( int, OSI_SetVMode_, OSI_SET_VMODE, int, mode, int, depth_mode ); | ||||
| struct osi_get_vmode_info; | ||||
| static inline _osi_call2_w6( int, OSI_GetVModeInfo_, OSI_GET_VMODE_INFO, int, mode, int, depth_mode, | ||||
| 			     struct osi_get_vmode_info *, ret ); | ||||
| static inline _osi_call1( int, OSI_SetVPowerState, OSI_SET_VIDEO_POWER, int, power_state ); | ||||
| static inline _osi_call2( int, OSI_SetColor, OSI_SET_COLOR, int, index, int, rgb ); | ||||
| static inline _osi_call0_w1( int, OSI_VideoAckIRQ, OSI_VIDEO_ACK_IRQ, int *, events ); | ||||
|  | ||||
| static inline void OSI_RefreshPalette( void ) { OSI_SetColor(-1,0); } | ||||
|  | ||||
| /* PIC (mac-io replacement) */ | ||||
| static inline _osi_call1( int, OSI_PICMaskIRQ, OSI_PIC_MASK_IRQ, int, irq ); | ||||
| static inline _osi_call1( int, OSI_PICUnmaskIRQ, OSI_PIC_UNMASK_IRQ, int, irq ); | ||||
| static inline _osi_call2( int, OSI_PICAckIRQ, OSI_PIC_ACK_IRQ, int, irq, int, mask_it ); | ||||
| static inline _osi_call0( int, OSI_PICGetActiveIRQ, OSI_PIC_GET_ACTIVE_IRQ ); | ||||
|  | ||||
| /* sound */ | ||||
| static inline _osi_call1( int, OSI_SoundCntl, OSI_SOUND_CNTL, int, cmd ); | ||||
| static inline _osi_call2( int, OSI_SoundCntl1, OSI_SOUND_CNTL, int, cmd, int, p1 ); | ||||
| static inline _osi_call3( int, OSI_SoundCntl2, OSI_SOUND_CNTL, int, cmd, int, p1, int, p2 ); | ||||
| static inline _osi_call0_w2( int, OSI_SoundIRQAck, OSI_SOUND_IRQ_ACK, ulong *, timestamp ); | ||||
| static inline _osi_call3( int, OSI_SoundWrite, OSI_SOUND_WRITE, int, physbuf, int, len, int, restart ); | ||||
| static inline _osi_call3( int, OSI_SoundSetVolume, OSI_SOUND_SET_VOLUME, int, hwvol, int, speakervol, int, mute ); | ||||
|  | ||||
| /* async block driver */ | ||||
| struct ablk_disk_info; | ||||
| static inline _osi_call2_w4( int, OSI_ABlkDiskInfo, OSI_ABLK_DISK_INFO, int, channel, int, unit, | ||||
| 			     struct ablk_disk_info *, retinfo ); | ||||
| static inline _osi_call1( int, OSI_ABlkKick, OSI_ABLK_KICK, int, channel ); | ||||
| static inline _osi_call1_w1w1w1( int, OSI_ABlkIRQAck, OSI_ABLK_IRQ_ACK, int, channel, int *, req_count,  | ||||
| 			       int *, active, int *, events ); | ||||
| static inline _osi_call3( int, OSI_ABlkRingSetup, OSI_ABLK_RING_SETUP, int, channel, int, mphys, int, n_el ); | ||||
| static inline _osi_call2( int, OSI_ABlkCntrl, OSI_ABLK_CNTRL, int, channel, int, cmd ); | ||||
| static inline _osi_call3( int, OSI_ABlkCntrl1, OSI_ABLK_CNTRL, int, channel, int, cmd, int, param ); | ||||
| static inline _osi_call5( int, OSI_ABlkSyncRead, OSI_ABLK_SYNC_READ, int, channel, int, unit,  | ||||
| 			  int, blk, ulong, mphys, int, size ); | ||||
| static inline _osi_call5( int, OSI_ABlkSyncWrite, OSI_ABLK_SYNC_WRITE, int, channel, int, unit, | ||||
| 			  int, blk, ulong, mphys, int, size ); | ||||
| static inline _osi_call2( int, OSI_ABlkBlessDisk, OSI_ABLK_BLESS_DISK, int, channel, int, unit ); | ||||
|  | ||||
| static inline _osi_call0( int, OSI_CMountDrvVol, OSI_CMOUNT_DRV_VOL ); | ||||
|  | ||||
| /* enet2 */ | ||||
| static inline _osi_call0( int, OSI_Enet2Open, OSI_ENET2_OPEN ); | ||||
| static inline _osi_call0( int, OSI_Enet2Close, OSI_ENET2_CLOSE ); | ||||
| static inline _osi_call3( int, OSI_Enet2RingSetup, OSI_ENET2_RING_SETUP, int, which_ring,  | ||||
| 			  int, ring_mphys, int, n_el ); | ||||
| static inline _osi_call2( int, OSI_Enet2Cntrl1, OSI_ENET2_CNTRL, int, cmd, int, param ); | ||||
| static inline _osi_call1( int, OSI_Enet2Cntrl, OSI_ENET2_CNTRL, int, cmd ); | ||||
| static inline _osi_call0( int, OSI_Enet2Kick, OSI_ENET2_KICK ); | ||||
|  | ||||
| static inline _osi_call0_w2( int, OSI_Enet2GetHWAddr__, OSI_ENET2_GET_HWADDR, ulong *, retbuf ); | ||||
| static inline int OSI_Enet2GetHWAddr( unsigned char *addr ) { | ||||
| 	int ret;  | ||||
| 	ulong buf[2]; | ||||
|  | ||||
| 	ret = OSI_Enet2GetHWAddr__( buf ); | ||||
|  | ||||
| 	((ulong*)addr)[0] = buf[0]; | ||||
| 	((ushort*)addr)[2] = (buf[1] >> 16); | ||||
| 	return ret; | ||||
| } | ||||
| static inline _osi_call2( int, OSI_Enet2IRQAck, OSI_ENET2_IRQ_ACK, int, irq_enable, int, rx_head ); | ||||
|  | ||||
| /* PROM (device-tree) */ | ||||
| static inline _osi_call2( int, OSI_PromIface, OSI_PROM_IFACE, int, what, int, ph ); | ||||
| static inline _osi_call3( int, OSI_PromIface1, OSI_PROM_IFACE, int, what, int, ph, int, p1 ); | ||||
| static inline _osi_call4( int, OSI_PromIface2, OSI_PROM_IFACE, int, what, int, ph, int, p1, int, p2 ); | ||||
| static inline _osi_call5( int, OSI_PromIface3, OSI_PROM_IFACE, int, what, int, ph, int, p1, int, p2, int, p3 ); | ||||
| static inline _osi_call2( int, OSI_PromPathIface, OSI_PROM_PATH_IFACE, int, what, const char *, p ); | ||||
|  | ||||
| /* emulation acceleration */ | ||||
| static inline _osi_call1( int, OSI_MapinMregs, OSI_MAPIN_MREGS, ulong, mphys ); | ||||
| static inline _osi_call3( int, OSI_EmuAccel, OSI_EMUACCEL, int, emuaccel_flags, int, param, int, inst_addr ); | ||||
|  | ||||
| /* timer frequency */ | ||||
| static inline _osi_call1( int, OSI_MticksToUsecs, OSI_MTICKS_TO_USECS, ulong, mticks ); | ||||
| static inline _osi_call1( int, OSI_UsecsToMticks, OSI_USECS_TO_MTICKS, ulong, usecs ); | ||||
|  | ||||
| /* fb info */ | ||||
| struct osi_fb_info; | ||||
| static inline _osi_call0_w5( int, OSI_GetFBInfo, OSI_GET_FB_INFO, struct osi_fb_info *, retinfo ); | ||||
|  | ||||
| /* SCSI */ | ||||
| static inline _osi_call0( int, OSI_SCSIAck, OSI_SCSI_ACK ); | ||||
| static inline _osi_call1( int, OSI_SCSISubmit, OSI_SCSI_SUBMIT, int, req_mphys ); | ||||
| static inline _osi_call2( int, OSI_SCSIControl, OSI_SCSI_CNTRL, int, sel, int, param ); | ||||
|  | ||||
| /* TTY */ | ||||
| static inline _osi_call0( int, OSI_TTYGetc, OSI_TTY_GETC ); | ||||
| static inline _osi_call1( int, OSI_TTYPutc, OSI_TTY_PUTC, int, ch ); | ||||
| static inline _osi_call0( int, OSI_TTYIRQAck, OSI_TTY_IRQ_ACK ); | ||||
|  | ||||
| #endif   /* _H_OSI_CALLS */ | ||||
							
								
								
									
										47
									
								
								arch/ppc/pearpc/console.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								arch/ppc/pearpc/console.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
|  | ||||
| /* | ||||
|  *      <console.c> | ||||
|  * | ||||
|  *      Simple text console | ||||
|  * | ||||
|  *   Copyright (C) 2005 Stefan Reinauer <stepan@openbios.org> | ||||
|  * | ||||
|  *   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 | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "libc/diskio.h" | ||||
| #include "ofmem.h" | ||||
| #include "pearpc/pearpc.h" | ||||
|  | ||||
|  | ||||
| typedef struct osi_fb_info { | ||||
| 	unsigned long   mphys; | ||||
| 	int             rb, w, h, depth; | ||||
| } osi_fb_info_t; | ||||
|  | ||||
|  | ||||
| int PearPC_GetFBInfo( osi_fb_info_t *fb ) | ||||
| { | ||||
|  | ||||
|         fb->w=1024; | ||||
|         fb->h=768; | ||||
|         fb->depth=15; | ||||
|         fb->rb=2048; | ||||
|         fb->mphys=0x84000000; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #define openbios_GetFBInfo(x) PearPC_GetFBInfo(x) | ||||
|  | ||||
| #include "../../../modules/video.c" | ||||
|  | ||||
| #include "../../../modules/console.c" | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										137
									
								
								arch/ppc/pearpc/init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								arch/ppc/pearpc/init.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,137 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *    | ||||
|  *	<init.c> | ||||
|  *	 | ||||
|  *	Initialization for pearpc | ||||
|  * | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  *   Copyright (C) 2005 Stefan Reinauer | ||||
|  * | ||||
|  *   based on mol/init.c: | ||||
|  *    | ||||
|  *   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Samuel & David Rydh  | ||||
|  *      (samuel@ibrium.se, dary@lindesign.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "pearpc/pearpc.h" | ||||
| #include "ofmem.h" | ||||
| #include "openbios-version.h" | ||||
|  | ||||
| extern void unexpected_excep( int vector ); | ||||
| extern void ob_ide_init( void ); | ||||
| extern void ob_pci_init( void ); | ||||
| extern void ob_adb_init( void ); | ||||
| extern void setup_timers( void ); | ||||
|  | ||||
| #if 0 | ||||
| int | ||||
| get_bool_res( const char *res ) | ||||
| { | ||||
| 	char buf[8], *p; | ||||
|  | ||||
| 	p = BootHGetStrRes( res, buf, sizeof(buf) ); | ||||
| 	if( !p ) | ||||
| 		return -1; | ||||
| 	if( !strcasecmp(p,"true") || !strcasecmp(p,"yes") || !strcasecmp(p,"1") ) | ||||
| 		return 1; | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void | ||||
| unexpected_excep( int vector ) | ||||
| { | ||||
| 	printk("openbios panic: Unexpected exception %x\n", vector ); | ||||
| 	for( ;; ) | ||||
| 		; | ||||
| } | ||||
|  | ||||
| void | ||||
| entry( void ) | ||||
| { | ||||
| 	printk("\n"); | ||||
| 	printk("=============================================================\n"); | ||||
| 	printk("OpenBIOS %s [%s]\n", OPENBIOS_RELEASE, OPENBIOS_BUILD_DATE ); | ||||
| 	 | ||||
| 	ofmem_init(); | ||||
| 	initialize_forth(); | ||||
| 	/* won't return */ | ||||
|  | ||||
| 	printk("of_startup returned!\n"); | ||||
| 	for( ;; ) | ||||
| 		; | ||||
| } | ||||
|  | ||||
| static void | ||||
| setenv( char *env, char *value ) | ||||
| { | ||||
| 	push_str( value ); | ||||
| 	push_str( env ); | ||||
| 	fword("$setenv"); | ||||
| } | ||||
|  | ||||
| void | ||||
| arch_of_init( void ) | ||||
| { | ||||
| #if USE_RTAS | ||||
| 	phandle_t ph; | ||||
| #endif | ||||
| 	int autoboot; | ||||
| 	 | ||||
| 	devtree_init(); | ||||
| 	nvram_init(); | ||||
| 	modules_init(); | ||||
| #ifdef CONFIG_DRIVER_PCI | ||||
| 	ob_pci_init(); | ||||
| #endif | ||||
| #ifdef CONFIG_DRIVER_IDE | ||||
|         setup_timers(); | ||||
|         ob_ide_init(); | ||||
| #endif | ||||
| #ifdef CONFIG_DRIVER_ADB | ||||
| 	ob_adb_init(); | ||||
| #endif | ||||
|  | ||||
| 	node_methods_init(); | ||||
| 	init_video(); | ||||
| 		 | ||||
| #if USE_RTAS | ||||
| 	if( !(ph=find_dev("/rtas")) ) | ||||
| 		printk("Warning: No /rtas node\n"); | ||||
| 	else { | ||||
| 		ulong size = 0x1000; | ||||
| 		while( size < (ulong)of_rtas_end - (ulong)of_rtas_start ) | ||||
| 			size *= 2; | ||||
| 		set_property( ph, "rtas-size", (char*)&size, sizeof(size) ); | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| 	/* tweak boot settings */ | ||||
| 	autoboot = !!get_bool_res("autoboot"); | ||||
| #endif | ||||
| 	autoboot = 0; | ||||
| 	if( !autoboot ) | ||||
| 		printk("Autobooting disabled - dropping into OpenFirmware\n"); | ||||
| 	setenv("auto-boot?", autoboot ? "true" : "false" ); | ||||
| 	setenv("boot-command", "pearpcboot"); | ||||
|  | ||||
| #if 0 | ||||
| 	if( get_bool_res("tty-interface") == 1 ) | ||||
| #endif | ||||
| 		fword("activate-tty-interface"); | ||||
|  | ||||
| 	/* hack */ | ||||
| 	device_end(); | ||||
| 	bind_func("pearpcboot", boot ); | ||||
| } | ||||
							
								
								
									
										17
									
								
								arch/ppc/pearpc/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								arch/ppc/pearpc/kernel.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:03:25 stepan> | ||||
|  *   Time-stamp: <2004/08/28 18:03:25 stepan> | ||||
|  *    | ||||
|  *	<pearpc/kernel.c> | ||||
|  *	 | ||||
|  *   Copyright (C) 2005 Stefan Reinauer | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "pearpc-dict.h" | ||||
| #include "../kernel.c" | ||||
|  | ||||
							
								
								
									
										145
									
								
								arch/ppc/pearpc/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								arch/ppc/pearpc/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,145 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *    | ||||
|  *	<main.c> | ||||
|  *	 | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  *	 | ||||
|  *   Based on MOL specific code which is    | ||||
|  *   Copyright (C) 2002, 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "openbios/elfload.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "libc/diskio.h" | ||||
| #include "libc/vsprintf.h" | ||||
| #include "pearpc/pearpc.h" | ||||
| #include "ofmem.h" | ||||
|  | ||||
| static void | ||||
| transfer_control_to_elf( ulong entry ) | ||||
| { | ||||
| 	extern void call_elf( ulong entry ); | ||||
| 	printk("Starting ELF image at 0x%08lX\n", entry); | ||||
| 	call_elf( 0x400000 ); | ||||
| 	//call_elf( entry ); | ||||
|  | ||||
| 	fatal_error("call_elf returned unexpectedly\n"); | ||||
| } | ||||
|  | ||||
| static int | ||||
| load_elf_rom( ulong *entry, int fd ) | ||||
| { | ||||
| 	int i, lszz_offs, elf_offs; | ||||
| 	char buf[128], *addr; | ||||
| 	Elf_ehdr ehdr; | ||||
| 	Elf_phdr *phdr; | ||||
| 	size_t s; | ||||
|  | ||||
| 	printk("Loading '%s'\n", get_file_path(fd)); | ||||
|  | ||||
| 	/* the ELF-image (usually) starts at offset 0x4000 */ | ||||
| 	if( (elf_offs=find_elf(fd)) < 0 ) { | ||||
| 		printk("----> %s is not an ELF image\n", buf ); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 	if( !(phdr=elf_readhdrs(fd, elf_offs, &ehdr)) ) | ||||
| 		fatal_error("elf_readhdrs failed\n"); | ||||
|  | ||||
| 	*entry = ehdr.e_entry; | ||||
|  | ||||
| 	/* load segments. Compressed ROM-image assumed to be located immediately | ||||
| 	 * after the last segment */ | ||||
| 	lszz_offs = elf_offs; | ||||
| 	for( i=0; i<ehdr.e_phnum; i++ ) { | ||||
| 		/* p_memsz, p_flags */ | ||||
| 		s = MIN( phdr[i].p_filesz, phdr[i].p_memsz ); | ||||
| 		seek_io( fd, elf_offs + phdr[i].p_offset ); | ||||
|  | ||||
| 		/* printk("filesz: %08lX memsz: %08lX p_offset: %08lX p_vaddr %08lX\n",  | ||||
| 		   phdr[i].p_filesz, phdr[i].p_memsz, phdr[i].p_offset, | ||||
| 		   phdr[i].p_vaddr ); */ | ||||
|  | ||||
| 		if( phdr[i].p_vaddr != phdr[i].p_paddr ) | ||||
| 			printk("WARNING: ELF segment virtual addr != physical addr\n"); | ||||
| 		lszz_offs = MAX( lszz_offs, elf_offs + phdr[i].p_offset + phdr[i].p_filesz ); | ||||
| 		if( !s ) | ||||
| 			continue; | ||||
| 		if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) | ||||
| 			fatal_error("Claim failed!\n"); | ||||
|  | ||||
| 		addr = (char*)phdr[i].p_vaddr; | ||||
| 		if( read_io(fd, addr, s) != s ) | ||||
| 			fatal_error("read failed\n"); | ||||
|  | ||||
| #if 0 | ||||
| 		/* patch CODE segment */ | ||||
| 		if( *entry >= phdr[i].p_vaddr && *entry < phdr[i].p_vaddr + s ) { | ||||
| 			patch_newworld_rom( (char*)phdr[i].p_vaddr, s ); | ||||
| 			newworld_timer_hack( (char*)phdr[i].p_vaddr, s ); | ||||
| 		} | ||||
| #endif | ||||
| 		flush_icache_range( addr, addr+s ); | ||||
|  | ||||
| 		/*printk("ELF ROM-section loaded at %08lX (size %08lX)\n",  | ||||
| 		   (ulong)phdr[i].p_vaddr, (ulong)phdr[i].p_memsz );*/ | ||||
| 	} | ||||
| 	free( phdr ); | ||||
| 	return lszz_offs; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| encode_bootpath( const char *spec, const char *args ) | ||||
| { | ||||
| 	phandle_t chosen_ph = find_dev("/chosen"); | ||||
| 	set_property( chosen_ph, "bootpath", spec, strlen(spec)+1 );	 | ||||
| 	set_property( chosen_ph, "bootargs", args, strlen(args)+1 );	 | ||||
| } | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	pearpc booting							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static void | ||||
| pearpc_startup( void ) | ||||
| { | ||||
| 	const char *paths[] = { "hd:0,\\zImage.chrp", NULL }; | ||||
| 	const char *args[] = { "root=/dev/hda2 console=ttyS0,115200", NULL }; | ||||
| 	ulong entry; | ||||
| 	int i, fd; | ||||
|  | ||||
| 	for( i=0; paths[i]; i++ ) { | ||||
| 		if( (fd=open_io(paths[i])) == -1 ) | ||||
| 			continue; | ||||
| 		(void) load_elf_rom( &entry, fd ); | ||||
| 		close_io( fd ); | ||||
| 		encode_bootpath( paths[i], args[i] ); | ||||
|  | ||||
| 		update_nvram(); | ||||
| 		transfer_control_to_elf( entry ); | ||||
| 		/* won't come here */ | ||||
| 	} | ||||
| 	printk("*** Boot failure! No secondary bootloader specified ***\n"); | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	entry								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| void | ||||
| boot( void ) | ||||
| { | ||||
| 	fword("update-chosen"); | ||||
| 	pearpc_startup(); | ||||
| } | ||||
							
								
								
									
										335
									
								
								arch/ppc/pearpc/methods.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								arch/ppc/pearpc/methods.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,335 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *    | ||||
|  *	<methods.c> | ||||
|  *	 | ||||
|  *	Misc device node methods | ||||
|  * | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  *    | ||||
|  *   Based on MOL specific code which is | ||||
|  *    | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "libc/string.h" | ||||
| #include "pearpc/pearpc.h" | ||||
| #include "ofmem.h" | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	RTAS (run-time abstraction services)				*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #ifdef USE_RTAS | ||||
| DECLARE_NODE( rtas, INSTALL_OPEN, 0, "+/rtas" ); | ||||
|  | ||||
| /* ( physbase -- rtas_callback ) */ | ||||
| static void | ||||
| rtas_instantiate( void ) | ||||
| { | ||||
| 	int physbase = POP(); | ||||
| 	int s=0x1000, size = (int)of_rtas_end - (int)of_rtas_start; | ||||
| 	ulong virt; | ||||
| 	 | ||||
| 	while( s < size ) | ||||
| 		s += 0x1000; | ||||
| 	virt = ofmem_claim_virt( 0, s, 0x1000 ); | ||||
| 	ofmem_map( physbase, virt, s, -1 ); | ||||
| 	memcpy( (char*)virt, of_rtas_start, size ); | ||||
|  | ||||
| 	printk("RTAS instantiated at %08x\n", physbase ); | ||||
| 	flush_icache_range( (char*)virt, (char*)virt + size ); | ||||
|  | ||||
| 	PUSH( physbase ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( rtas ) = { | ||||
| 	{ "instantiate",	rtas_instantiate }, | ||||
| 	{ "instantiate-rtas",	rtas_instantiate }, | ||||
| }; | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	stdout								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( video_stdout, INSTALL_OPEN, 0, "Tdisplay" ); | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| stdout_write( void ) | ||||
| { | ||||
| 	int len = POP(); | ||||
| 	char *addr = (char*)POP(); | ||||
| 	char *s = malloc( len + 1 ); | ||||
|  | ||||
| 	strncpy_nopad( s, addr, len ); | ||||
| 	s[len]=0; | ||||
| 	 | ||||
| 	printk( "%s", s ); | ||||
| 	//vfd_draw_str( s ); | ||||
| 	console_draw_str( s ); | ||||
| 		 | ||||
| 	free( s ); | ||||
|  | ||||
| 	PUSH( len ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( video_stdout ) = { | ||||
| 	{ "write",	stdout_write	}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	tty								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( tty, INSTALL_OPEN, 0, "/packages/terminal-emulator" ); | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| tty_read( void ) | ||||
| { | ||||
| 	int ch, len = POP(); | ||||
| 	char *p = (char*)POP(); | ||||
| 	int ret=0; | ||||
|  | ||||
| 	if( len > 0 ) { | ||||
| 		ret = 1; | ||||
| 		ch = getchar(); | ||||
| 		if( ch >= 0 ) { | ||||
| 			*p = ch; | ||||
| 		} else { | ||||
| 			ret = 0; | ||||
| 		} | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( addr len -- actual ) */ | ||||
| static void | ||||
| tty_write( void ) | ||||
| { | ||||
| 	int i, len = POP(); | ||||
| 	char *p = (char*)POP(); | ||||
| 	for( i=0; i<len; i++ ) | ||||
| 		putchar( *p++ ); | ||||
| 	RET( len ); | ||||
| } | ||||
|  | ||||
| NODE_METHODS( tty ) = { | ||||
| 	{ "read",	tty_read	}, | ||||
| 	{ "write",	tty_write	}, | ||||
| }; | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	client interface 'quiesce'					*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( ciface, 0, 0, "/packages/client-iface" ); | ||||
|  | ||||
| /* ( -- ) */ | ||||
| static void | ||||
| ciface_quiesce( ulong args[], ulong ret[] )  | ||||
| { | ||||
| #if 0 | ||||
| 	ulong msr; | ||||
| 	/* This seems to be the correct thing to do - but I'm not sure */ | ||||
| 	asm volatile("mfmsr %0" : "=r" (msr) : ); | ||||
| 	msr &= ~(MSR_IR | MSR_DR); | ||||
| 	asm volatile("mtmsr %0" :: "r" (msr) ); | ||||
| #endif | ||||
| 	printk("=============================================================\n\n"); | ||||
| } | ||||
|  | ||||
| /* ( -- ms ) */ | ||||
| static void | ||||
| ciface_milliseconds( ulong args[], ulong ret[] )  | ||||
| { | ||||
| 	extern unsigned long get_timer_freq(); | ||||
| 	static ulong mticks=0, usecs=0; | ||||
| 	ulong t; | ||||
|          | ||||
| 	asm volatile("mftb %0" : "=r" (t) : ); | ||||
| 	if( mticks ) | ||||
| 		usecs += get_timer_freq() / 1000000 * ( t-mticks ); | ||||
| 	mticks = t; | ||||
|  | ||||
| 	PUSH( usecs/1000 ); | ||||
| } | ||||
|  | ||||
|  | ||||
| NODE_METHODS( ciface ) = { | ||||
| 	{ "quiesce",		ciface_quiesce		}, | ||||
| 	{ "milliseconds",	ciface_milliseconds	}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	MMU/memory methods						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| DECLARE_NODE( memory, INSTALL_OPEN, 0, "/memory" ); | ||||
| DECLARE_NODE( mmu, INSTALL_OPEN, 0, "/cpu@0" ); | ||||
| DECLARE_NODE( mmu_ciface, 0, 0, "/packages/client-iface" ); | ||||
|  | ||||
|  | ||||
| /* ( phys size align --- base ) */ | ||||
| static void | ||||
| mem_claim( void ) | ||||
| { | ||||
| 	int align = POP(); | ||||
| 	int size = POP(); | ||||
| 	int phys = POP(); | ||||
| 	int ret = ofmem_claim_phys( phys, size, align ); | ||||
| 	 | ||||
| 	if( ret == -1 ) { | ||||
| 		printk("MEM: claim failure\n"); | ||||
| 		throw( -13 ); | ||||
| 		return; | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( phys size --- ) */ | ||||
| static void | ||||
| mem_release( void ) | ||||
| { | ||||
| 	POP(); POP(); | ||||
| } | ||||
|  | ||||
| /* ( phys size align --- base ) */ | ||||
| static void | ||||
| mmu_claim( void ) | ||||
| { | ||||
| 	int align = POP(); | ||||
| 	int size = POP(); | ||||
| 	int phys = POP(); | ||||
| 	int ret = ofmem_claim_virt( phys, size, align ); | ||||
|  | ||||
| 	if( ret == -1 ) { | ||||
| 		printk("MMU: CLAIM failure\n"); | ||||
| 		throw( -13 ); | ||||
| 		return; | ||||
| 	} | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( phys size --- ) */ | ||||
| static void | ||||
| mmu_release( void ) | ||||
| { | ||||
| 	POP(); POP(); | ||||
| } | ||||
|  | ||||
| /* ( phys virt size mode -- [ret???] ) */ | ||||
| static void  | ||||
| mmu_map( void ) | ||||
| { | ||||
| 	int mode = POP(); | ||||
| 	int size = POP(); | ||||
| 	int virt = POP(); | ||||
| 	int phys = POP(); | ||||
| 	int ret; | ||||
| 	 | ||||
| 	/* printk("mmu_map: %x %x %x %x\n", phys, virt, size, mode ); */ | ||||
| 	ret = ofmem_map( phys, virt, size, mode ); | ||||
|  | ||||
| 	if( ret ) { | ||||
| 		printk("MMU: map failure\n"); | ||||
| 		throw( -13 ); | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* ( virt size -- ) */ | ||||
| static void | ||||
| mmu_unmap( void ) | ||||
| { | ||||
| 	POP(); POP(); | ||||
| } | ||||
|  | ||||
| /* ( virt -- false | phys mode true ) */ | ||||
| static void | ||||
| mmu_translate( void ) | ||||
| { | ||||
| 	ulong mode; | ||||
| 	int virt = POP(); | ||||
| 	int phys = ofmem_translate( virt, &mode ); | ||||
|  | ||||
| 	if( phys == -1 ) { | ||||
| 		PUSH( 0 ); | ||||
| 	} else { | ||||
| 		PUSH( phys ); | ||||
| 		PUSH( (int)mode ); | ||||
| 		PUSH( -1 ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* ( virt size align -- baseaddr|-1 ) */ | ||||
| static void | ||||
| ciface_claim( void ) | ||||
| { | ||||
| 	int align = POP(); | ||||
| 	int size = POP(); | ||||
| 	int virt = POP(); | ||||
| 	int ret = ofmem_claim( virt, size, align ); | ||||
|  | ||||
| 	/* printk("ciface_claim: %08x %08x %x\n", virt, size, align ); */ | ||||
| 	PUSH( ret ); | ||||
| } | ||||
|  | ||||
| /* ( virt size -- ) */ | ||||
| static void | ||||
| ciface_release( void ) | ||||
| { | ||||
| 	POP(); | ||||
| 	POP(); | ||||
| } | ||||
|  | ||||
|  | ||||
| NODE_METHODS( memory ) = { | ||||
| 	{ "claim",		mem_claim		}, | ||||
| 	{ "release",		mem_release		}, | ||||
| }; | ||||
|  | ||||
| NODE_METHODS( mmu ) = { | ||||
| 	{ "claim",		mmu_claim		}, | ||||
| 	{ "release",		mmu_release		}, | ||||
| 	{ "map",		mmu_map			}, | ||||
| 	{ "unmap",		mmu_unmap		}, | ||||
| 	{ "translate",		mmu_translate		}, | ||||
| }; | ||||
|  | ||||
| NODE_METHODS( mmu_ciface ) = { | ||||
| 	{ "claim",		ciface_claim		}, | ||||
| 	{ "release",		ciface_release		}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	init								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| void | ||||
| node_methods_init( void ) | ||||
| { | ||||
| #ifdef USE_RTAS | ||||
| 	REGISTER_NODE( rtas ); | ||||
| #endif | ||||
| 	REGISTER_NODE( video_stdout ); | ||||
| 	REGISTER_NODE( ciface ); | ||||
| 	REGISTER_NODE( memory ); | ||||
| 	REGISTER_NODE( mmu ); | ||||
| 	REGISTER_NODE( mmu_ciface ); | ||||
| 	REGISTER_NODE( tty ); | ||||
| } | ||||
							
								
								
									
										206
									
								
								arch/ppc/pearpc/pearpc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								arch/ppc/pearpc/pearpc.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,206 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *    | ||||
|  *	<pearpc.c> | ||||
|  *    | ||||
|  *   Copyright (C) 2004, Greg Watson | ||||
|  *    | ||||
|  *   derived from mol.c | ||||
|  * | ||||
|  *   Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/kernel.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "libc/vsprintf.h" | ||||
| #include "libc/string.h" | ||||
| #include "pearpc/pearpc.h" | ||||
| #include <stdarg.h> | ||||
|  | ||||
| #define UART_BASE 0x3f8 | ||||
|  | ||||
| // FIXME | ||||
| unsigned long virt_offset = 0; | ||||
|  | ||||
|  | ||||
| void | ||||
| exit( int status ) | ||||
| { | ||||
| 	for (;;); | ||||
| } | ||||
|  | ||||
| void | ||||
| fatal_error( const char *err ) | ||||
| { | ||||
| 	printk("Fatal error: %s\n", err ); | ||||
| 	exit(0); | ||||
| } | ||||
|  | ||||
| void | ||||
| panic( const char *err ) | ||||
| { | ||||
| 	printk("Panic: %s\n", err ); | ||||
| 	exit(0); | ||||
|  | ||||
| 	/* won't come here... this keeps the gcc happy */ | ||||
| 	for( ;; ) | ||||
| 		; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	print using OSI interface					*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static int do_indent; | ||||
|  | ||||
| int | ||||
| printk( const char *fmt, ... ) | ||||
| { | ||||
| 	char *p, buf[1024];	/* XXX: no buffer overflow protection... */ | ||||
| 	va_list args; | ||||
| 	int i; | ||||
|  | ||||
| 	va_start(args, fmt); | ||||
| 	i=vsprintf(buf,fmt,args); | ||||
| 	va_end(args); | ||||
|  | ||||
| 	for( p=buf; *p; p++ ) { | ||||
| 		if( *p == '\n' ) | ||||
| 			do_indent = 0; | ||||
| 		if( do_indent++ == 1 ) { | ||||
| 			putchar( '>' ); | ||||
| 			putchar( '>' ); | ||||
| 			putchar( ' ' ); | ||||
| 		} | ||||
| 		putchar( *p ); | ||||
| 	} | ||||
| 	return i; | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	TTY iface							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| static int ttychar = -1; | ||||
|  | ||||
| static int | ||||
| tty_avail( void ) | ||||
| { | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int | ||||
| tty_putchar( int c ) | ||||
| { | ||||
| 	if( tty_avail() ) { | ||||
| 		while (!(inb(UART_BASE + 0x05) & 0x20)) | ||||
| 			; | ||||
| 		outb(c, UART_BASE); | ||||
| 		while (!(inb(UART_BASE + 0x05) & 0x40)) | ||||
| 			; | ||||
| 	} | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| int | ||||
| availchar( void ) | ||||
| { | ||||
| 	if( !tty_avail() ) | ||||
| 		return 0; | ||||
| 	 | ||||
| 	if( ttychar < 0 ) | ||||
| 		ttychar = inb(UART_BASE); | ||||
| 	return (ttychar >= 0); | ||||
| } | ||||
|  | ||||
| int | ||||
| getchar( void ) | ||||
| { | ||||
| 	int ch; | ||||
|  | ||||
| 	if( !tty_avail() ) | ||||
| 		return 0; | ||||
|  | ||||
| 	if( ttychar < 0 ) | ||||
| 		return inb(UART_BASE); | ||||
| 	ch = ttychar; | ||||
| 	ttychar = -1; | ||||
| 	return ch; | ||||
| } | ||||
|  | ||||
| int | ||||
| putchar( int c ) | ||||
| { | ||||
| 	if (c == '\n') | ||||
| 		tty_putchar('\r'); | ||||
| 	return tty_putchar(c); | ||||
| } | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	briQ specific stuff						*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #define IO_NVRAM_PA_START 0x80860000 | ||||
| #define IO_NVRAM_PA_END 0x80880000 | ||||
|  | ||||
| static char *nvram=(char *)IO_NVRAM_PA_START; | ||||
|  | ||||
| void | ||||
| dump_nvram(void) | ||||
| { | ||||
|   static char hexdigit[] = "0123456789abcdef"; | ||||
|   int i; | ||||
|   for (i = 0; i < 16*4; i++) | ||||
|     { | ||||
|       printk ("%c", hexdigit[nvram[i<<4] >> 4]); | ||||
|       printk ("%c", hexdigit[nvram[i<<4] % 16]); | ||||
|       if (!((i + 1) % 16)) | ||||
|         { | ||||
|           printk ("\n"); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           printk (" "); | ||||
|         } | ||||
|     }	 | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| arch_nvram_size( void ) | ||||
| { | ||||
| 	return (IO_NVRAM_PA_END-IO_NVRAM_PA_START)>>4; | ||||
| } | ||||
|  | ||||
| void | ||||
| arch_nvram_put( char *buf ) | ||||
| { | ||||
| 	int i; | ||||
| 	for (i=0; i<(IO_NVRAM_PA_END-IO_NVRAM_PA_START)>>4; i++) | ||||
| 		nvram[i<<4]=buf[i]; | ||||
| 	// memcpy(nvram, buf, IO_NVRAM_PA_END-IO_NVRAM_PA_START); | ||||
| 	printk("new nvram:\n"); | ||||
| 	dump_nvram(); | ||||
| } | ||||
|  | ||||
| void | ||||
| arch_nvram_get( char *buf ) | ||||
| { | ||||
| 	int i; | ||||
| 	for (i=0; i<(IO_NVRAM_PA_END-IO_NVRAM_PA_START)>>4; i++) | ||||
| 		buf[i]=nvram[i<<4]; | ||||
|  | ||||
| 	//memcpy(buf, nvram, IO_NVRAM_PA_END-IO_NVRAM_PA_START); | ||||
| 	printk("current nvram:\n"); | ||||
| 	dump_nvram(); | ||||
| } | ||||
							
								
								
									
										116
									
								
								arch/ppc/pearpc/pearpc.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								arch/ppc/pearpc/pearpc.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| \   pearpc specific initialization code | ||||
| \  | ||||
| \   Copyright (C) 2005 Stefan Reinauer | ||||
| \  | ||||
| \   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 | ||||
| \  | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------------------- | ||||
| \ initialization | ||||
| \ ------------------------------------------------------------------------- | ||||
|  | ||||
| : make-openable ( path ) | ||||
|   find-dev if | ||||
|     begin ?dup while | ||||
|       \ install trivial open and close methods | ||||
|       dup active-package! is-open | ||||
|       parent | ||||
|     repeat | ||||
|   then | ||||
| ; | ||||
|  | ||||
| : preopen ( chosen-str node-path ) | ||||
|   2dup make-openable | ||||
|    | ||||
|   " /chosen" find-device | ||||
|   open-dev ?dup if | ||||
|     encode-int 2swap property | ||||
|   else | ||||
|     2drop | ||||
|   then | ||||
| ; | ||||
|  | ||||
| \ preopen device nodes (and store the ihandles under /chosen) | ||||
| :noname | ||||
|   " rtc" " /pci/isa/rtc" preopen | ||||
|   " memory" " /memory" preopen | ||||
|   " mmu" " /cpu@0" preopen | ||||
|   \ " stdout" " /packages/terminal-emulator" preopen | ||||
|   " stdout" " /pci/pci6666,6666" preopen | ||||
|   " stdin" " /pci/via-cuda/adb" preopen | ||||
|  | ||||
| ; SYSTEM-initializer | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------------------- | ||||
| \ device tree fixing | ||||
| \ ------------------------------------------------------------------------- | ||||
|  | ||||
| \ add decode-address methods | ||||
| : (make-decodable) ( phandle -- ) | ||||
|  | ||||
|     dup " #address-cells" rot get-package-property 0= if | ||||
|       decode-int nip nip | ||||
|       over " decode-unit" rot find-method if 2drop else | ||||
|         ( save phandle ncells ) | ||||
|        | ||||
|         over active-package! | ||||
|         case | ||||
|           1 of ['] parse-hex " decode-unit" is-xt-func endof | ||||
|           3 of | ||||
|             " bus-range" active-package get-package-property 0= if | ||||
|               decode-int nip nip | ||||
|               ['] encode-unit-pci " encode-unit" is-xt-func | ||||
|               " decode-unit" is-func-begin | ||||
|                 ['] (lit) , , | ||||
|                 ['] decode-unit-pci-bus , | ||||
|               is-func-end | ||||
|             then | ||||
|           endof | ||||
|         endcase | ||||
|       then | ||||
|     then | ||||
|     drop | ||||
| ; | ||||
|      | ||||
| : init-pearpc-tree ( -- ) | ||||
|   active-package | ||||
|    | ||||
|   iterate-tree-begin | ||||
|   begin ?dup while | ||||
|  | ||||
|     dup (make-decodable) | ||||
|      | ||||
|     iterate-tree | ||||
|   repeat | ||||
|  | ||||
|   active-package! | ||||
| ; | ||||
|  | ||||
| \ use the tty interface if available | ||||
| : activate-tty-interface | ||||
|   " /packages/terminal-emulator" find-dev if drop | ||||
|     " /pci/via-cuda/adb" " input-device" $setenv | ||||
|     " /pci/pci6666,6666" " output-device" $setenv | ||||
|   then | ||||
| ; | ||||
|  | ||||
| :noname | ||||
|   " keyboard" input | ||||
| ; CONSOLE-IN-initializer | ||||
|  | ||||
|  | ||||
| \ ------------------------------------------------------------------------- | ||||
| \ pre-booting | ||||
| \ ------------------------------------------------------------------------- | ||||
|  | ||||
| : update-chosen | ||||
|   " /chosen" find-device | ||||
|   stdin @ encode-int " stdin" property | ||||
|   stdout @ encode-int " stdout" property | ||||
|   " /pci/isa/interrupt-controller" find-dev if encode-int " interrupt-controller" property then | ||||
|   device-end | ||||
| ; | ||||
							
								
								
									
										26
									
								
								arch/ppc/pearpc/pearpc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								arch/ppc/pearpc/pearpc.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 17:50:12 stepan> | ||||
|  *   Time-stamp: <2004/08/28 17:50:12 stepan> | ||||
|  *    | ||||
|  *	<pearpc.h> | ||||
|  *    | ||||
|  *   Copyright (C) 2005 Stefan Reinauer | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #ifndef _H_PEARPC | ||||
| #define _H_PEARPC | ||||
|  | ||||
| /* vfd.c */ | ||||
| extern int		vfd_draw_str( const char *str ); | ||||
| extern void		vfd_close( void ); | ||||
|  | ||||
| extern int                console_draw_str( const char *str ); | ||||
|  | ||||
| #include "kernel.h" | ||||
|  | ||||
| #endif   /* _H_PEARPC */ | ||||
							
								
								
									
										23
									
								
								arch/ppc/pearpc/tree.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								arch/ppc/pearpc/tree.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 18:38:22 greg> | ||||
|  *   Time-stamp: <2004/08/28 18:38:22 greg> | ||||
|  *  | ||||
|  *	<tree.c> | ||||
|  *	 | ||||
|  *	device tree setup | ||||
|  *    | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
|  | ||||
| void devtree_init( void ) | ||||
| { | ||||
| 	fword("init-pearpc-tree"); | ||||
| } | ||||
							
								
								
									
										247
									
								
								arch/ppc/pearpc/tree.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								arch/ppc/pearpc/tree.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,247 @@ | ||||
| \   PearPC specific initialization code | ||||
| \  | ||||
| \   Copyright (C) 2005 Stefan Reinauer | ||||
| \  | ||||
| \   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 | ||||
| \  | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ device-tree | ||||
| \ ------------------------------------------------------------- | ||||
|  | ||||
| " /" find-device | ||||
|  | ||||
| " chrp" device-type | ||||
| " OpenSource,PEARPC" model | ||||
| h# 80000000 encode-int " isa-io-base" property | ||||
| 1 encode-int " #interrupt-cells" property | ||||
| 1 encode-int " #size-cells" property | ||||
|  | ||||
| new-device | ||||
| 	" memory" device-name | ||||
| 	" memory" device-type | ||||
| 	0 encode-int h# 1E00000 encode-int encode+ | ||||
| 	h# 2000000 encode-int encode+ h# 40000000 encode-int encode+  | ||||
| 	  " available" property | ||||
| 	0 h# 40000000 reg | ||||
| 	external | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
| 	" cpu" device-name | ||||
| 	" cpu" device-type | ||||
| 	" " encode-string " translations" property | ||||
| 	0 encode-phys h# 8000000 encode-int encode+ " available" property | ||||
| 	d# 32 encode-int " d-cache-block-size" property | ||||
| 	8 encode-int " d-cache-sets" property | ||||
| 	d# 32768 encode-int " d-cache-size" property | ||||
| 	d# 32 encode-int " i-cache-block-size" property | ||||
| 	8 encode-int " i-cache-sets" property | ||||
| 	d# 32768 encode-int " i-cache-size" property | ||||
| 	" " encode-string " cache-unified" property | ||||
| 	2 encode-int " i-tlb-sets" property | ||||
| 	d# 128 encode-int " i-tlb-size" property | ||||
| 	2 encode-int " d-tlb-sets" property | ||||
| 	d# 128 encode-int " d-tlb-size" property | ||||
| 	" " encode-string " tlb-split" property | ||||
| 	2 encode-int " tlb-sets" property | ||||
| 	d# 256 encode-int " tlb-size" property | ||||
| 	" " encode-string " performance-monitor" property | ||||
| 	" " encode-string " graphics" property | ||||
| 	4 encode-int " reservation-granule-size" property | ||||
|         d# 25000000 encode-int " timebase-frequency" property | ||||
|         d# 300000000 encode-int " clock-frequency" property | ||||
|         d# 66000000 encode-int " bus-frequency" property | ||||
|         h# 88201 encode-int " cpu-version" property | ||||
| 	0 encode-int " reg" property | ||||
| finish-device | ||||
|  | ||||
| " /pci" find-device | ||||
| 	h# 01000000 encode-int 0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 80000000 encode-int encode+ 0 encode-int encode+  | ||||
| 	  h# 01000000 encode-int encode+  | ||||
| 	h# 02000000 encode-int encode+ 0 encode-int encode+ 0 encode-int encode+  | ||||
| 	  h# C0000000 encode-int encode+ 0 encode-int encode+  | ||||
| 	  h# 08000000 encode-int encode+  | ||||
| 	" ranges" property | ||||
| 	" IBM,CPC710" model | ||||
| 	h# FF5F7700 encode-int " 8259-interrupt-acknowledge" property | ||||
| 	h# 0000F800 encode-int 0 encode-int encode+ 0 encode-int encode+  | ||||
| 	  7 encode-int encode+ | ||||
| 	  " interrupt-map-mask" property | ||||
| 	1 encode-int " #interrupt-cells" property | ||||
| 	h# 80000000 encode-int " system-dma-base" property | ||||
| 	d# 33333333 encode-int " clock-frequency" property | ||||
| 	" " encode-string " primary-bridge" property | ||||
| 	0 encode-int " pci-bridge-number" property | ||||
| 	h# FEC00000 encode-int h# 100000 encode-int encode+ " reg" property | ||||
| 	0 encode-int 0 encode-int encode+ " bus-range" property | ||||
|  | ||||
| new-device | ||||
| 	" ide" device-name | ||||
| 	" ide" device-type | ||||
| 	" WINBOND,82C553" model | ||||
| 	h# 28 encode-int " max-latency" property | ||||
| 	h# 2 encode-int " min-grant" property | ||||
| 	h# 1 encode-int " devsel-speed" property | ||||
| 	h# 0 encode-int " subsystem-vendor-id" property | ||||
| 	h# 0 encode-int " subsystem-id" property | ||||
| 	h# 1018A encode-int " class-code" property | ||||
| 	h# 5 encode-int " revision-id" property | ||||
| 	h# 105 encode-int " device-id" property | ||||
| 	h# 10AD encode-int " vendor-id" property | ||||
| 	h# 1003110 encode-int 0 encode-int encode+ h# 10020 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003114 encode-int 0 encode-int encode+ h# 10030 encode-int encode+ | ||||
| 	  h# 4 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003118 encode-int 0 encode-int encode+ h# 10040 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 100311C encode-int 0 encode-int encode+ h# 10034 encode-int encode+ | ||||
| 	  h# 4 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003120 encode-int 0 encode-int encode+ h# 10050 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003124 encode-int 0 encode-int encode+ h# 10060 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  " assigned-addresses" property | ||||
| 	h# 3100 encode-int 0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003110 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003114 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 4 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003118 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 100311C encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 4 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003120 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  h# 1003124 encode-int 0 encode-int encode+ h# 0 encode-int encode+ | ||||
| 	  h# 10 encode-int encode+ 0 encode-int encode+ | ||||
| 	  " reg" property | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
| 	" ethernet" device-name | ||||
| 	" network" device-type | ||||
| 	" AMD,79C973" model | ||||
| 	h# 3800 encode-int 0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  " reg" property | ||||
| finish-device | ||||
|  | ||||
| " /pci/isa" find-device | ||||
| 	0 0 " assigned-addresses" property | ||||
| 	0 0 " ranges" property | ||||
| 	0 encode-int " slot-names" property | ||||
| 	d# 8333333 encode-int " clock-frequency" property | ||||
| 	0 encode-int " eisa-slots" property | ||||
| 	2 encode-int " #interrupt-cells" property | ||||
| 	" W83C553F" encode-string " compatible" property | ||||
| 	" WINBOND,82C553" model | ||||
| 	0 encode-int " max-latency" property | ||||
| 	0 encode-int " min-grant" property | ||||
| 	1 encode-int " devsel-speed" property | ||||
| 	0 encode-int " subsystem-vendor-id" property | ||||
| 	0 encode-int " subsystem-id" property | ||||
| 	h# 60100 encode-int " class-code" property | ||||
| 	h# 10 encode-int " revision-id" property | ||||
| 	h# 565 encode-int " device-id" property | ||||
| 	h# 10AD encode-int " vendor-id" property | ||||
| 	h# 3000 encode-int 0 encode-int encode+ 0 encode-int encode+ | ||||
| 	  0 encode-int encode+ 0 encode-int encode+ " reg" property | ||||
|  | ||||
| new-device | ||||
| 	" rtc" device-name | ||||
| 	" rtc" device-type | ||||
| 	" DS17285S" model | ||||
| 	" MC146818" encode-string | ||||
| 	" DS17285S" encode-string encode+ | ||||
| 	" pnpPNP,b00" encode-string encode+ " compatible" property | ||||
| 	8 encode-int 0 encode-int encode+ " interrupts" property | ||||
| 	h# 70 encode-int 1 encode-int encode+ | ||||
| 	  2 encode-int encode+ " reg" property | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
| 	" interrupt-controller" device-name | ||||
| 	" interrupt-controller" device-type | ||||
| 	" 8259" model | ||||
| 	" " encode-string " interrupt-controller" property | ||||
| 	2 encode-int " #interrupt-cells" property | ||||
| 	1 encode-int  | ||||
| 	2 encode-int encode+ | ||||
| 	3 encode-int encode+ | ||||
| 	6 encode-int encode+ | ||||
| 	  " reserved-interrupts" property | ||||
| 	" 8259" encode-string | ||||
| 	  " chrp,iic" encode-string encode+  | ||||
| 	  " compatible" property | ||||
| 	h# 20 encode-int 1 encode-int encode+ | ||||
| 	  2 encode-int encode+ " reg" property | ||||
| finish-device | ||||
|  | ||||
| new-device | ||||
| 	" serial" device-name | ||||
| 	" serial" device-type | ||||
| 	" no" encode-string " ctsrts" property | ||||
| 	" no" encode-string " xon" property | ||||
| 	" no" encode-string " parity" property | ||||
| 	d# 115200 encode-int " bps" property | ||||
| 	1 encode-int " stop-bits" property | ||||
| 	8 encode-int " data-bits" property | ||||
| 	h# 70800 encode-int " divisor" property | ||||
| 	h# 708000 encode-int " clock-frequency" property | ||||
| 	4 encode-int 0 encode-int encode+ " interrupts" property | ||||
| 	h# 3F8 encode-int 1 encode-int encode+ | ||||
| 	  8 encode-int encode+ " reg" property | ||||
| finish-device | ||||
|  | ||||
| " /pci" find-device | ||||
| 	" /pci/isa/interrupt-controller" find-dev if  | ||||
| 		encode-int " interrupt-parent" property  | ||||
| 	then | ||||
| 	h# 3800 encode-int 0 encode-int encode+  | ||||
| 	  0 encode-int encode+ 1 encode-int encode+ | ||||
| 	  " /pci/isa/interrupt-controller" find-dev if  | ||||
| 		encode-int encode+ | ||||
| 	  then | ||||
| 	  h# 0C encode-int encode+ 1 encode-int encode+ | ||||
| 	  " interrupt-map" property | ||||
|  | ||||
| " /pci/isa" find-device | ||||
| 	" /pci/isa/interrupt-controller" find-dev if  | ||||
| 		encode-int " interrupt-parent" property  | ||||
| 	then | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ /packages | ||||
| \ ------------------------------------------------------------- | ||||
|  | ||||
| " /packages" find-device | ||||
|  | ||||
| 	" packages" device-name | ||||
| 	external | ||||
| 	\ allow packages to be opened with open-dev | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
|  | ||||
| \ /packages/terminal-emulator | ||||
| new-device | ||||
| 	" terminal-emulator" device-name | ||||
| 	external | ||||
| 	: open true ; | ||||
| 	: close ; | ||||
| 	\ : write ( addr len -- actual ) | ||||
| 	\	dup -rot type | ||||
| 	\ ; | ||||
| finish-device | ||||
|  | ||||
| \ ------------------------------------------------------------- | ||||
| \ The END | ||||
| \ ------------------------------------------------------------- | ||||
| device-end | ||||
|  | ||||
							
								
								
									
										42
									
								
								arch/ppc/pearpc/vfd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								arch/ppc/pearpc/vfd.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2004/08/28 17:29:43 greg> | ||||
|  *   Time-stamp: <2004/08/28 17:29:43 greg> | ||||
|  *    | ||||
|  *	<vfd.c> | ||||
|  *	 | ||||
|  *	Simple text console | ||||
|  *    | ||||
|  *   Copyright (C) 2004 Greg Watson | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "pearpc/pearpc.h" | ||||
|  | ||||
| static int vfd_is_open; | ||||
|  | ||||
| static int | ||||
| vfd_init( void )  | ||||
| { | ||||
| 	vfd_is_open = 1; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void | ||||
| vfd_close( void )  | ||||
| { | ||||
| } | ||||
|  | ||||
| int | ||||
| vfd_draw_str( const char *str ) | ||||
| { | ||||
| 	if (!vfd_is_open) | ||||
| 		vfd_init(); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										47
									
								
								arch/ppc/ppc.fs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								arch/ppc/ppc.fs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | ||||
|  | ||||
| 0 value %cr | ||||
| 0 value %ctr | ||||
| 0 value %lr | ||||
| 0 value %msr | ||||
| 0 value %srr0 | ||||
| 0 value %srr1 | ||||
| 0 value %pc							\ should be an alias for %srr0 | ||||
|  | ||||
| 0 value %r0 | ||||
| 0 value %r1 | ||||
| 0 value %r2 | ||||
| 0 value %r3 | ||||
| 0 value %r4 | ||||
| 0 value %r5 | ||||
| 0 value %r6 | ||||
| 0 value %r7 | ||||
| 0 value %r8 | ||||
| 0 value %r9 | ||||
| 0 value %r10 | ||||
| 0 value %r11 | ||||
| 0 value %r12 | ||||
| 0 value %r13 | ||||
| 0 value %r14 | ||||
| 0 value %r15 | ||||
| 0 value %r16 | ||||
| 0 value %r17 | ||||
| 0 value %r18 | ||||
| 0 value %r19 | ||||
| 0 value %r20 | ||||
| 0 value %r21 | ||||
| 0 value %r22 | ||||
| 0 value %r23 | ||||
| 0 value %r24 | ||||
| 0 value %r25 | ||||
| 0 value %r26 | ||||
| 0 value %r27 | ||||
| 0 value %r28 | ||||
| 0 value %r29 | ||||
| 0 value %r30 | ||||
| 0 value %r31 | ||||
|  | ||||
| 0 value %xer | ||||
| 0 value %sprg0 | ||||
| 0 value %sprg1 | ||||
| 0 value %sprg2 | ||||
| 0 value %sprg3 | ||||
							
								
								
									
										324
									
								
								arch/ppc/start.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								arch/ppc/start.S
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,324 @@ | ||||
| /*  | ||||
|  *   Creation Date: <2001/06/16 21:30:18 samuel> | ||||
|  *   Time-stamp: <2003/04/04 16:32:06 samuel> | ||||
|  *    | ||||
|  *	<init.S> | ||||
|  *	 | ||||
|  *	Asm glue for ELF images run inside MOL | ||||
|  *    | ||||
|  *   Copyright (C) 2001, 2002, 2003 Samuel Rydh (samuel@ibrium.se) | ||||
|  *    | ||||
|  *   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 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| changequote([[[[[,]]]]]) [[[[[  /* shield includes from m4-expansion */ | ||||
| #include "asm/asmdefs.h" | ||||
| #include "asm/processor.h" | ||||
| #include "osi.h" | ||||
| 		 | ||||
| /************************************************************************/ | ||||
| /*	Macros								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| #define ILLEGAL_VECTOR( v )	.org __vectors + v ; bl trap_error ; | ||||
| #define VECTOR( v, dummystr )	.org __vectors + v ; vector__##v | ||||
|  | ||||
| MACRO(EXCEPTION_PREAMBLE, [ | ||||
| 	mtsprg1	r1		// scratch | ||||
| 	mfsprg0	r1		// exception stack in sprg0 | ||||
| 	addi	r1,r1,-80	// push exception frame | ||||
|  | ||||
| 	stw	r0,0(r1)	// save r0 | ||||
| 	mfsprg1	r0 | ||||
| 	stw	r0,4(r1)	// save r1 | ||||
| 	stw	r2,8(r1)	// save r2 | ||||
| 	stw	r3,12(r1)	// save r3 | ||||
| 	stw	r4,16(r1) | ||||
| 	stw	r5,20(r1) | ||||
| 	stw	r6,24(r1) | ||||
| 	stw	r7,28(r1) | ||||
| 	stw	r8,32(r1) | ||||
| 	stw	r9,36(r1) | ||||
| 	stw	r10,40(r1) | ||||
| 	stw	r11,44(r1) | ||||
| 	stw	r12,48(r1) | ||||
|  | ||||
| 	mflr	r0 | ||||
| 	stw	r0,52(r1) | ||||
| 	mfcr	r0 | ||||
| 	stw	r0,56(r1) | ||||
| 	mfctr	r0 | ||||
| 	stw	r0,60(r1) | ||||
| 	mfxer	r0 | ||||
| 	stw	r0,64(r1) | ||||
|  | ||||
| 	// 76(r1) unused | ||||
| 	addi	r1,r1,-16	// call conventions uses 0(r1) and 4(r1)... | ||||
| ]) | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	stack space							*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| 	.section .bss | ||||
| 	.balign 32 | ||||
| 	.space  32*1024		// 32 K client stack | ||||
| client_stack: | ||||
| 	.space	128 | ||||
|  | ||||
| 	.space	64*1024		// 64 K stack | ||||
| stack:	.space  64 | ||||
|  | ||||
| 	.space  32*1024		// 32 K exception stack | ||||
| estack:	.space	128 | ||||
| 	 | ||||
| 	 | ||||
| /************************************************************************/ | ||||
| /*	entry								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| 	.text | ||||
| GLOBL(_start): | ||||
| 	li	r0,0 | ||||
| 	mtmsr	r0 | ||||
| 	 | ||||
| 	LOADI	r1,estack | ||||
| 	mtsprg0 r1			// setup exception stack | ||||
| 	LOADI	r1,stack | ||||
|  | ||||
| 	// copy exception vectors | ||||
| 	LOADI	r3,__vectors | ||||
| 	li	r4,0 | ||||
| 	li	r5,__vectors_end - __vectors + 16 | ||||
| 	rlwinm	r5,r5,0,0,28 | ||||
| 1:	lwz	r6,0(r3) | ||||
| 	lwz	r7,4(r3) | ||||
| 	lwz	r8,8(r3) | ||||
| 	lwz	r9,12(r3) | ||||
| 	stw	r6,0(r4) | ||||
| 	stw	r7,4(r4) | ||||
| 	stw	r8,8(r4) | ||||
| 	stw	r9,12(r4) | ||||
| 	dcbst	0,r4 | ||||
| 	sync | ||||
| 	icbi	0,r4 | ||||
| 	sync | ||||
| 	addi	r5,r5,-16 | ||||
| 	addi	r3,r3,16 | ||||
| 	addi	r4,r4,16 | ||||
| 	cmpwi	r5,0 | ||||
| 	bgt	1b | ||||
| 	isync | ||||
|  | ||||
| 	bl	setup_mmu | ||||
| 	bl	entry | ||||
| 1:	nop | ||||
| 	b	1b | ||||
|  | ||||
|  | ||||
| 	/* According to IEEE 1275, PPC bindings: | ||||
| 	 *	 | ||||
| 	 * 	MSR = FP, ME + (DR|IR) | ||||
| 	 *	r1 = stack (32 K + 32 bytes link area above) | ||||
| 	 *	r5 = clint interface handler | ||||
| 	 *	r6 = address of client program arguments (unused) | ||||
| 	 *	r7 = length of client program arguments (unsed) | ||||
| 	 */ | ||||
| saved_stack: | ||||
| 	.long	0 | ||||
| 	/* void call_elf( entry ) */ | ||||
| GLOBL(call_elf): | ||||
| 	mflr	r0 | ||||
| 	stwu	r1,-16(r1) | ||||
| 	stw	r0,20(r1) | ||||
| 	mtlr	r3 | ||||
| 	LOADI	r8,saved_stack		// save our stack pointer | ||||
| 	stw	r1,0(r8) | ||||
| 	LOADI	r1,client_stack | ||||
| 	LOADI	r5,of_client_callback	// r5 = callback | ||||
| 	li	r6,0			// r6 = address of client program arguments (unused) | ||||
| 	li	r7,0			// r7 = length of client program arguments (unused) | ||||
| 	li	r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR | ||||
| 	mtmsr	r0 | ||||
| 	blrl | ||||
|  | ||||
| 	LOADI	r8,saved_stack		// restore stack pointer | ||||
| 	mr	r1,r8 | ||||
| 	lwz	r0,20(r1) | ||||
| 	mtlr	r0 | ||||
| 	addi	r1,r1,16 | ||||
| 	// XXX: should restore r12-r31 etc..  | ||||
| 	// we should not really come here though | ||||
| 	blr | ||||
|  | ||||
| GLOBL(of_client_callback): | ||||
| 	LOADI	r4,saved_stack | ||||
| 	lwz	r4,0(r4) | ||||
| 	stwu	r4,-32(r4) | ||||
| 	mflr	r5 | ||||
| 	stw	r5,32+4(r4) | ||||
| 	stw	r1,8(r4)		// save caller stack | ||||
| 	mr	r1,r4 | ||||
| 	stw	r2,12(r1) | ||||
| 	stw	r0,16(r1) | ||||
| 	mfctr	r2 | ||||
| 	stw	r2,20(r1) | ||||
| 	mfcr	r2 | ||||
| 	stw	r2,24(r1) | ||||
| 	mfxer	r2 | ||||
| 	stw	r2,28(r1) | ||||
| 	// do we need to save more registers? | ||||
| 	bl	of_client_interface | ||||
| 	lwz	r4,32+4(r1) | ||||
| 	mtlr	r4 | ||||
| 	lwz	r2,20(r1) | ||||
| 	mtctr	r2 | ||||
| 	lwz	r2,24(r1) | ||||
| 	mtcr	r2 | ||||
| 	lwz	r2,28(r1) | ||||
| 	mtxer	r2 | ||||
| 	lwz	r2,12(r1) | ||||
| 	lwz	r0,16(r1) | ||||
| 	lwz	r1,8(r1)		// restore caller stack | ||||
| 	blr | ||||
| 	 | ||||
| 	/* rtas glue (must be reloctable) */ | ||||
| GLOBL(of_rtas_start): | ||||
| 	/* r3 = argument buffer, r4 = of_rtas_start */ | ||||
| 	/* according to the CHRP standard, cr must be preserved (cr0/cr1 too?) */ | ||||
| 	mr      r6,r3 | ||||
| 	LOADI	r3,OSI_SC_MAGIC_R3 | ||||
| 	LOADI	r4,OSI_SC_MAGIC_R4 | ||||
| 	li	r5,OSI_OF_RTAS | ||||
| 	sc | ||||
| 	blr | ||||
| GLOBL(of_rtas_end): | ||||
|  | ||||
|  | ||||
| 	/* used in a hack to the newworld calibration */ | ||||
| GLOBL(nw_dec_calibration): | ||||
| 	.long	0 | ||||
| GLOBL(timer_calib_start): | ||||
| 	LOADI	r3,nw_dec_calibration | ||||
| 	lwz	r3,0(r3) | ||||
| 	blr | ||||
| GLOBL(timer_calib_end): | ||||
|  | ||||
|  | ||||
| /************************************************************************/ | ||||
| /*	vectors								*/ | ||||
| /************************************************************************/ | ||||
|  | ||||
| GLOBL(__vectors): | ||||
| 	nop			// NULL-jmp trap | ||||
| 1:	nop			// | ||||
| 	b	1b | ||||
|  | ||||
| exception_return: | ||||
| 	addi	r1,r1,16	// pop ABI frame | ||||
|  | ||||
| 	lwz	r0,52(r1) | ||||
| 	mtlr	r0 | ||||
| 	lwz	r0,56(r1) | ||||
| 	mtcr	r0 | ||||
| 	lwz	r0,60(r1) | ||||
| 	mtctr	r0 | ||||
| 	lwz	r0,64(r1) | ||||
| 	mtxer	r0 | ||||
|  | ||||
| 	lwz	r0,0(r1)	// restore r0 | ||||
| 	lwz	r2,8(r1)	// restore r2 | ||||
| 	lwz	r3,12(r1)	// restore r3 | ||||
| 	lwz	r4,16(r1) | ||||
| 	lwz	r5,20(r1) | ||||
| 	lwz	r6,24(r1) | ||||
| 	lwz	r7,28(r1) | ||||
| 	lwz	r8,32(r1) | ||||
| 	lwz	r9,36(r1) | ||||
| 	lwz	r10,40(r1) | ||||
| 	lwz	r11,44(r1) | ||||
| 	lwz	r12,48(r1) | ||||
| 	lwz	r1,4(r1)	// restore r1 | ||||
| 	rfi | ||||
|  | ||||
| trap_error: | ||||
| 	mflr	r3 | ||||
| 	b	unexpected_excep | ||||
|  | ||||
| ILLEGAL_VECTOR( 0x100 ) | ||||
| ILLEGAL_VECTOR( 0x200 ) | ||||
|  | ||||
| VECTOR( 0x300, "DSI" ): | ||||
| 	EXCEPTION_PREAMBLE | ||||
| 	LOADI	r3,dsi_exception | ||||
| 	mtctr	r3 | ||||
| 	bctrl | ||||
| 	b	exception_return | ||||
|  | ||||
| VECTOR( 0x400, "ISI" ): | ||||
| 	EXCEPTION_PREAMBLE | ||||
| 	LOADI	r3,isi_exception | ||||
| 	mtctr	r3 | ||||
| 	bctrl | ||||
| 	b	exception_return | ||||
| 	 | ||||
| 	ILLEGAL_VECTOR( 0x500 ) | ||||
| 	ILLEGAL_VECTOR( 0x600 ) | ||||
| 	ILLEGAL_VECTOR( 0x700 ) | ||||
|  | ||||
| VECTOR( 0x800, "FPU" ):	 | ||||
| 	mtsprg1	r3 | ||||
| 	mfsrr1	r3 | ||||
| 	ori	r3,r3,0x2000 | ||||
| 	mtsrr1	r3 | ||||
| 	mfsprg1	r3 | ||||
| 	rfi | ||||
|  | ||||
| ILLEGAL_VECTOR( 0x900 ) | ||||
| ILLEGAL_VECTOR( 0xa00 ) | ||||
| ILLEGAL_VECTOR( 0xb00 ) | ||||
| ILLEGAL_VECTOR( 0xc00 ) | ||||
| ILLEGAL_VECTOR( 0xd00 ) | ||||
| ILLEGAL_VECTOR( 0xe00 ) | ||||
| ILLEGAL_VECTOR( 0xf00 ) | ||||
| ILLEGAL_VECTOR( 0xf20 ) | ||||
| ILLEGAL_VECTOR( 0x1000 ) | ||||
| ILLEGAL_VECTOR( 0x1100 ) | ||||
| ILLEGAL_VECTOR( 0x1200 ) | ||||
| ILLEGAL_VECTOR( 0x1300 ) | ||||
| ILLEGAL_VECTOR( 0x1400 ) | ||||
| ILLEGAL_VECTOR( 0x1500 ) | ||||
| ILLEGAL_VECTOR( 0x1600 ) | ||||
| ILLEGAL_VECTOR( 0x1700 ) | ||||
|  | ||||
| GLOBL(__vectors_end): | ||||
|  | ||||
|  | ||||
| #define CACHE_LINE_SIZE         32 | ||||
| #define LG_CACHE_LINE_SIZE      5 | ||||
|  | ||||
| /* flush_icache_range( ulong start, ulong stop) */ | ||||
| GLOBL(flush_icache_range): | ||||
|         li      r5,CACHE_LINE_SIZE-1 | ||||
|         andc    r3,r3,r5 | ||||
|         subf    r4,r3,r4 | ||||
|         add     r4,r4,r5 | ||||
|         srwi.   r4,r4,LG_CACHE_LINE_SIZE | ||||
|         beqlr | ||||
|         mtctr   r4 | ||||
|         mr      r6,r3 | ||||
| 1:      dcbst   0,r3 | ||||
|         addi    r3,r3,CACHE_LINE_SIZE | ||||
|         bdnz    1b | ||||
|         sync                            /* wait for dcbst's to get to ram */ | ||||
|         mtctr   r4 | ||||
| 2:      icbi    0,r6 | ||||
|         addi    r6,r6,CACHE_LINE_SIZE | ||||
|         bdnz    2b | ||||
|         sync                            /* additional sync needed on g4 */ | ||||
|         isync | ||||
|         blr | ||||
							
								
								
									
										35
									
								
								arch/ppc/timebase.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								arch/ppc/timebase.S
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| changequote([[[[[,]]]]]) [[[[[  /* shield includes from m4-expansion */ | ||||
| #include "asm/asmdefs.h" | ||||
| #include "asm/processor.h" | ||||
|  | ||||
| /* | ||||
|  * unsigned long long _get_ticks(void); | ||||
|  */ | ||||
| GLOBL(_get_ticks): | ||||
| 1:      mftbu   r3 | ||||
|         mftb    r4 | ||||
|         mftbu   r5 | ||||
|         cmpw    0,r3,r5 | ||||
|         bne     1b | ||||
|         blr | ||||
|  | ||||
| /* | ||||
|  * Delay for a number of ticks | ||||
|  */ | ||||
| GLOBL(_wait_ticks): | ||||
|         mflr    r8              /* save link register */ | ||||
|         mr      r7, r3          /* save tick count */ | ||||
|         bl      _get_ticks       /* Get start time */ | ||||
|  | ||||
|         /* Calculate end time */ | ||||
|         addc    r7, r4, r7      /* Compute end time lower */ | ||||
|         addze   r6, r3          /*     and end time upper */ | ||||
|  | ||||
| 1:      bl      _get_ticks       /* Get current time */ | ||||
|         subfc   r4, r4, r7      /* Subtract current time from end time */ | ||||
|         subfe.  r3, r3, r6 | ||||
|         bge     1b              /* Loop until time expired */ | ||||
|  | ||||
|         mtlr    r8              /* restore link register */ | ||||
|         blr | ||||
|  | ||||
							
								
								
									
										18
									
								
								arch/unix/Kconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								arch/unix/Kconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
|  | ||||
| config HOST_UNIX | ||||
| 	bool "Build Hosted Unix binary" | ||||
| 	default y | ||||
| 	help | ||||
| 	  Build a version of the OpenBIOS kernel that runs in a  | ||||
| 	  Unix-like operating system. | ||||
|  | ||||
| config UNIX_QT | ||||
| 	depends HOST_UNIX | ||||
| 	bool "QT frontend for Unix binary" | ||||
| 	default n | ||||
| 	help | ||||
| 	  Enable this option if you wish to add a graphical user  | ||||
| 	  interface to the openbios hosted unix binary. This option | ||||
| 	  needs the QT library installed. | ||||
|  | ||||
| source "arch/unix/plugins/Kconfig" | ||||
							
								
								
									
										29
									
								
								arch/unix/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								arch/unix/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| #  | ||||
|  | ||||
| include			../../config/Makefile.top | ||||
|  | ||||
| SUBDIRS-$(CONFIG_PLUGINS)	= plugins | ||||
| SUBDIRS-$(CONFIG_UNIX_QT)	= gui_qt | ||||
|  | ||||
| DICTIONARIES		= unix | ||||
| unix-SRC		= tree.fs $(ARCHDICT_SRC) | ||||
|  | ||||
| PROGRAMS		= unix | ||||
|  | ||||
| unix-OBJS               = $(unix-y) | ||||
| unix-y			+= blk.o  | ||||
| unix-y			+= boot.o  | ||||
| unix-y			+= unix.o  | ||||
| unix-y			+= $(KOBJS)  | ||||
| unix-y			+= $(MODULE_LIBS) $(FS_LIBS) $(DRIVER_LIBS) $(LIBC_LIBS) | ||||
| unix-$(CONFIG_PLUGINS)  += plugins.o  | ||||
|  | ||||
| unix-LDFLAGS		= $(unix-LDFLAGS-$(CONFIG_PLUGINS)) | ||||
| unix-LDFLAGS-y		= -rdynamic $(LIBDL_LDFLAGS) | ||||
| unix-LDFLAGS-n		=  | ||||
| unix-LDADD		=  | ||||
|  | ||||
| INCLUDES		= -I../../kernel -I../../kernel/include -DBOOTSTRAP | ||||
|  | ||||
| include			$(rules)/Rules.forth | ||||
| include			$(rules)/Rules.make | ||||
							
								
								
									
										115
									
								
								arch/unix/blk.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								arch/unix/blk.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | ||||
| /*  | ||||
|  *  <arch/unix/blk.c> | ||||
|  *	 | ||||
|  *	block device emulation for unix hosts  | ||||
|  *    | ||||
|  *   Copyright (C) 2004 Stefan Reinauer <stepan@openbios.org> | ||||
|  *    | ||||
|  *   This program is free software; you can redistribute it and/or | ||||
|  *   modify it under the terms of the GNU General Public License | ||||
|  *   version 2 | ||||
|  *    | ||||
|  */ | ||||
|  | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "blk.h" | ||||
|  | ||||
| typedef struct { | ||||
| 	int	unit; | ||||
| 	int	channel; | ||||
| } blk_data_t; | ||||
|  | ||||
|  | ||||
| DECLARE_NODE( blk, INSTALL_OPEN, sizeof(blk_data_t), "+/unix/block/disk" ); | ||||
|  | ||||
| static void | ||||
| blk_open( blk_data_t *pb ) | ||||
| { | ||||
| 	phandle_t ph; | ||||
|  | ||||
| 	fword("my-unit"); | ||||
|  | ||||
| 	pb->unit = POP(); | ||||
| 	pb->channel = 0;	/* FIXME */ | ||||
|  | ||||
| 	selfword("open-deblocker"); | ||||
|  | ||||
| 	/* interpose disk-label */ | ||||
| 	ph = find_dev("/packages/disk-label"); | ||||
| 	fword("my-args"); | ||||
| 	PUSH_ph( ph ); | ||||
| 	fword("interpose"); | ||||
|  | ||||
| 	/* printk("osi-blk: open %d\n", pb->unit ); */ | ||||
|  | ||||
| 	PUSH( -1 ); | ||||
| } | ||||
|  | ||||
| static void | ||||
| blk_close( blk_data_t *pb ) | ||||
| { | ||||
| 	selfword("close-deblocker"); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ( buf blk nblks -- actual ) */ | ||||
| static void | ||||
| blk_read_blocks( blk_data_t *pb ) | ||||
| { | ||||
| 	cell i, n = POP(); | ||||
| 	cell blk = POP(); | ||||
| 	char *dest = (char*)POP(); | ||||
| 	 | ||||
| 	// printk("blk_read_blocks %x block=%d n=%d\n", (ucell)dest, blk, n ); | ||||
| 	 | ||||
| 	for( i=0; i<n; ) { | ||||
| 		char buf[4096]; | ||||
| 		ucell m = MIN( n-i, sizeof(buf)/512 ); | ||||
|  | ||||
| 		if( read_from_disk(pb->channel, pb->unit, blk+i, (ucell)buf, m*512) < 0 ) { | ||||
| 			printk("read_from_disk: error\n"); | ||||
| 			RET(0); | ||||
| 		} | ||||
| 		memcpy( dest, buf, m * 512 ); | ||||
| 		i += m; | ||||
| 		dest += m * 512; | ||||
| 	} | ||||
| 	PUSH( n ); | ||||
| } | ||||
|  | ||||
| /* ( -- bs ) */ | ||||
| static void | ||||
| blk_block_size( blk_data_t *pb ) | ||||
| { | ||||
| 	PUSH( 512 ); | ||||
| } | ||||
|  | ||||
| /* ( -- maxbytes ) */ | ||||
| static void | ||||
| blk_max_transfer( blk_data_t *pb ) | ||||
| { | ||||
| 	PUSH( 1024*1024 ); | ||||
| } | ||||
|  | ||||
| static void | ||||
| blk_initialize( blk_data_t *pb ) | ||||
| { | ||||
| 	fword("is-deblocker"); | ||||
| } | ||||
|  | ||||
|  | ||||
| NODE_METHODS( blk ) = { | ||||
| 	{ NULL,			blk_initialize	}, | ||||
| 	{ "open",		blk_open	}, | ||||
| 	{ "close",		blk_close	}, | ||||
| 	{ "read-blocks",	blk_read_blocks	}, | ||||
| 	{ "block-size",		blk_block_size	}, | ||||
| 	{ "max-transfer",	blk_max_transfer}, | ||||
| }; | ||||
|  | ||||
| void | ||||
| blk_init( void ) | ||||
| { | ||||
| 	REGISTER_NODE( blk ); | ||||
| } | ||||
							
								
								
									
										8
									
								
								arch/unix/blk.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								arch/unix/blk.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
|  | ||||
| #ifndef _H_BLK | ||||
| #define _H_BLK | ||||
|  | ||||
| extern void 	blk_init( void ); | ||||
| extern int	read_from_disk( int channel, int unit, int blk, unsigned long mphys, int size ); | ||||
|  | ||||
| #endif   /* _H_BLK */ | ||||
							
								
								
									
										80
									
								
								arch/unix/boot.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								arch/unix/boot.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | ||||
| /* | ||||
|  * | ||||
|  */ | ||||
| #undef BOOTSTRAP | ||||
| #include "openbios/config.h" | ||||
| #include "openbios/bindings.h" | ||||
| #include "openbios/elfload.h" | ||||
| #include "openbios/nvram.h" | ||||
| #include "libc/diskio.h" | ||||
|  | ||||
| void boot(void); | ||||
| void *load_elf(char *spec); | ||||
|  | ||||
| void | ||||
| *load_elf(char *spec) | ||||
| { | ||||
| #if 0 | ||||
| 	int fd; | ||||
| 	void *entry=NULL; | ||||
| 	int i, lszz_offs, elf_offs; | ||||
| 	char buf[128]; // , *addr; | ||||
| 	Elf_ehdr ehdr; | ||||
| 	Elf_phdr *phdr; | ||||
| 	size_t s; | ||||
|  | ||||
| 	if( (fd=open_io(spec)) == -1 ) | ||||
| 		return NULL; | ||||
|  | ||||
| 	if( (elf_offs=find_elf(fd)) < 0 ) { | ||||
| 		printk("----> %s is not an ELF image\n", buf ); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if( !(phdr=elf_readhdrs(fd, 0, &ehdr)) ) { | ||||
| 		printk("elf32_readhdrs failed\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	(ullong *)entry = ehdr.e_entry; | ||||
| 	 | ||||
| 	lszz_offs = elf_offs; | ||||
| 	for( i=0; i<ehdr.e_phnum; i++ ) { | ||||
| 		s = MIN( phdr[i].p_filesz, phdr[i].p_memsz ); | ||||
| 		seek_io( fd, elf_offs + phdr[i].p_offset ); | ||||
| 		/* printk("filesz: %08lX memsz: %08lX p_offset: %08lX p_vaddr %08lX\n",  | ||||
| 		   phdr[i].p_filesz, phdr[i].p_memsz, phdr[i].p_offset, | ||||
| 		   phdr[i].p_vaddr ); */ | ||||
| 		if( phdr[i].p_vaddr != phdr[i].p_paddr ) | ||||
| 			printk("WARNING: ELF segment virtual addr != physical addr\n"); | ||||
| 		lszz_offs = MAX( lszz_offs, elf_offs + phdr[i].p_offset + phdr[i].p_filesz ); | ||||
| 		if( !s ) | ||||
| 			continue; | ||||
|  | ||||
| 		 printk("ELF ROM-section loaded at %08lX (size %08lX)\n", | ||||
| 				 (ulong)phdr[i].p_vaddr, (ulong)phdr[i].p_memsz); | ||||
| 	} | ||||
| 	free( phdr ); | ||||
| 	return entry; | ||||
| #else  | ||||
| 	return NULL; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void | ||||
| boot( void ) | ||||
| { | ||||
| 	char *path=pop_fstr_copy(); | ||||
| 	void *entry; | ||||
| 	 | ||||
| 	if(!path) { | ||||
| 		printk("[unix] Booting default not supported.\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 	printk("[unix] Booting '%s'\n",path); | ||||
| 	entry=load_elf(path); | ||||
| 	if(entry) | ||||
| 		printk("successfully loaded client at %x.\n", (ucell)entry); | ||||
| 	else | ||||
| 		printk("failed.\n"); | ||||
| } | ||||
							
								
								
									
										22
									
								
								arch/unix/build.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								arch/unix/build.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| <build condition="HOST_UNIX"> | ||||
|  | ||||
|  <dictionary name="openbios-unix" init="openbios" target="forth"> | ||||
|   <object source="tree.fs"/> | ||||
|  </dictionary> | ||||
|  | ||||
|  <executable name="openbios-unix" target="target"> | ||||
|   <rule> | ||||
| 	$(CC) $(CFLAGS) -rdynamic $(LIBDL_LDFLAGS) -o $@ $^ | ||||
|   </rule> | ||||
|   <object source="unix.c" flags="-DBOOTSTRAP"/> | ||||
|   <object source="boot.c" flags="-DBOOTSTRAP"/> | ||||
|   <object source="blk.c"  flags="-DBOOTSTRAP"/> | ||||
|   <object source="plugins.c" flags="-DBOOTSTRAP" condition="PLUGINS"/> | ||||
|   <external-object source="libbootstrap.a"/> | ||||
|   <external-object source="libmodules.a"/> | ||||
|   <external-object source="libdrivers.a"/> | ||||
|   <external-object source="liblibc.a"/> | ||||
|   <external-object source="libfs.a"/> | ||||
|  </executable> | ||||
|  | ||||
| </build> | ||||
							
								
								
									
										42
									
								
								arch/unix/gui_qt/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								arch/unix/gui_qt/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| # | ||||
| # Makefile of QT user interface for OpenBIOS | ||||
| #  | ||||
| #  (C) 2004 Stefan Reinauer <stepan@openbios.org> | ||||
| # | ||||
| # This program is free software; you can redistribute it and/or | ||||
| # modify it under the terms of the GNU General Public License | ||||
| # version 2 | ||||
| #    | ||||
|  | ||||
| include		../../../config/Makefile.top | ||||
|  | ||||
| XTARGETS                = qt | ||||
|  | ||||
| qt-OBJS                 = $(obj-y) | ||||
| obj-y                   += gui_qt.o | ||||
|  | ||||
| QMAKE		= qmake | ||||
| UIDIR	= $(shell pwd ) | ||||
| TOPDIR		= $(shell cd $(top_srcdir) ; pwd) | ||||
| ABSOINC		= $(shell cd $(ARCHINCLUDES) 2> /dev/null ; pwd ) | ||||
|  | ||||
| export UIDIR TOPDIR ABSOINC | ||||
|  | ||||
| $(ODIR)/makefile.qmake: gui-qt.pro Makefile | ||||
| 	@echo "ODIR: $(ODIR)" | ||||
| 	@test -d $(ODIR) || $(INSTALL) -d $(ODIR) | ||||
| 	@test -d $(ODIR)/qbuild || $(INSTALL) -d $(ODIR)/qbuild | ||||
| 	@install -m 644 gui-qt.pro $(ODIR)/ | ||||
| 	cd $(ODIR) ; $(QMAKE) -o makefile.qmake | ||||
|  | ||||
| $(ODIR)/libgui_qt.a: $(ODIR)/makefile.qmake $(wildcard *.cpp) | ||||
| 	cd $(ODIR) ; $(MAKE) -f makefile.qmake | ||||
| 	@ln -f $(ODIR)/qbuild/libgui_qt.a $@ | ||||
|  | ||||
| clean-local: | ||||
| 	@rm -f $(ODIR)/makefile.qmake | ||||
| 	@rm -rf $(QBUILDDIR) | ||||
|  | ||||
| INCLUDES	= -I$(top_srcdir)/include -DBOOTSTRAP | ||||
|  | ||||
| include		$(rules)/Rules.make | ||||
							
								
								
									
										129
									
								
								arch/unix/gui_qt/gui-qt.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								arch/unix/gui_qt/gui-qt.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,129 @@ | ||||
| /* tag: qt user interface fb class | ||||
|  *  | ||||
|  * Copyright (C) 2003-2004 Stefan Reinauer | ||||
|  * | ||||
|  * See the file "COPYING" for further information about | ||||
|  * the copyright and warranty status of this work. | ||||
|  */ | ||||
|  | ||||
| #include "gui-qt.h" | ||||
| #include "logo.xpm" | ||||
|  | ||||
| #include <iostream> | ||||
|  | ||||
| static const int sizex=640; | ||||
| static const int sizey=480; | ||||
| static const int depth=8; | ||||
|  | ||||
| static unsigned char color[256][3]={  | ||||
| 	{ 0x00, 0x00, 0x00 },  | ||||
| 	{ 0x00, 0x00, 0xaa },  | ||||
| 	{ 0x00, 0xaa, 0x00 },  | ||||
| 	{ 0x00, 0xaa, 0xaa },  | ||||
| 	{ 0xaa, 0x00, 0x00 },  | ||||
| 	{ 0xaa, 0x00, 0xaa },  | ||||
| 	{ 0xaa, 0x55, 0x00 },  | ||||
| 	{ 0xaa, 0xaa, 0xaa },  | ||||
| 	{ 0x55, 0x55, 0x55 },  | ||||
| 	{ 0x55, 0x55, 0xff },  | ||||
| 	{ 0x55, 0xff, 0x55 },  | ||||
| 	{ 0x55, 0xff, 0xff },  | ||||
| 	{ 0xff, 0x55, 0x55 },  | ||||
| 	{ 0xff, 0x55, 0xff },  | ||||
| 	{ 0xff, 0xff, 0x55 },  | ||||
| 	{ 0xff, 0xff, 0xff }, | ||||
| }; | ||||
|  | ||||
| FrameBufferWidget::FrameBufferWidget(QWidget *parent, const char * name) | ||||
| : QWidget(parent, name, Qt::WType_TopLevel) | ||||
| { | ||||
| 	setCaption ("OpenBIOS"); | ||||
| 	setIcon(QPixmap(logo)); | ||||
|  | ||||
| 	QPopupMenu *file = new QPopupMenu (this); | ||||
|  | ||||
| 	file->insertItem( "E&xit",  this, SLOT(quit()), CTRL+Key_Q ); | ||||
| 	 | ||||
| 	QPopupMenu *help = new QPopupMenu( this ); | ||||
| 	help->insertItem("&About OpenBIOS", this, SLOT(about()), CTRL+Key_H ); | ||||
| 	help->insertItem( "About &Qt", this, SLOT(aboutQt()) ); | ||||
| 	 | ||||
| 	menu = new QMenuBar( this ); | ||||
| 	Q_CHECK_PTR( menu ); | ||||
| 	menu->insertItem( "&File", file ); | ||||
| 	menu->insertSeparator(); | ||||
| 	menu->insertItem( "&Help", help ); | ||||
| 	menu->setSeparator( QMenuBar::InWindowsStyle ); | ||||
| 	 | ||||
| 	setFixedSize(sizex,sizey+menu->heightForWidth(sizex)); | ||||
| 	 | ||||
| 	buffer.create(sizex, sizey, depth, 256); | ||||
|  | ||||
| 	for (int i=16; i < 256; i++) { | ||||
| 		color[i][0]=i; | ||||
| 		color[i][1]=i; | ||||
| 		color[i][2]=i; | ||||
| 	} | ||||
| 		 | ||||
| 	for (int i=0; i< 256; i++) | ||||
| 		buffer.setColor(i, qRgb(color[i][0], color[i][1], color[i][2])); | ||||
| 	 | ||||
| 	buffer.fill( 0 ); | ||||
| 	 | ||||
| 	updatetimer=new QTimer(this); | ||||
| 	connect( updatetimer, SIGNAL(timeout()), this, SLOT(update()) ); | ||||
| 	updatetimer->start(200,FALSE); | ||||
| 	 | ||||
| 	setMouseTracking( TRUE ); | ||||
| } | ||||
|  | ||||
| unsigned char * FrameBufferWidget::getFrameBuffer(void) | ||||
| { | ||||
| 	return buffer.bits(); | ||||
| } | ||||
|  | ||||
| void FrameBufferWidget::paintEvent ( QPaintEvent * ) | ||||
| { | ||||
| 	QPainter p( this ); | ||||
| 	p.drawImage(0,menu->heightForWidth(sizex),buffer, 0,0, sizex, sizey); | ||||
| } | ||||
|  | ||||
| void FrameBufferWidget::about() | ||||
| { | ||||
| 	QMessageBox::about( this, "About OpenBIOS", | ||||
| 			  "              Welcome to OpenBIOS 1.01\n" | ||||
| 			  "  IEEE 1275-1994 Open Firmware implementation\n\n" | ||||
| 			  "written by Stefan Reinauer <stepan@openbios.org>\n\n" | ||||
| 			  "                http://www.openbios.org/\n"); | ||||
| } | ||||
|  | ||||
| void FrameBufferWidget::aboutQt() | ||||
| {                                                                                | ||||
| 	QMessageBox::aboutQt( this, "OpenBIOS" ); | ||||
| }                                                                                | ||||
|                                                                                  | ||||
| void FrameBufferWidget::quit() | ||||
| { | ||||
| 	extern volatile int gui_running; | ||||
| 	extern volatile int runforth; | ||||
|  | ||||
| 	gui_running=0; | ||||
| 	runforth=0; | ||||
|  | ||||
| 	qApp->quit(); | ||||
| } | ||||
|  | ||||
| void FrameBufferWidget::update() | ||||
| { | ||||
| 	QPainter p( this ); | ||||
| 	p.drawImage(0,menu->heightForWidth(sizex),buffer, 0,0, sizex, sizey); | ||||
| } | ||||
|  | ||||
| void FrameBufferWidget::keyPressEvent(QKeyEvent * e) | ||||
| { | ||||
| 	int a=e->ascii(); | ||||
| 	if (a) { | ||||
| 		std::cout << " key '" << e->text() << "' pressed" << std::endl; | ||||
| 	} | ||||
| } | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 Stefan Reinauer
					Stefan Reinauer