- Support for a LinuxBIOS version number (start at 1.0.0)
- Support for remember our compile time environment - Simple and always correct version of compute_ip_checksum - Improve message strings in crt0.base - Initial support for > 2G ram. - Sizeram now returns a list of valid ranges of ram - pci resource allocation now starts at 0xC0000000 - Update sizeram for every northbridge - Misc cleanups.
This commit is contained in:
parent
9deed69cdd
commit
e803bc7bd4
63 changed files with 1370 additions and 912 deletions
340
COPYING
Normal file
340
COPYING
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, 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
|
||||
|
||||
Appendix: 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., 675 Mass Ave, Cambridge, MA 02139, 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.
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
#include <mem.h>
|
||||
#include <ip_checksum.h>
|
||||
#include <boot/linuxbios_tables.h>
|
||||
#include <boot/linuxbios_table.h>
|
||||
#include <printk.h>
|
||||
#include <string.h>
|
||||
#include <version.h>
|
||||
|
||||
|
||||
struct lb_header *lb_table_init(unsigned long addr)
|
||||
{
|
||||
|
|
@ -73,28 +76,58 @@ struct lb_memory *lb_memory(struct lb_header *header)
|
|||
|
||||
struct lb_mainboard *lb_mainboard(struct lb_header *header)
|
||||
{
|
||||
#define __STR(X) #X
|
||||
#define STR(X) __STR(X)
|
||||
static const char vendor[] = STR(MAINBOARD_VENDOR);
|
||||
static const char part_number[] = STR(MAINBOARD_PART_NUMBER);
|
||||
struct lb_record *rec;
|
||||
struct lb_mainboard *mainboard;
|
||||
rec = lb_new_record(header);
|
||||
mainboard = (struct lb_mainboard *)rec;
|
||||
mainboard->tag = LB_TAG_MAINBOARD;
|
||||
mainboard->size = sizeof(*mainboard) +
|
||||
sizeof(vendor) + sizeof(part_number);
|
||||
|
||||
mainboard->size = (sizeof(*mainboard) +
|
||||
strlen(mainboard_vendor) + 1 +
|
||||
strlen(mainboard_part_number) + 1 +
|
||||
3) & ~3;
|
||||
|
||||
mainboard->vendor_idx = 0;
|
||||
mainboard->part_number_idx = sizeof(vendor);
|
||||
mainboard->part_number_idx = strlen(mainboard_vendor) + 1;
|
||||
|
||||
memcpy(mainboard->strings + mainboard->vendor_idx,
|
||||
vendor, sizeof(vendor));
|
||||
mainboard_vendor, strlen(mainboard_vendor) + 1);
|
||||
memcpy(mainboard->strings + mainboard->part_number_idx,
|
||||
part_number, sizeof(part_number));
|
||||
#undef STR
|
||||
#undef __STR
|
||||
mainboard_part_number, strlen(mainboard_part_number) + 1);
|
||||
|
||||
return mainboard;
|
||||
}
|
||||
|
||||
void lb_strings(struct lb_header *header)
|
||||
{
|
||||
static const struct {
|
||||
uint32_t tag;
|
||||
const uint8_t *string;
|
||||
} strings[] = {
|
||||
{ LB_TAG_VERSION, linuxbios_version, },
|
||||
{ LB_TAG_EXTRA_VERSION, linuxbios_extra_version, },
|
||||
{ LB_TAG_BUILD, linuxbios_build, },
|
||||
{ LB_TAG_COMPILE_TIME, linuxbios_compile_time, },
|
||||
{ LB_TAG_COMPILE_BY, linuxbios_compile_by, },
|
||||
{ LB_TAG_COMPILE_HOST, linuxbios_compile_host, },
|
||||
{ LB_TAG_COMPILE_DOMAIN, linuxbios_compile_domain, },
|
||||
{ LB_TAG_COMPILER, linuxbios_compiler, },
|
||||
{ LB_TAG_LINKER, linuxbios_linker, },
|
||||
{ LB_TAG_ASSEMBLER, linuxbios_assembler, },
|
||||
};
|
||||
int i;
|
||||
for(i = 0; i < sizeof(strings)/sizeof(strings[0]); i++) {
|
||||
struct lb_string *rec;
|
||||
size_t len;
|
||||
rec = lb_new_record(header);
|
||||
len = strlen(strings[i].string);
|
||||
rec->tag = strings[i].tag;
|
||||
rec->size = (sizeof(*rec) + len + 1 + 3) & ~3;
|
||||
memcpy(rec->string, strings[i].string, len+1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Some version of gcc have problems with 64 bit types so
|
||||
* take an unsigned long instead of a uint64_t for now.
|
||||
*/
|
||||
|
|
@ -109,6 +142,19 @@ void lb_memory_range(struct lb_memory *mem,
|
|||
mem->size += sizeof(mem->map[0]);
|
||||
}
|
||||
|
||||
static void lb_memory_rangek(struct lb_memory *mem,
|
||||
uint32_t type, unsigned long startk, unsigned long endk)
|
||||
{
|
||||
int entries;
|
||||
entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
|
||||
mem->map[entries].start = startk;
|
||||
mem->map[entries].start <<= 10;
|
||||
mem->map[entries].size = endk - startk;
|
||||
mem->map[entries].size <<= 10;
|
||||
mem->map[entries].type = type;
|
||||
mem->size += sizeof(mem->map[0]);
|
||||
}
|
||||
|
||||
static void lb_reserve_table_memory(struct lb_header *head)
|
||||
{
|
||||
struct lb_record *last_rec;
|
||||
|
|
@ -173,14 +219,16 @@ struct lb_memory *get_lb_mem(void)
|
|||
|
||||
unsigned long write_linuxbios_table(
|
||||
unsigned long *processor_map,
|
||||
unsigned long totalram,
|
||||
struct mem_range *ram,
|
||||
unsigned long low_table_start, unsigned long low_table_end,
|
||||
unsigned long rom_table_start, unsigned long rom_table_end)
|
||||
unsigned long rom_table_startk, unsigned long rom_table_endk)
|
||||
{
|
||||
unsigned long table_size;
|
||||
struct mem_range *ramp;
|
||||
struct lb_header *head;
|
||||
struct lb_memory *mem;
|
||||
struct lb_record *rec_dest, *rec_src;
|
||||
|
||||
|
||||
head = lb_table_init(low_table_end);
|
||||
low_table_end = (unsigned long)head;
|
||||
#if HAVE_OPTION_TABLE == 1
|
||||
|
|
@ -191,18 +239,40 @@ unsigned long write_linuxbios_table(
|
|||
#endif
|
||||
mem = lb_memory(head);
|
||||
mem_ranges = mem;
|
||||
/* I assume there is always ram at address 0 */
|
||||
/* Reserve our tables in low memory */
|
||||
lb_memory_range(mem, LB_MEM_RESERVED, low_table_start, low_table_end - low_table_start);
|
||||
lb_memory_range(mem, LB_MEM_RAM, low_table_end, 640*1024 - low_table_end);
|
||||
/* Reserve the whole dos BIOS reserved area, we can probably do
|
||||
* better but it isn't too important right now
|
||||
table_size = (low_table_end - low_table_start);
|
||||
lb_memory_range(mem, LB_MEM_TABLE, 0, table_size);
|
||||
lb_memory_range(mem, LB_MEM_RAM, table_size, (ram[0].sizek << 10) - table_size);
|
||||
/* Reserving pci memory mapped space will keep the kernel from booting seeing
|
||||
* any pci resources.
|
||||
*/
|
||||
lb_memory_range(mem, LB_MEM_RESERVED, 0x000a0000, 0x00060000);
|
||||
/* Now show all of memory */
|
||||
lb_memory_range(mem, LB_MEM_RAM, 0x00100000, (totalram - 1024) << 10);
|
||||
for(ramp = &ram[1]; ramp->sizek; ramp++) {
|
||||
unsigned long startk, endk;
|
||||
startk = ramp->basek;
|
||||
endk = startk + ramp->sizek;
|
||||
if ((startk < rom_table_startk) && (endk > rom_table_startk)) {
|
||||
lb_memory_rangek(mem, LB_MEM_RAM, startk, rom_table_startk);
|
||||
startk = rom_table_startk;
|
||||
}
|
||||
if ((startk == rom_table_startk) && (endk > startk)) {
|
||||
unsigned long tend;
|
||||
tend = rom_table_endk;
|
||||
if (tend > endk) {
|
||||
tend = endk;
|
||||
}
|
||||
lb_memory_rangek(mem, LB_MEM_TABLE, rom_table_startk, tend);
|
||||
startk = tend;
|
||||
}
|
||||
if (endk > startk) {
|
||||
lb_memory_rangek(mem, LB_MEM_RAM, startk, endk);
|
||||
}
|
||||
}
|
||||
|
||||
/* Record our motheboard */
|
||||
lb_mainboard(head);
|
||||
/* Record our various random string information */
|
||||
lb_strings(head);
|
||||
|
||||
low_table_end = lb_table_fini(head);
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,6 @@ __main:
|
|||
jmp .Lhlt
|
||||
|
||||
.section ".rom.data"
|
||||
str_after_ram: .string "Ram Initialize?\r\n"
|
||||
str_pre_main: .string "before main\r\n"
|
||||
str_after_ram: .string "Copying LinuxBIOS to ram.\r\n"
|
||||
str_pre_main: .string "Jumping to LinuxBIOS.\r\n"
|
||||
.previous
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef ASM_I386_BOOT_H
|
||||
#define ASM_I386_BOOT_H
|
||||
|
||||
#define UBE32
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_DATA ELFDATA2LSB
|
||||
#define ELF_ARCH EM_386
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#ifndef I386_SUBR_H
|
||||
#define I386_SUBR_H
|
||||
|
||||
void cache_on(unsigned long totalram);
|
||||
struct mem_range;
|
||||
void cache_on(struct mem_range *mem);
|
||||
void interrupts_on(void);
|
||||
|
||||
#endif /* I386_SUBR_H */
|
||||
|
|
|
|||
|
|
@ -2,8 +2,22 @@
|
|||
|
||||
jmp console0
|
||||
|
||||
console_test: .string "\r\n\r\nLinuxBIOS starting...\r\n"
|
||||
#define __STR(X) #X
|
||||
#define STR(X) __STR(X)
|
||||
|
||||
#ifndef LINUXBIOS_EXTRA_VERSION
|
||||
#define LINUXBIOS_EXTRA_VERSION
|
||||
#endif
|
||||
|
||||
console_test:
|
||||
.ascii "\r\n\r\nLinuxBIOS-"
|
||||
.ascii STR(LINUXBIOS_VERSION)
|
||||
.ascii STR(LINUXBIOS_EXTRA_VERSION)
|
||||
.ascii " "
|
||||
.ascii STR(LINUXBIOS_BUILD)
|
||||
.asciz " starting...\r\n"
|
||||
|
||||
#undef STR
|
||||
/* uses: ax, dx */
|
||||
#if defined(SERIAL_CONSOLE)
|
||||
#define __CONSOLE_INLINE_TX_AL TTYS0_TX_AL
|
||||
|
|
@ -229,7 +243,7 @@ console_test: .string "\r\n\r\nLinuxBIOS starting...\r\n"
|
|||
#define CONSOLE_SPEW_TX_STRING(string) __CONSOLE_TX_STRING(string)
|
||||
#define CONSOLE_SPEW_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
|
||||
|
||||
#if ASM_CONSOLE_LOGLEVEL <= BIOS_SPEW
|
||||
#if ASM_CONSOLE_LOGLEVEL <= BIOS_EMERG
|
||||
#undef CONSOLE_EMERG_TX_CHAR
|
||||
#undef CONSOLE_EMERG_INLINE_TX_CHAR
|
||||
#undef CONSOLE_EMERG_TX_HEX8
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ static char rcsid[] = "$Id$";
|
|||
#include <pci.h>
|
||||
#include <subr.h>
|
||||
#include <printk.h>
|
||||
#include <mem.h>
|
||||
#include <version.h>
|
||||
#include <smp/start_stop.h>
|
||||
#include <cpu/l2_cache.h>
|
||||
#include <cpu/cpufixup.h>
|
||||
|
|
@ -76,7 +78,7 @@ static char rcsid[] = "$Id$";
|
|||
*/
|
||||
static unsigned long processor_map[MAX_CPUS];
|
||||
|
||||
static unsigned long cpu_initialize(unsigned long totalram)
|
||||
static unsigned long cpu_initialize(struct mem_range *mem)
|
||||
{
|
||||
/* Because we busy wait at the printk spinlock.
|
||||
* It is important to keep the number of printed messages
|
||||
|
|
@ -87,10 +89,10 @@ static unsigned long cpu_initialize(unsigned long totalram)
|
|||
printk_notice("Initializing CPU #%d\n", processor_id);
|
||||
|
||||
/* some cpus need a fixup done. This is the hook for doing that. */
|
||||
cpufixup(totalram);
|
||||
cpufixup(mem);
|
||||
|
||||
/* Turn on caching if we haven't already */
|
||||
cache_on(totalram);
|
||||
cache_on(mem);
|
||||
|
||||
display_cpuid();
|
||||
mtrr_check();
|
||||
|
|
@ -105,16 +107,18 @@ static unsigned long cpu_initialize(unsigned long totalram)
|
|||
return processor_id;
|
||||
}
|
||||
|
||||
static unsigned long get_ramsize(void)
|
||||
|
||||
static struct mem_range *get_ramsize(void)
|
||||
{
|
||||
unsigned long totalram;
|
||||
totalram = sizeram();
|
||||
// can't size just yet ...
|
||||
// mainboard totalram sizing may not be up yet. If it is not ready,
|
||||
// take a default of 64M
|
||||
if (!totalram)
|
||||
totalram = 64 * 1024;
|
||||
return totalram;
|
||||
static struct mem_range *mem = 0;
|
||||
if (!mem) {
|
||||
mem = sizeram();
|
||||
}
|
||||
if (!mem) {
|
||||
printk_err("No memory size information!\n");
|
||||
for(;;);
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
|
||||
#ifdef SMP
|
||||
|
|
@ -123,14 +127,14 @@ static atomic_t active_cpus = ATOMIC_INIT(1);
|
|||
|
||||
void secondary_cpu_init(void)
|
||||
{
|
||||
unsigned long totalram;
|
||||
struct mem_range *mem;
|
||||
unsigned long id;
|
||||
int index;
|
||||
|
||||
atomic_inc(&active_cpus);
|
||||
printk_debug(__FUNCTION__ "\n");
|
||||
totalram = get_ramsize();
|
||||
id = cpu_initialize(totalram);
|
||||
mem = get_ramsize();
|
||||
id = cpu_initialize(mem);
|
||||
index = processor_index(id);
|
||||
printk_debug(__FUNCTION__ " %d/%u\n", index, id);
|
||||
processor_map[index] = CPU_ENABLED;
|
||||
|
|
@ -153,7 +157,7 @@ static void wait_for_other_cpus(void)
|
|||
}
|
||||
active_count = atomic_read(&active_cpus);
|
||||
}
|
||||
for (i = 0; i < MAX_CPUS; i++) {
|
||||
for(i = 0; i < MAX_CPUS; i++) {
|
||||
if (!(processor_map[i] & CPU_ENABLED)) {
|
||||
printk_err("CPU %d/%u did not initialize!\n",
|
||||
i, initial_apicid[i]);
|
||||
|
|
@ -185,7 +189,7 @@ static void remove_logical_cpus(void)
|
|||
#endif /* SMP */
|
||||
|
||||
|
||||
void write_tables(unsigned long totalram)
|
||||
void write_tables(struct mem_range *mem)
|
||||
{
|
||||
unsigned long low_table_start, low_table_end;
|
||||
unsigned long rom_table_start, rom_table_end;
|
||||
|
|
@ -193,7 +197,7 @@ void write_tables(unsigned long totalram)
|
|||
rom_table_start = 0xf0000;
|
||||
rom_table_end = 0xf0000;
|
||||
/* Start low addr at 16 bytes instead of 0 because of a buglet
|
||||
* in the generic linux bunzip code, as it tests for the a20 line.
|
||||
* in the generic linux unzip code, as it tests for the a20 line.
|
||||
*/
|
||||
low_table_start = 0;
|
||||
low_table_end = 16;
|
||||
|
|
@ -202,6 +206,7 @@ void write_tables(unsigned long totalram)
|
|||
check_pirq_routing_table();
|
||||
/* This table must be betweeen 0xf0000 & 0x100000 */
|
||||
rom_table_end = copy_pirq_routing_table(rom_table_end);
|
||||
rom_table_end = (rom_table_end + 1023) & ~1023;
|
||||
|
||||
/* copy the smp block to address 0 */
|
||||
post_code(0x96);
|
||||
|
|
@ -214,9 +219,9 @@ void write_tables(unsigned long totalram)
|
|||
low_table_end = 0x500;
|
||||
}
|
||||
/* The linuxbios table must be in 0-4K or 960K-1M */
|
||||
write_linuxbios_table(processor_map, totalram,
|
||||
write_linuxbios_table(processor_map, mem,
|
||||
low_table_start, low_table_end,
|
||||
rom_table_start, rom_table_end);
|
||||
rom_table_start >> 10, rom_table_end >> 10);
|
||||
}
|
||||
|
||||
void hardwaremain(int boot_complete)
|
||||
|
|
@ -244,8 +249,9 @@ void hardwaremain(int boot_complete)
|
|||
* things, so that the other work can use the PciRead* and PciWrite*
|
||||
* functions.
|
||||
*/
|
||||
unsigned long totalram = 0;
|
||||
extern void linuxbiosmain(unsigned long membase, unsigned long totalram);
|
||||
struct mem_range *mem, *tmem;
|
||||
unsigned long totalmem;
|
||||
extern void linuxbiosmain(struct mem_range *mem);
|
||||
|
||||
// we don't call post code for this one -- since serial post could cause real
|
||||
// trouble.
|
||||
|
|
@ -254,8 +260,9 @@ void hardwaremain(int boot_complete)
|
|||
displayinit();
|
||||
|
||||
post_code(0x39);
|
||||
|
||||
printk_notice("LinuxBIOS %s...\n", (boot_complete) ? "rebooting" : "booting");
|
||||
printk_notice("LinuxBIOS-%s%s %s %s...\n",
|
||||
linuxbios_version, linuxbios_extra_version, linuxbios_build,
|
||||
(boot_complete)?"rebooting":"booting");
|
||||
|
||||
post_code(0x40);
|
||||
|
||||
|
|
@ -278,12 +285,17 @@ void hardwaremain(int boot_complete)
|
|||
// So you really need to run this before you size ram.
|
||||
framebuffer_on();
|
||||
|
||||
totalram = get_ramsize();
|
||||
mem = get_ramsize();
|
||||
post_code(0x70);
|
||||
printk_info("totalram: %ldM\n", totalram/1024);
|
||||
totalmem = 0;
|
||||
for(tmem = mem; tmem->sizek; tmem++) {
|
||||
totalmem += tmem->sizek;
|
||||
}
|
||||
printk_info("totalram: %ldM\n",
|
||||
(totalmem + 512) >> 10); /* Round to the nearest meg */
|
||||
|
||||
/* Fully initialize the cpu before configuring the bus */
|
||||
boot_cpu = cpu_initialize(totalram);
|
||||
boot_cpu = cpu_initialize(mem);
|
||||
boot_index = processor_index(boot_cpu);
|
||||
printk_spew("BOOT CPU is %d\n", boot_cpu);
|
||||
processor_map[boot_index] = CPU_BOOTPROCESSOR|CPU_ENABLED;
|
||||
|
|
@ -378,14 +390,14 @@ void hardwaremain(int boot_complete)
|
|||
/* Now that we have collected all of our information
|
||||
* write our configuration tables.
|
||||
*/
|
||||
write_tables(totalram);
|
||||
write_tables(mem);
|
||||
|
||||
|
||||
#ifdef LINUXBIOS
|
||||
printk_info("Jumping to linuxbiosmain()...\n");
|
||||
// we could go to argc, argv, for main but it seems like overkill.
|
||||
post_code(0xed);
|
||||
linuxbiosmain(0, totalram);
|
||||
linuxbiosmain(mem);
|
||||
#endif /* LINUXBIOS */
|
||||
}
|
||||
|
||||
|
|
@ -393,6 +405,3 @@ void hardwaremain(int boot_complete)
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include <mem.h>
|
||||
#include <cpu/p5/io.h>
|
||||
#include <cpu/p5/macros.h>
|
||||
#include <cpu/p6/msr.h>
|
||||
|
|
@ -13,7 +14,7 @@
|
|||
#define APIC 1
|
||||
#endif
|
||||
|
||||
void cache_on(unsigned long totalram)
|
||||
void cache_on(struct mem_range *mem)
|
||||
{
|
||||
post_code(0x60);
|
||||
printk_info("Enabling cache...");
|
||||
|
|
@ -32,7 +33,7 @@ void cache_on(unsigned long totalram)
|
|||
#if defined(i686)
|
||||
// totalram here is in linux sizing, i.e. units of KB.
|
||||
// set_mtrr is responsible for getting it into the right units!
|
||||
setup_mtrrs(totalram);
|
||||
setup_mtrrs(mem);
|
||||
#endif
|
||||
|
||||
post_code(0x6A);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
## This is Architecture independant part of the makefile
|
||||
|
||||
option LINUXBIOS_VERSION=1.0.0
|
||||
|
||||
option CROSS_COMPILE=
|
||||
|
||||
makedefine CC:=$(CROSS_COMPILE)gcc
|
||||
|
|
@ -14,6 +16,15 @@ makedefine CFLAGS := $(CPU_OPT) $(CPPFLAGS) -Os -nostdinc -nostdlib -fno-builtin
|
|||
makedefine HOSTCC:=gcc
|
||||
makedefine HOSTCFLAGS:= -Os -Wall
|
||||
|
||||
option LINUXBIOS_BUILD = $(shell date)
|
||||
option LINUXBIOS_COMPILE_TIME = $(shell date +%T)
|
||||
option LINUXBIOS_COMPILE_BY = $(shell whoami)
|
||||
option LINUXBIOS_COMPILE_HOST = $(shell hostname)
|
||||
option LINUXBIOS_COMPILE_DOMAIN = $(shell dnsdomainname)
|
||||
option LINUXBIOS_COMPILER = $(shell $(CC) $(CFLAGS) -v 2>&1 | tail -1)
|
||||
option LINUXBIOS_LINKER = $(shell $(CC) -Wl,-v 2>&1 | grep version | tail -1)
|
||||
option LINUXBIOS_ASSEMBLER = $(shell touch dummy.s ; $(CC) -c -Wa,-v dummy.s 2>&1; rm -f dummy.s dummy.o )
|
||||
|
||||
makerule ldscript.ld : ldoptions $(LDSUBSCRIPTS-1) ; echo "INCLUDE ldoptions" > $@ ; for file in $(LDSUBSCRIPTS-1) ; do echo "INCLUDE $$file" >> $@ ; done
|
||||
|
||||
makerule cpuflags : Makefile.settings ; perl -e 'print "CPUFLAGS :=\n"; foreach $$var (split(" ", $$ENV{VARIABLES})) { if (exists($$ENV{$$var})) { print "CPUFLAGS += -D$$var" . (length($$ENV{$$var})?"=\x27$$ENV{$$var}\x27":"") ."\n"} else { print "CPUFLAGS += -U$$var\n"} }' > $@
|
||||
|
|
@ -34,6 +45,8 @@ addaction linuxbios.a ar cr linuxbios.a $(OBJECTS-1)
|
|||
option CRT0=$(TOP)/src/arch/$(ARCH)/config/crt0.base
|
||||
makerule crt0.S: $(CRT0) ; cp $< $@
|
||||
|
||||
# Force crt0.s (which has build time version code in it to rebuild every time)
|
||||
makedefine .PHONY : crt0.s
|
||||
makerule crt0.s: crt0.S crt0_includes.h $(CRT0_INCLUDES); @echo "$(CPP) ... $< > $@ "
|
||||
addaction crt0.s @$(CPP) $(CPPFLAGS) -I$(TOP)/src $< > $@.new && mv $@.new $@
|
||||
|
||||
|
|
|
|||
23
src/cpu/i786/disable_sse.inc
Normal file
23
src/cpu/i786/disable_sse.inc
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Put the processor back into a reset state
|
||||
* with respect to the xmm registers.
|
||||
*/
|
||||
|
||||
pxor %xmm0, %xmm0
|
||||
pxor %xmm1, %xmm1
|
||||
pxor %xmm2, %xmm2
|
||||
pxor %xmm3, %xmm3
|
||||
pxor %xmm4, %xmm4
|
||||
pxor %xmm5, %xmm5
|
||||
pxor %xmm6, %xmm6
|
||||
pxor %xmm7, %xmm7
|
||||
|
||||
/* Disable floating point emulation */
|
||||
movl %cr0, %eax
|
||||
andl $~(1<<2), %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Disable sse instructions */
|
||||
movl %cr4, %eax
|
||||
andl $~(3<<9), %eax
|
||||
movl %eax, %cr4
|
||||
13
src/cpu/i786/enable_sse.inc
Normal file
13
src/cpu/i786/enable_sse.inc
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Enable the use of the xmm registers
|
||||
*/
|
||||
|
||||
/* Disable floating point emulation */
|
||||
movl %cr0, %eax
|
||||
andl $~(1<<2), %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Enable sse instructions */
|
||||
movl %cr4, %eax
|
||||
orl $(1<<9), %eax
|
||||
movl %eax, %cr4
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
option i586=1
|
||||
object cpuid.o
|
||||
object delay_tsc.o
|
||||
#object tsc.o
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ static void display_cpuid_update_microcode(void)
|
|||
}
|
||||
}
|
||||
|
||||
void p6_cpufixup(unsigned long totalram)
|
||||
void p6_cpufixup(struct mem_range *mem)
|
||||
{
|
||||
printk_info("Updating microcode\n");
|
||||
display_cpuid_update_microcode();
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
static char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <mem.h>
|
||||
#include <cpu/p6/msr.h>
|
||||
#include <cpu/p6/mtrr.h>
|
||||
#include <cpu/k7/mtrr.h>
|
||||
|
|
@ -43,120 +44,6 @@ static unsigned int mtrr_msr[] = {
|
|||
MTRRfix4K_E0000_MSR, MTRRfix4K_E8000_MSR, MTRRfix4K_F0000_MSR, MTRRfix4K_F8000_MSR,
|
||||
};
|
||||
|
||||
#ifndef HAVE_MTRR_TABLE
|
||||
|
||||
/* We want to cache memory as efficiently as possible.
|
||||
*/
|
||||
#define MTRR_TYPE_RAM MTRR_TYPE_WRBACK
|
||||
/* We can't use Write Combining on a legacy frame buffer because
|
||||
* it is incompatible with EGA 16 color video modes...
|
||||
*/
|
||||
#define MTRR_TYPE_FB MTRR_TYPE_UNCACHABLE
|
||||
/* For areas that are supposed to cover roms it makes no
|
||||
* sense to cache writes.
|
||||
*/
|
||||
#define MTRR_TYPE_ROM MTRR_TYPE_WRPROT
|
||||
|
||||
|
||||
#ifdef MEMORY_HOLE
|
||||
#define RAM MTRR_TYPE_RAM
|
||||
#define FB MTRR_TYPE_FB
|
||||
#define ROM MTRR_TYPE_ROM
|
||||
#else
|
||||
#define RAM MTRR_TYPE_RAM
|
||||
#define FB MTRR_TYPE_RAM
|
||||
#define ROM MTRR_TYPE_RAM
|
||||
#endif /* MEMORY_HOLE */
|
||||
|
||||
#ifdef MTRR_ONLY_TOP_64K_FLASH
|
||||
|
||||
// This is for boards that only support flash in low memory at 0xf0000
|
||||
// and above, such as the technoland sbc 710. This type of board
|
||||
// is so common that we put it here instead of in the sbc710 mainboard.c
|
||||
|
||||
static unsigned char fixed_mtrr_values[][4] = {
|
||||
/* MTRRfix64K_00000_MSR, defines memory range from 0KB to 512 KB, each byte cover 64KB area */
|
||||
{RAM, RAM, RAM, RAM}, {RAM, RAM, RAM, RAM},
|
||||
|
||||
/* MTRRfix16K_80000_MSR, defines memory range from 512KB to 640KB, each byte cover 16KB area */
|
||||
{RAM, RAM, RAM, RAM}, {RAM, RAM, RAM, RAM},
|
||||
|
||||
/* MTRRfix16K_A0000_MSR, defines memory range from A0000 to C0000, each byte cover 16KB area */
|
||||
{FB, FB, FB, FB}, {FB, FB, FB, FB},
|
||||
|
||||
/* MTRRfix4K_C0000_MSR, defines memory range from C0000 to C8000, each byte cover 4KB area */
|
||||
{FB, FB, FB, FB}, {FB, FB, FB, FB},
|
||||
|
||||
/* MTRRfix4K_C8000_MSR, defines memory range from C8000 to D0000, each byte cover 4KB area */
|
||||
{FB, FB, FB, FB}, {FB, FB, FB, FB},
|
||||
|
||||
/* MTRRfix4K_D0000_MSR, defines memory range from D0000 to D8000, each byte cover 4KB area */
|
||||
{FB, FB, FB, FB}, {FB, FB, FB, FB},
|
||||
|
||||
/* MTRRfix4K_D8000_MSR, defines memory range from D8000 to E0000, each byte cover 4KB area */
|
||||
{FB, FB, FB, FB}, {FB, FB, FB, FB},
|
||||
|
||||
/* MTRRfix4K_E0000_MSR, defines memory range from E0000 to E8000, each byte cover 4KB area */
|
||||
{FB, FB, FB, FB}, {FB, FB, FB, FB},
|
||||
|
||||
/* MTRRfix4K_E8000_MSR, defines memory range from E8000 to F0000, each byte cover 4KB area */
|
||||
{FB, FB, FB, FB}, {FB, FB, FB, FB},
|
||||
|
||||
/* MTRRfix4K_F0000_MSR, defines memory range from F0000 to F8000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
|
||||
/* MTRRfix4K_F8000_MSR, defines memory range from F8000 to 100000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
};
|
||||
#else
|
||||
|
||||
static unsigned char fixed_mtrr_values[][4] = {
|
||||
/* MTRRfix64K_00000_MSR, defines memory range from 0KB to 512 KB, each byte cover 64KB area */
|
||||
{RAM, RAM, RAM, RAM}, {RAM, RAM, RAM, RAM},
|
||||
|
||||
/* MTRRfix16K_80000_MSR, defines memory range from 512KB to 640KB, each byte cover 16KB area */
|
||||
{RAM, RAM, RAM, RAM}, {RAM, RAM, RAM, RAM},
|
||||
|
||||
/* MTRRfix16K_A0000_MSR, defines memory range from A0000 to C0000, each byte cover 16KB area */
|
||||
{FB, FB, FB, FB}, {FB, FB, FB, FB},
|
||||
|
||||
/* MTRRfix4K_C0000_MSR, defines memory range from C0000 to C8000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
|
||||
/* MTRRfix4K_C8000_MSR, defines memory range from C8000 to D0000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
|
||||
/* MTRRfix4K_D0000_MSR, defines memory range from D0000 to D8000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
|
||||
/* MTRRfix4K_D8000_MSR, defines memory range from D8000 to E0000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
|
||||
/* MTRRfix4K_E0000_MSR, defines memory range from E0000 to E8000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
|
||||
/* MTRRfix4K_E8000_MSR, defines memory range from E8000 to F0000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
|
||||
/* MTRRfix4K_F0000_MSR, defines memory range from F0000 to F8000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
|
||||
/* MTRRfix4K_F8000_MSR, defines memory range from F8000 to 100000, each byte cover 4KB area */
|
||||
{ROM, ROM, ROM, ROM}, {ROM, ROM, ROM, ROM},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#undef FB
|
||||
#undef RAM
|
||||
#undef ROM
|
||||
#undef MTRR_TYPE_RAM
|
||||
#undef MTRR_TYPE_FB
|
||||
#undef MTRR_TYPE_ROM
|
||||
|
||||
#else
|
||||
extern unsigned char fixed_mtrr_values[][4];
|
||||
#endif
|
||||
|
||||
static void intel_enable_fixed_mtrr(void)
|
||||
{
|
||||
|
|
@ -176,24 +63,25 @@ static void intel_enable_var_mtrr(void)
|
|||
wrmsr(MTRRdefType_MSR, low, high);
|
||||
}
|
||||
|
||||
/* setting fixed mtrr, you can do some experiments with different memory type
|
||||
defined in the table "fixed_mtrr_values" */
|
||||
static void intel_set_fixed_mtrr(void)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned long low, high;
|
||||
|
||||
for (i = 0; i < arraysize(mtrr_msr); i++) {
|
||||
low = *(unsigned long *) fixed_mtrr_values[i*2];
|
||||
high = *(unsigned long *) fixed_mtrr_values[i*2+1];
|
||||
wrmsr(mtrr_msr[i], low, high);
|
||||
}
|
||||
}
|
||||
|
||||
/* setting variable mtrr, comes from linux kernel source */
|
||||
static void intel_set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type)
|
||||
static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type)
|
||||
{
|
||||
unsigned int tmp;
|
||||
unsigned long base_high, base_low;
|
||||
unsigned long mask_high, mask_low;
|
||||
|
||||
base_high = basek >> 22;
|
||||
base_low = basek << 10;
|
||||
|
||||
if (sizek < 4*1024*1024) {
|
||||
mask_high = 0x0F;
|
||||
mask_low = ~((sizek << 10) -1);
|
||||
}
|
||||
else {
|
||||
mask_high = 0x0F & (~((sizek >> 22) -1));
|
||||
mask_low = 0;
|
||||
}
|
||||
|
||||
if (reg >= 8)
|
||||
return;
|
||||
|
|
@ -208,14 +96,14 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long base, unsigned lo
|
|||
"movl %0, %%cr0\n\t"
|
||||
"wbinvd\n\t":"=r" (tmp)::"memory");
|
||||
|
||||
if (size == 0) {
|
||||
if (sizek == 0) {
|
||||
/* The invalid bit is kept in the mask, so we simply clear the
|
||||
relevant mask register to disable a range. */
|
||||
wrmsr (MTRRphysMask_MSR (reg), 0, 0);
|
||||
} else {
|
||||
/* Bit 32-35 of MTRRphysMask should be set to 1 */
|
||||
wrmsr (MTRRphysBase_MSR (reg), base | type, 0);
|
||||
wrmsr (MTRRphysMask_MSR (reg), ~(size - 1) | 0x800, 0x0F);
|
||||
wrmsr (MTRRphysBase_MSR(reg), base_low | type, base_high);
|
||||
wrmsr (MTRRphysMask_MSR(reg), mask_low | 0x800, mask_high);
|
||||
}
|
||||
|
||||
// turn cache back on.
|
||||
|
|
@ -262,7 +150,7 @@ void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsi
|
|||
}
|
||||
|
||||
/* fms: find most sigificant bit set, stolen from Linux Kernel Source. */
|
||||
static __inline__ unsigned int fms(unsigned int x)
|
||||
static inline unsigned int fms(unsigned int x)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
|
@ -273,6 +161,18 @@ static __inline__ unsigned int fms(unsigned int x)
|
|||
return r;
|
||||
}
|
||||
|
||||
/* fms: find least sigificant bit set */
|
||||
static inline unsigned int fls(unsigned int x)
|
||||
{
|
||||
int r;
|
||||
|
||||
__asm__("bsfl %1,%0\n\t"
|
||||
"jnz 1f\n\t"
|
||||
"movl $32,%0\n"
|
||||
"1:" : "=r" (r) : "g" (x));
|
||||
return r;
|
||||
}
|
||||
|
||||
/* setting up variable and fixed mtrr
|
||||
*
|
||||
* From Intel Vol. III Section 9.12.4, the Range Size and Base Alignment has some kind of requirement:
|
||||
|
|
@ -299,81 +199,152 @@ static __inline__ unsigned int fms(unsigned int x)
|
|||
#define OS_MTRRS 2
|
||||
#define MTRRS (BIOS_MTRRS + OS_MTRRS)
|
||||
|
||||
void setup_mtrrs(unsigned long ramsizeK)
|
||||
|
||||
static void set_fixed_mtrrs(unsigned int first, unsigned int last, unsigned char type)
|
||||
{
|
||||
unsigned int reg = 0;
|
||||
unsigned long range_wb, range_uc;
|
||||
unsigned long rambase;
|
||||
unsigned long romendK;
|
||||
|
||||
printk_debug("\n");
|
||||
rambase = 0;
|
||||
|
||||
while (ramsizeK != 0 && reg < BIOS_MTRRS) {
|
||||
post_code(0x60 + reg);
|
||||
|
||||
range_wb = 1 << (fms(ramsizeK - 1) + 1);
|
||||
range_uc = range_wb - ramsizeK;
|
||||
|
||||
if ((range_uc == 0) || ((ramsizeK % range_uc) == 0)) {
|
||||
printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type: WB\n",
|
||||
reg, rambase >> 10, range_wb >> 10);
|
||||
intel_set_var_mtrr(reg++, rambase * 1024, range_wb * 1024,
|
||||
MTRR_TYPE_WRBACK);
|
||||
rambase += ramsizeK;
|
||||
|
||||
if (range_uc) {
|
||||
printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type: UC\n",
|
||||
reg, rambase >> 10, range_uc >> 10);
|
||||
intel_set_var_mtrr(reg++, rambase * 1024, range_uc * 1024,
|
||||
MTRR_TYPE_UNCACHABLE);
|
||||
unsigned int i;
|
||||
unsigned int fixed_msr = NUM_FIXED_RANGES >> 3;
|
||||
unsigned long low, high;
|
||||
low = high = 0; /* Shut up gcc */
|
||||
for(i = first; i < last; i++) {
|
||||
/* When I switch to a new msr read it in */
|
||||
if (fixed_msr != i >> 3) {
|
||||
/* But first write out the old msr */
|
||||
if (fixed_msr < (NUM_FIXED_RANGES >> 3)) {
|
||||
wrmsr(mtrr_msr[fixed_msr], low, high);
|
||||
}
|
||||
ramsizeK = 0; /* effectivly a break */
|
||||
fixed_msr = i>>3;
|
||||
rdmsr(mtrr_msr[fixed_msr], low, high);
|
||||
}
|
||||
if ((i & 7) < 4) {
|
||||
low &= ~(0xff << ((i&3)*8));
|
||||
low |= type << ((i&3)*8);
|
||||
} else {
|
||||
range_wb >>= 1;
|
||||
|
||||
printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type: WB\n",
|
||||
reg, rambase >> 10, range_wb >> 10);
|
||||
intel_set_var_mtrr(reg++, rambase * 1024, range_wb * 1024,
|
||||
MTRR_TYPE_WRBACK);
|
||||
|
||||
rambase += range_wb;
|
||||
ramsizeK -= range_wb;
|
||||
high &= ~(0xff << ((i&3)*8));
|
||||
high |= type << ((i&3)*8);
|
||||
}
|
||||
}
|
||||
printk_debug("DONE variable MTRRs\n");
|
||||
#if defined(XIP_ROM_SIZE) && defined(XIP_ROM_BASE)
|
||||
#if XIP_ROM_SIZE < 4096
|
||||
#error XIP_ROM_SIZE must be at least 4K
|
||||
#endif
|
||||
#if XIP_ROM_SIZE & (XIP_ROM_SIZE -1)
|
||||
#error XIP_ROM_SIZE must be a power of two
|
||||
#endif
|
||||
#if XIP_ROM_BASE & (XIP_ROM_SIZE -1)
|
||||
#error XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
|
||||
#endif
|
||||
/* I assume that XIP_ROM_SIZE is a power of two
|
||||
* and that XIP_ROM_BASE is power of tow aligned.
|
||||
*/
|
||||
romendK = (XIP_ROM_BASE + XIP_ROM_SIZE) >>10;
|
||||
if ((reg < BIOS_MTRRS) &&
|
||||
((XIP_ROM_BASE > rambase) || (romendK > rambase))) {
|
||||
intel_set_var_mtrr(reg++, XIP_ROM_BASE, XIP_ROM_SIZE,
|
||||
MTRR_TYPE_WRPROT);
|
||||
/* Write out the final msr */
|
||||
if (fixed_msr < (NUM_FIXED_RANGES >> 3)) {
|
||||
wrmsr(mtrr_msr[fixed_msr], low, high);
|
||||
}
|
||||
#endif /* XIP_ROM_SIZE && XIP_ROM_BASE */
|
||||
}
|
||||
|
||||
static unsigned fixed_mtrr_index(unsigned long addrk)
|
||||
{
|
||||
unsigned index;
|
||||
index = (addrk - 0) >> 6;
|
||||
if (index >= 8) {
|
||||
index = ((addrk - 8*64) >> 4) + 8;
|
||||
}
|
||||
if (index >= 24) {
|
||||
index = ((addrk - (8*64 + 16*16)) >> 2) + 24;
|
||||
}
|
||||
if (index > NUM_FIXED_RANGES) {
|
||||
index = NUM_FIXED_RANGES;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
static unsigned int range_to_mtrr(unsigned int reg,
|
||||
unsigned long range_startk, unsigned long range_sizek)
|
||||
{
|
||||
if (!range_sizek || (reg >= BIOS_MTRRS)) {
|
||||
return reg;
|
||||
}
|
||||
while(range_sizek) {
|
||||
unsigned long max_align, align;
|
||||
unsigned long sizek;
|
||||
/* Compute the maximum size I can make a range */
|
||||
max_align = fls(range_startk);
|
||||
align = fms(range_sizek);
|
||||
if (align > max_align) {
|
||||
align = max_align;
|
||||
}
|
||||
sizek = 1 << align;
|
||||
printk_debug("Setting variable MTRR %d, base: %4dMB, range: %4dMB, type WB\n",
|
||||
reg, range_startk >>10, sizek >> 10);
|
||||
intel_set_var_mtrr(reg++, range_startk, sizek, MTRR_TYPE_WRBACK);
|
||||
range_startk += sizek;
|
||||
range_sizek -= sizek;
|
||||
if (reg >= BIOS_MTRRS)
|
||||
break;
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
void setup_mtrrs(struct mem_range *mem)
|
||||
{
|
||||
/* Try this the simple way of incrementally adding together
|
||||
* mtrrs. If this doesn't work out we can get smart again
|
||||
* and clear out the mtrrs.
|
||||
*/
|
||||
struct mem_range *memp;
|
||||
unsigned long range_startk, range_sizek;
|
||||
unsigned int reg;
|
||||
|
||||
printk_debug("\n");
|
||||
/* Initialized the fixed_mtrrs to uncached */
|
||||
printk_debug("Setting fixed MTRRs(%d-%d) type: UC\n",
|
||||
0, NUM_FIXED_RANGES);
|
||||
set_fixed_mtrrs(0, NUM_FIXED_RANGES, MTRR_TYPE_UNCACHABLE);
|
||||
|
||||
/* Now see which of the fixed mtrrs cover ram.
|
||||
*/
|
||||
for(memp = mem; memp->sizek; memp++) {
|
||||
unsigned int start_mtrr;
|
||||
unsigned int last_mtrr;
|
||||
start_mtrr = fixed_mtrr_index(memp->basek);
|
||||
last_mtrr = fixed_mtrr_index(memp->basek + memp->sizek);
|
||||
if (start_mtrr >= NUM_FIXED_RANGES) {
|
||||
break;
|
||||
}
|
||||
printk_debug("Setting fixed MTRRs(%d-%d) type: WB\n",
|
||||
start_mtrr, last_mtrr);
|
||||
set_fixed_mtrrs(start_mtrr, last_mtrr, MTRR_TYPE_WRBACK);
|
||||
}
|
||||
printk_debug("DONE fixed MTRRs\n");
|
||||
/* Cache as many memory areas as possible */
|
||||
/* FIXME is there an algorithm for computing the optimal set of mtrrs?
|
||||
* In some cases it is definitely possible to do better.
|
||||
*/
|
||||
range_startk = 0;
|
||||
range_sizek = 0;
|
||||
reg = 0;
|
||||
for (memp = mem; memp->sizek; memp++) {
|
||||
/* See if I can merge with the last range
|
||||
* Either I am below 1M and the fixed mtrrs handle it, or
|
||||
* the ranges touch.
|
||||
*/
|
||||
if ((memp->basek <= 1024) || (range_startk + range_sizek == memp->basek)) {
|
||||
unsigned long endk = memp->basek + memp->sizek;
|
||||
range_sizek = endk - range_startk;
|
||||
continue;
|
||||
}
|
||||
/* Write the range mtrrs */
|
||||
if (range_sizek != 0) {
|
||||
reg = range_to_mtrr(reg, range_startk, range_sizek);
|
||||
range_startk = 0;
|
||||
range_sizek = 0;
|
||||
if (reg >= BIOS_MTRRS)
|
||||
break;
|
||||
}
|
||||
/* Allocate an msr */
|
||||
range_startk = memp->basek;
|
||||
range_sizek = memp->sizek;
|
||||
}
|
||||
/* Write the last range */
|
||||
reg = range_to_mtrr(reg, range_startk, range_sizek);
|
||||
printk_debug("DONE variable MTRRs\n");
|
||||
printk_debug("Clear out the extra MTRR's\n");
|
||||
/* Clear out the extra MTRR's */
|
||||
while(reg < MTRRS) {
|
||||
intel_set_var_mtrr(reg++, 0, 0, 0);
|
||||
}
|
||||
printk_debug("call intel_set_fixed_mtrr()\n");
|
||||
intel_set_fixed_mtrr();
|
||||
|
||||
/* enable fixed MTRR */
|
||||
printk_debug("call intel_enable_fixed_mtrr()\n");
|
||||
intel_enable_fixed_mtrr();
|
||||
printk_debug("call intel_enable_var_mtrr()\n");
|
||||
intel_enable_var_mtrr();
|
||||
printk_debug("Leave " __FUNCTION__ "\n");
|
||||
printk_debug("Leave %s\n", __FUNCTION__);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
#include <boot/linuxbios_tables.h>
|
||||
|
||||
struct mem_range;
|
||||
|
||||
/* This file holds function prototypes for building the linuxbios table. */
|
||||
unsigned long write_linuxbios_table(
|
||||
unsigned long *processor_map,
|
||||
unsigned long totalram,
|
||||
struct mem_range *ram,
|
||||
unsigned long low_table_start, unsigned long low_table_end,
|
||||
unsigned long rom_table_start, unsigned long rom_table_end);
|
||||
|
||||
|
|
@ -17,7 +19,7 @@ struct lb_record *lb_next_record(struct lb_record *rec);
|
|||
struct lb_record *lb_new_record(struct lb_header *header);
|
||||
struct lb_memory *lb_memory(struct lb_header *header);
|
||||
void lb_memory_range(struct lb_memory *mem,
|
||||
uint32_t type, unsigned long start, unsigned long size);
|
||||
uint32_t type, unsigned long startk, unsigned long sizek);
|
||||
struct lb_mainboard *lb_mainboard(struct lb_header *header);
|
||||
unsigned long lb_table_fini(struct lb_header *header);
|
||||
|
||||
|
|
|
|||
|
|
@ -61,8 +61,9 @@ struct lb_memory_range {
|
|||
uint64_t start;
|
||||
uint64_t size;
|
||||
uint32_t type;
|
||||
#define LB_MEM_RAM 1
|
||||
#define LB_MEM_RESERVED 2
|
||||
#define LB_MEM_RAM 1 /* Memory anyone can use */
|
||||
#define LB_MEM_RESERVED 2 /* Don't use this memory region */
|
||||
#define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -88,7 +89,21 @@ struct lb_mainboard {
|
|||
uint8_t strings[0];
|
||||
};
|
||||
|
||||
|
||||
#define LB_TAG_VERSION 0x0004
|
||||
#define LB_TAG_EXTRA_VERSION 0x0005
|
||||
#define LB_TAG_BUILD 0x0006
|
||||
#define LB_TAG_COMPILE_TIME 0x0007
|
||||
#define LB_TAG_COMPILE_BY 0x0008
|
||||
#define LB_TAG_COMPILE_HOST 0x0009
|
||||
#define LB_TAG_COMPILE_DOMAIN 0x000a
|
||||
#define LB_TAG_COMPILER 0x000b
|
||||
#define LB_TAG_LINKER 0x000c
|
||||
#define LB_TAG_ASSEMBLER 0x000d
|
||||
struct lb_string {
|
||||
uint32_t tag;
|
||||
uint32_t size;
|
||||
uint8_t string[0];
|
||||
};
|
||||
|
||||
/* The following structures are for the cmos definitions table */
|
||||
#define LB_TAG_CMOS_OPTION_TABLE 200
|
||||
|
|
|
|||
|
|
@ -1,19 +1,21 @@
|
|||
#ifndef CPU_CPUFIXUP_H
|
||||
#define CPU_CPUFIXUP_H
|
||||
|
||||
struct mem_range;
|
||||
|
||||
#include <cpu/k7/cpufixup.h>
|
||||
#include <cpu/p6/cpufixup.h>
|
||||
|
||||
#ifdef CPU_FIXUP
|
||||
# if defined(k7)
|
||||
# define cpufixup(totalram) k7_cpufixup(totalram)
|
||||
# define cpufixup(mem) k7_cpufixup(mem)
|
||||
# elif defined(i786)
|
||||
# define cpufixup(totalram) p6_cpufixup(totalram)
|
||||
# define cpufixup(mem) p6_cpufixup(mem)
|
||||
# elif defined(i686)
|
||||
# define cpufixup(totalram) p6_cpufixup(totalram)
|
||||
# define cpufixup(mem) p6_cpufixup(mem)
|
||||
# endif
|
||||
#else
|
||||
# define cpufixup(totalram) do {} while(0)
|
||||
# define cpufixup(mem) do {} while(0)
|
||||
#endif
|
||||
|
||||
#endif /* CPU_CPUFIXUP_H */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef CPU_K7_CPUFIXUP_H
|
||||
#define CPU_K7_CPUFIXUP_H
|
||||
|
||||
void k7_cpufixup(unsigned long totalram);
|
||||
void k7_cpufixup(struct mem_range *mem);
|
||||
|
||||
#endif /* CPU_K7_CPUFIXUP_H */
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@
|
|||
#define CPU_FIXUP
|
||||
#endif
|
||||
|
||||
void p6_cpufixup(unsigned long totalram);
|
||||
void p6_cpufixup(struct mem_range *mem);
|
||||
|
||||
#endif /* CPU_P6_CPUFIXUP_H */
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@
|
|||
|
||||
void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type);
|
||||
#if defined(INTEL_PPRO_MTRR)
|
||||
void setup_mtrrs(unsigned long ramsizeK);
|
||||
struct mem_range;
|
||||
void setup_mtrrs(struct mem_range *mem);
|
||||
#endif
|
||||
|
||||
#endif /* ASSEMBLY */
|
||||
|
|
|
|||
11
src/include/mem.h
Normal file
11
src/include/mem.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef MEM_H
|
||||
#define MEM_H
|
||||
|
||||
struct mem_range {
|
||||
unsigned long basek;
|
||||
unsigned long sizek;
|
||||
};
|
||||
|
||||
/* mem_range arrays are non-overlapping, in ascending order and null terminated */
|
||||
|
||||
#endif /* MEM_H */
|
||||
6
src/include/northbridge/amd/amd76x.h
Normal file
6
src/include/northbridge/amd/amd76x.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef AMD76X_H
|
||||
#define AMD76X_H
|
||||
|
||||
void amd76x_setup_pci_arbiter(void);
|
||||
|
||||
#endif /* AMD76X_H */
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef PART_SIZERAM_H
|
||||
#define PART_SIZERAM_H
|
||||
|
||||
unsigned long sizeram(void);
|
||||
struct mem_rang;
|
||||
struct mem_range *sizeram(void);
|
||||
|
||||
#endif /* PART_SIZERAM_H */
|
||||
|
|
|
|||
|
|
@ -10,18 +10,22 @@
|
|||
|
||||
//extern inline int strlen(char *src) { int i = 0; while (*src++) i++; return i;}
|
||||
|
||||
static inline size_t strnlen(const char *src, size_t max) {
|
||||
int i = 0;
|
||||
if (max<0) {
|
||||
while (*src++)
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
else {
|
||||
while ((*src++) && (i < max))
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
static inline size_t strnlen(const char *src, size_t max)
|
||||
{
|
||||
size_t i = 0;
|
||||
while((*src++) && (i < max)) {
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline size_t strlen(const char *src)
|
||||
{
|
||||
size_t i = 0;
|
||||
while(*src++) {
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
extern void *memcpy(void *dest, const void *src, size_t n);
|
||||
|
|
|
|||
22
src/include/version.h
Normal file
22
src/include/version.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
/* Motherboard Information */
|
||||
extern const char mainboard_vendor[];
|
||||
extern const char mainboard_part_number[];
|
||||
|
||||
/* LinuxBIOS Version */
|
||||
extern const char linuxbios_version[];
|
||||
extern const char linuxbios_extra_version[];
|
||||
extern const char linuxbios_build[];
|
||||
|
||||
/* When LinuxBIOS was compiled */
|
||||
extern const char linuxbios_compile_time[];
|
||||
extern const char linuxbios_compile_by[];
|
||||
extern const char linuxbios_compile_host[];
|
||||
extern const char linuxbios_compile_domain[];
|
||||
extern const char linuxbios_compiler[];
|
||||
extern const char linuxbios_linker[];
|
||||
extern const char linuxbios_assembler[];
|
||||
|
||||
#endif /* VERSION_H */
|
||||
|
|
@ -16,4 +16,7 @@ object do_inflate.o
|
|||
object floppy_subr.o BOOT_FLOPPY
|
||||
object delay.o
|
||||
object fallback_boot.o HAVE_FALLBACK_BOOT
|
||||
object compute_ip_checksum.o
|
||||
object compute_ip_checksum.o
|
||||
object version.o
|
||||
# Force version.o to recompile every time
|
||||
makedefine .PHONY : version.o
|
||||
|
|
@ -3,54 +3,34 @@
|
|||
|
||||
unsigned long compute_ip_checksum(void *addr, unsigned long length)
|
||||
{
|
||||
uint16_t *ptr;
|
||||
uint8_t *ptr;
|
||||
volatile union {
|
||||
uint8_t byte[2];
|
||||
uint16_t word;
|
||||
} value;
|
||||
unsigned long sum;
|
||||
unsigned long len;
|
||||
unsigned long laddr;
|
||||
/* compute an ip style checksum */
|
||||
laddr = (unsigned long )addr;
|
||||
unsigned long i;
|
||||
/* In the most straight forward way possible,
|
||||
* compute an ip style checksum.
|
||||
*/
|
||||
sum = 0;
|
||||
if (laddr & 1) {
|
||||
uint16_t buffer;
|
||||
unsigned char *ptr;
|
||||
/* copy the first byte into a 2 byte buffer.
|
||||
* This way automatically handles the endian question
|
||||
* of which byte (low or high) the last byte goes in.
|
||||
*/
|
||||
buffer = 0;
|
||||
ptr = addr;
|
||||
memcpy(&buffer, ptr, 1);
|
||||
sum += buffer;
|
||||
if (sum > 0xFFFF)
|
||||
sum -= 0xFFFF;
|
||||
length -= 1;
|
||||
addr = ptr +1;
|
||||
|
||||
}
|
||||
len = length >> 1;
|
||||
ptr = addr;
|
||||
while (len--) {
|
||||
sum += *(ptr++);
|
||||
if (sum > 0xFFFF)
|
||||
sum -= 0xFFFF;
|
||||
for(i = 0; i < length; i++) {
|
||||
unsigned long value;
|
||||
value = ptr[i];
|
||||
if (i & 1) {
|
||||
value <<= 8;
|
||||
}
|
||||
/* Add the new value */
|
||||
sum += value;
|
||||
/* Wrap around the carry */
|
||||
if (sum > 0xFFFF) {
|
||||
sum = (sum + (sum >> 16)) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
addr = ptr;
|
||||
if (length & 1) {
|
||||
uint16_t buffer;
|
||||
unsigned char *ptr;
|
||||
/* copy the last byte into a 2 byte buffer.
|
||||
* This way automatically handles the endian question
|
||||
* of which byte (low or high) the last byte goes in.
|
||||
*/
|
||||
buffer = 0;
|
||||
ptr = addr;
|
||||
memcpy(&buffer, ptr, 1);
|
||||
sum += buffer;
|
||||
if (sum > 0xFFFF)
|
||||
sum -= 0xFFFF;
|
||||
}
|
||||
return (~sum) & 0xFFFF;
|
||||
|
||||
value.byte[0] = sum & 0xff;
|
||||
value.byte[1] = (sum >> 8) & 0xff;
|
||||
return (~value.word) & 0xFFFF;
|
||||
}
|
||||
|
||||
unsigned long add_ip_checksums(unsigned long offset, unsigned long sum, unsigned long new)
|
||||
|
|
|
|||
|
|
@ -139,11 +139,11 @@ void pci_get_size(struct pci_dev *dev, unsigned long reg, unsigned long addr)
|
|||
// This incidentally catches the common case where registers
|
||||
// read back as 0 for both address and size.
|
||||
if (addr == size) {
|
||||
printk_debug(__FUNCTION__
|
||||
printk_spew(__FUNCTION__
|
||||
"dev_fn 0x%x, register %d, read-only"
|
||||
" SO, ignoring it\n",
|
||||
dev->devfn, reg);
|
||||
printk_debug("addr was 0x%x, size was 0x%x\n",addr,size);
|
||||
printk_spew("addr was 0x%x, size was 0x%x\n",addr,size);
|
||||
type = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ static char rcsid[] = "$Id$";
|
|||
|
||||
#define ONEMEG (1 << 20)
|
||||
|
||||
#define PCI_MEM_START 0x80000000
|
||||
#define PCI_MEM_START 0xC0000000
|
||||
#define PCI_IO_START 0x1000
|
||||
|
||||
// historical functions, sometimes very useful.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <pci.h>
|
||||
#include <printk.h>
|
||||
|
||||
|
|
@ -25,7 +27,7 @@ void refresh_set(int turn_it_on)
|
|||
// printk_info( __FUNCTION__ "refresh is now 0x%lx\n", ref);
|
||||
}
|
||||
// FIX ME!
|
||||
unsigned long sizeram()
|
||||
static unsigned long __sizeram(void)
|
||||
{
|
||||
extern void cache_disable(void), cache_enable(void);
|
||||
int i;
|
||||
|
|
@ -177,7 +179,21 @@ unsigned long sizeram()
|
|||
cache_enable();
|
||||
return 0; //64*1024*1024;
|
||||
}
|
||||
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = __sizeram();
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if (mem[1].sizek == 0) {
|
||||
mem[1].sizek = 64*1024;
|
||||
}
|
||||
mem[1].sizek -= mem[1].basek;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,23 @@
|
|||
#include <mem.h>
|
||||
#include <pci.h>
|
||||
#include <cpu/p5/io.h>
|
||||
#include <part/sizeram.h>
|
||||
|
||||
unsigned long sizeram(void)
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
u32 size;
|
||||
/* Use the PCI top memory register */
|
||||
pcibios_read_config_dword(0, 0, 0x9c, &size);
|
||||
/* Convert size in bytes to size in K */
|
||||
size = size >> 10;
|
||||
return size;
|
||||
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = size - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizke = 0;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1803,7 +1803,7 @@ spd_set_dram_timing_out:
|
|||
* Arguments: %bl device on the smbus to read from
|
||||
* %esi an initially zeroed copy of the
|
||||
* DRAM mode register.
|
||||
* %ebp Pointer to infomration that varies by memory bus speed
|
||||
* %ebp Pointer to information that varies by memory bus speed
|
||||
*
|
||||
* Results: cf clear
|
||||
* %esi updated with dimm with setting
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <pci.h>
|
||||
|
||||
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
/*
|
||||
* Code for the BX/GX and TX are almost the same
|
||||
*/
|
||||
|
|
@ -28,7 +31,13 @@ unsigned long sizeram()
|
|||
totalmem = 0x20000000UL;
|
||||
}
|
||||
|
||||
return totalmem;
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = totalmem - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <pci.h>
|
||||
|
||||
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
/*
|
||||
* This is written for BX but should work also for GX.
|
||||
*/
|
||||
|
|
@ -24,7 +27,14 @@ unsigned long sizeram()
|
|||
totalmem = 0x80000000UL;
|
||||
}
|
||||
|
||||
return totalmem;
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = totalmem - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <pci.h>
|
||||
#include <cpu/p5/io.h>
|
||||
#include <printk.h>
|
||||
|
|
@ -29,7 +31,7 @@ dumpramregs(struct pci_dev *pcidev)
|
|||
|
||||
|
||||
}
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
/*
|
||||
* This is written for BX but should work also for GX.
|
||||
|
|
@ -53,7 +55,13 @@ unsigned long sizeram()
|
|||
}
|
||||
dumpramregs(pcidev);
|
||||
|
||||
return totalmem;
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = totalmem - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <pci.h>
|
||||
#include <printk.h>
|
||||
|
||||
|
|
@ -19,8 +21,9 @@ static int DRP_sizetbl[] = {
|
|||
256, 256, 256, 512
|
||||
};
|
||||
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
unsigned long totalmem, curmem;
|
||||
unsigned char regval;
|
||||
|
||||
|
|
@ -46,7 +49,13 @@ unsigned long sizeram()
|
|||
printk_info("DIMM2 - size = %ldM\n", curmem );
|
||||
totalmem += curmem;
|
||||
|
||||
return totalmem * 1024;
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = totalmem*1024 - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,14 @@
|
|||
Intel 830 sizing.
|
||||
*/
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <pci.h>
|
||||
#include <printk.h>
|
||||
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
unsigned long totalmem;
|
||||
unsigned char regval;
|
||||
|
||||
|
|
@ -23,7 +26,14 @@ unsigned long sizeram()
|
|||
totalmem += regval * 32;
|
||||
}
|
||||
|
||||
return totalmem * 1024;
|
||||
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = totalmem*1024 - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
#include <mem.h>
|
||||
#include <pci.h>
|
||||
#include <arch/io.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
|
||||
unsigned long sizeram(void)
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned short word;
|
||||
|
|
@ -13,6 +14,12 @@ unsigned long sizeram(void)
|
|||
pcibios_read_config_word(0, 0, 0xc4, &word);
|
||||
/* Convert size in 64K bytes to size in K bytes */
|
||||
size = word << 6;
|
||||
return size;
|
||||
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = size - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
return &mem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,45 @@
|
|||
#include <mem.h>
|
||||
#include <pci.h>
|
||||
#include <arch/io.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
|
||||
unsigned long sizeram(void)
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned short word;
|
||||
static struct mem_range mem[4];
|
||||
uint16_t tolm, remapbase, remaplimit;
|
||||
uint8_t drb;
|
||||
|
||||
/* Read TOLM */
|
||||
/* How should we handle > 4GB of ram? */
|
||||
pcibios_read_config_word(0, 0, 0xc4, &word);
|
||||
/* Convert size in 128K bytes to size in K bytes */
|
||||
size = word << 5;
|
||||
return size;
|
||||
|
||||
/* FIXME do some of the configuration here instead of
|
||||
* just reading it all out, and reporting it.
|
||||
*/
|
||||
/* Read the ram configruation registers */
|
||||
pcibios_read_config_word(0, 0, 0xc4, &tolm);
|
||||
pcibios_read_config_word(0, 0, 0xc6, &remapbase);
|
||||
remapbase &= 0x1FF;
|
||||
pcibios_read_config_word(0, 0, 0xc8, &remaplimit);
|
||||
remaplimit &= 0x1FF;
|
||||
pcibios_read_config_byte(0, 0, 0x67, &drb);
|
||||
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 768;
|
||||
/* Convert size in 64K bytes to size in K bytes */
|
||||
mem[1].sizek = (tolm << 6) - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if ((drb << 16) > (tolm << 6)) {
|
||||
mem[2].basek = 4096*1024;
|
||||
mem[2].sizek = (drb << 16) - mem[2].basek;
|
||||
/* I know that the remap window always immediately follows
|
||||
* the real top of memory.
|
||||
*/
|
||||
if (remapbase < remaplimit) {
|
||||
mem[2].sizek = (remaplimit << 16) - mem[2].basek;
|
||||
}
|
||||
}
|
||||
mem[3].basek = 0;
|
||||
mem[3].sizek = 0;
|
||||
|
||||
return &mem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <pci.h>
|
||||
#include <cpu/p5/io.h>
|
||||
#include <printk.h>
|
||||
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
//unsigned long totalmemKB = 1024*1024;
|
||||
struct pci_dev *pcidev;
|
||||
unsigned long totalmemKB = 0 ,memfound = 0;
|
||||
|
|
@ -64,9 +67,14 @@ unsigned long sizeram()
|
|||
pci_read_config_byte(pcidev,(0x80+i),&value);
|
||||
}
|
||||
}
|
||||
|
||||
return totalmemKB;
|
||||
//return 1024*1024;
|
||||
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = totalmemKB - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
Do chipset setup for a National Semiconductor GX1 CPU.
|
||||
*/
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pci.h>
|
||||
#include <pci_ids.h>
|
||||
|
|
@ -58,8 +60,9 @@ static unsigned long adjust_video_memory(unsigned long mem_size)
|
|||
return mem_size;
|
||||
}
|
||||
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
u32 mem_bank_cfg;
|
||||
unsigned mem_size;
|
||||
|
||||
|
|
@ -71,7 +74,13 @@ unsigned long sizeram()
|
|||
|
||||
mem_size = adjust_video_memory(mem_size);
|
||||
|
||||
return mem_size;
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = mem_size - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pci.h>
|
||||
#include <pciconf.h>
|
||||
|
||||
|
||||
unsigned long sizeram()
|
||||
static unsigned long __sizeram(void)
|
||||
{
|
||||
unsigned long totalmem;
|
||||
unsigned char bank, mem, prevmem;
|
||||
|
|
@ -52,13 +54,21 @@ unsigned long sizeram()
|
|||
return totalmem;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
return 0;
|
||||
static struct mem_range mem[3];
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = __sizeram();
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if (mem[1].sizek == 0) {
|
||||
mem[1].sizek = 64*1024;
|
||||
}
|
||||
mem[1].sizek -= mem[1].basek;
|
||||
return &mem;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
void framebuffer_on()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pci.h>
|
||||
#include <pciconf.h>
|
||||
|
||||
|
||||
unsigned long sizeram()
|
||||
static unsigned long __sizeram(void)
|
||||
{
|
||||
unsigned long totalmem;
|
||||
unsigned char bank, mem, prevmem;
|
||||
|
|
@ -52,13 +54,21 @@ unsigned long sizeram()
|
|||
return totalmem;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
return 0;
|
||||
static struct mem_range mem[3];
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = __sizeram();
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if (mem[1].sizek == 0) {
|
||||
mem[1].sizek = 64*1024;
|
||||
}
|
||||
mem[1].sizek -= mem[1].basek;
|
||||
return &mem;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
void framebuffer_on()
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
Do chipset setup for a National Semiconductor SCx200 CPU.
|
||||
*/
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pci.h>
|
||||
#include <pci_ids.h>
|
||||
|
|
@ -26,8 +28,9 @@ static unsigned calc_dimm(int index, unsigned cfg)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned long sizeram()
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
u32 mem_bank_cfg;
|
||||
unsigned mem_size;
|
||||
|
||||
|
|
@ -37,7 +40,13 @@ unsigned long sizeram()
|
|||
mem_size += calc_dimm(0, mem_bank_cfg);
|
||||
mem_size += calc_dimm(1, mem_bank_cfg >> 16);
|
||||
|
||||
return mem_size;
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = mem_size - mem[1].basek;
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ static char rcsid[] =
|
|||
#endif
|
||||
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pciconf.h>
|
||||
#include <subr.h>
|
||||
|
|
@ -37,7 +39,7 @@ const static int ramsizes[16] =
|
|||
#define SIS630_BANK1 0x61
|
||||
#define SIS630_BANK2 0x62
|
||||
#define SIS630_DIMM_LOCATION_FOR_SMA 0x65
|
||||
unsigned long sizeram()
|
||||
static unsigned long __sizeram(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
unsigned int dimm_slot, dimm_reg, sides;
|
||||
|
|
@ -95,6 +97,22 @@ unsigned long sizeram()
|
|||
return total_size;
|
||||
}
|
||||
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = __sizeram();
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if (mem[1].sizek == 0) {
|
||||
mem[1].sizek = 64*1024;
|
||||
}
|
||||
mem[1].sizek -= mem[1].basek;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
void framebuffer_on()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ static char rcsid[] =
|
|||
#endif
|
||||
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pciconf.h>
|
||||
#include <subr.h>
|
||||
|
|
@ -37,7 +39,7 @@ const static int ramsizes[16] =
|
|||
#define SIS630_BANK1 0x61
|
||||
#define SIS630_BANK2 0x62
|
||||
#define SIS630_DIMM_LOCATION_FOR_SMA 0x65
|
||||
unsigned long sizeram()
|
||||
static unsigned long __sizeram(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
unsigned int dimm_slot, dimm_reg, sides;
|
||||
|
|
@ -92,6 +94,23 @@ unsigned long sizeram()
|
|||
return total_size;
|
||||
}
|
||||
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = __sizeram();
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if (mem[1].sizek == 0) {
|
||||
mem[1].sizek = 64*1024;
|
||||
}
|
||||
mem[1].sizek -= mem[1].basek;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
void framebuffer_on()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ static char rcsid[] =
|
|||
#endif
|
||||
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pciconf.h>
|
||||
#include <subr.h>
|
||||
|
|
@ -37,7 +39,7 @@ const static int ramsizes[16] =
|
|||
#define SIS630_BANK1 0x61
|
||||
#define SIS630_BANK2 0x62
|
||||
#define SIS630_DIMM_LOCATION_FOR_SMA 0x65
|
||||
unsigned long sizeram()
|
||||
static unsigned long __sizeram(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
unsigned int dimm_slot, dimm_reg, sides;
|
||||
|
|
@ -92,6 +94,23 @@ unsigned long sizeram()
|
|||
return total_size;
|
||||
}
|
||||
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = __sizeram();
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if (mem[1].sizek == 0) {
|
||||
mem[1].sizek = 64*1024;
|
||||
}
|
||||
mem[1].sizek -= mem[1].basek;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
void framebuffer_on()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pciconf.h>
|
||||
#include <subr.h>
|
||||
|
|
@ -49,8 +51,7 @@ const static int ramsizes[16] =
|
|||
#define SIS635_BANK1 0x61
|
||||
#define SIS635_BANK2 0x62
|
||||
#define SIS635_BANK3 0x63
|
||||
unsigned
|
||||
long sizeram()
|
||||
static unsigned long __sizeram(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
unsigned int dimm_slot, dimm_reg, sides;
|
||||
|
|
@ -87,6 +88,24 @@ long sizeram()
|
|||
return total_size;
|
||||
}
|
||||
|
||||
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = __sizeram();
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if (mem[1].sizek == 0) {
|
||||
mem[1].sizek = 64*1024;
|
||||
}
|
||||
mem[1].sizek -= mem[1].basek;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
void framebuffer_on()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
<<<<<<< northbridge.c
|
||||
* southbridge.c: Norththbridge Initialization For SiS 730
|
||||
* northbridge.c: Norththbridge Initialization For SiS 730
|
||||
*
|
||||
* Copyright 2002 Silicon Integrated Systems Corp.
|
||||
*
|
||||
|
|
@ -28,6 +27,8 @@ static char rcsid[] =
|
|||
#endif
|
||||
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pciconf.h>
|
||||
#include <subr.h>
|
||||
|
|
@ -56,7 +57,7 @@ const static int ramsizes[16] =
|
|||
#define SIS630_DIMM_LOCATION_FOR_SMA 0x65
|
||||
#define MAX_DIMM_SLOTS 3
|
||||
|
||||
unsigned long sizeram()
|
||||
static unsigned long __sizeram(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
unsigned int dimm_slot, dimm_reg, sides;
|
||||
|
|
@ -111,6 +112,22 @@ unsigned long sizeram()
|
|||
return total_size;
|
||||
}
|
||||
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = __sizeram();
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if (mem[1].sizek == 0) {
|
||||
mem[1].sizek = 64*1024;
|
||||
}
|
||||
mem[1].sizek -= mem[1].basek;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
void framebuffer_on()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <mem.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <printk.h>
|
||||
#include <pciconf.h>
|
||||
#include <subr.h>
|
||||
|
|
@ -49,8 +51,7 @@ const static int ramsizes[16] =
|
|||
#define SIS735_BANK1 0x61
|
||||
#define SIS735_BANK2 0x62
|
||||
#define SIS735_BANK3 0x63
|
||||
unsigned
|
||||
long sizeram()
|
||||
static unsigned long __sizeram(void)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
unsigned int dimm_slot, dimm_reg, sides;
|
||||
|
|
@ -87,6 +88,22 @@ long sizeram()
|
|||
return total_size;
|
||||
}
|
||||
|
||||
struct mem_range *sizeram(void)
|
||||
{
|
||||
static struct mem_range mem[3];
|
||||
mem[0].basek = 0;
|
||||
mem[0].sizek = 640;
|
||||
mem[1].basek = 1024;
|
||||
mem[1].sizek = __sizeram();
|
||||
mem[2].basek = 0;
|
||||
mem[2].sizek = 0;
|
||||
if (mem[1].sizek == 0) {
|
||||
mem[1].sizek = 64*1024;
|
||||
}
|
||||
mem[1].sizek -= mem[1].basek;
|
||||
return &mem;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
void framebuffer_on()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ int get_option(void *dest, char *name)
|
|||
}
|
||||
}
|
||||
if(!found) {
|
||||
printk_err("ERR: No cmos option '%s'\n", name);
|
||||
printk_err("ERROR: No cmos option '%s'\n", name);
|
||||
return(-2);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,36 +12,27 @@ dn_after: .string "After setting values: \r\n"
|
|||
.previous
|
||||
|
||||
|
||||
dumpnorth:
|
||||
dumpnorth:
|
||||
mov %esp, %ebp
|
||||
CONSOLE_INFO_TX_STRING($dn_banner)
|
||||
xorl %ecx, %ecx
|
||||
1:
|
||||
CONSOLE_INFO_TX_HEX32(%ecx)
|
||||
CONSOLE_INFO_TX_CHAR($'-')
|
||||
movl %ecx, %eax
|
||||
CONSOLE_INFO_TX_HEX8(%cl)
|
||||
CONSOLE_INFO_TX_CHAR($':')
|
||||
CONSOLE_INFO_TX_CHAR($' ')
|
||||
|
||||
PCI_READ_CONFIG_DWORD
|
||||
#if 0
|
||||
CONSOLE_INFO_TX_HEX32(%eax)
|
||||
#else
|
||||
CONSOLE_INFO_TX_HEX8(%al)
|
||||
2:
|
||||
movl %ecx, %eax
|
||||
PCI_READ_CONFIG_DWORD
|
||||
shrl $8,%eax
|
||||
PCI_READ_CONFIG_BYTE
|
||||
CONSOLE_INFO_TX_HEX8(%al)
|
||||
movl %ecx, %eax
|
||||
PCI_READ_CONFIG_DWORD
|
||||
shrl $16,%eax
|
||||
CONSOLE_INFO_TX_HEX8(%al)
|
||||
movl %ecx, %eax
|
||||
PCI_READ_CONFIG_DWORD
|
||||
shrl $24,%eax
|
||||
CONSOLE_INFO_TX_HEX8(%al)
|
||||
#endif
|
||||
CONSOLE_INFO_TX_CHAR($' ')
|
||||
|
||||
incl %ecx
|
||||
testb $0xf, %cl
|
||||
jnz 2b
|
||||
|
||||
CONSOLE_INFO_TX_CHAR($'\r')
|
||||
CONSOLE_INFO_TX_CHAR($'\n')
|
||||
addl $0x4, %ecx
|
||||
cmpl $256, %ecx
|
||||
jne 1b
|
||||
CONSOLE_INFO_TX_STRING($dn_done)
|
||||
|
|
|
|||
24
src/sdram/generic_cache_linuxbios.inc
Normal file
24
src/sdram/generic_cache_linuxbios.inc
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* enable caching for 0 - 16M using a variable mtrr
|
||||
* This should be all we need to get good performance out of LinuxBIOS.
|
||||
*/
|
||||
|
||||
/* Disable the cache while we set up a new MTRR over memory */
|
||||
movl %cr0, %eax
|
||||
orl $0x40000000, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
movl $0x200, %ecx /* mtrr[0] physical base register */
|
||||
movl $0x00000000, %edx
|
||||
movl $0x00000006, %eax
|
||||
wrmsr
|
||||
|
||||
movl $0x201, %ecx /* mtrr[0] physical mask register */
|
||||
movl $0x0000000f, %edx
|
||||
movl $0xff000800, %eax
|
||||
wrmsr
|
||||
|
||||
/* Reenable the cache now that the mtrr is set up */
|
||||
movl %cr0, %eax
|
||||
andl $0x9fffffff, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
|
|
@ -8,15 +8,14 @@ dump_spd_reg_dimm:
|
|||
CONSOLE_DEBUG_TX_CHAR($'m')
|
||||
CONSOLE_DEBUG_TX_CHAR($'m')
|
||||
CONSOLE_DEBUG_TX_CHAR($' ')
|
||||
movb %bl, %al
|
||||
CALLSP(ttys0_tx_hex8)
|
||||
CONSOLE_DEBUG_TX_HEX8(%bl)
|
||||
CONSOLE_DEBUG_TX_CHAR($'\r')
|
||||
CONSOLE_DEBUG_TX_CHAR($'\n')
|
||||
dump_spd_reg_byte:
|
||||
CALLSP(smbus_read_byte)
|
||||
jz dump_spd_reg_next_dimm
|
||||
|
||||
CALLSP(ttys0_tx_hex8)
|
||||
CONSOLE_DEBUG_TX_HEX8(%al)
|
||||
CONSOLE_DEBUG_TX_CHAR($' ')
|
||||
incb %bh
|
||||
testb $0x0F, %bh
|
||||
|
|
|
|||
|
|
@ -7,11 +7,14 @@ ram_4: .string "Ram4\r\n"
|
|||
ram_5: .string "Ram5\r\n"
|
||||
ram_6: .string "Ram6\r\n"
|
||||
|
||||
no_memory_str: .string "ERROR: No memory!"
|
||||
crlf: .string "\r\n"
|
||||
|
||||
no_memory_str: .string "No memory!\r\n"
|
||||
|
||||
no_memory: CONSOLE_DEBUG_TX_STRING($no_memory_str)
|
||||
1: hlt /* stick here.. */
|
||||
no_memory: CONSOLE_ERR_TX_STRING($no_memory_str)
|
||||
mem_stop:
|
||||
CONSOLE_ERR_TX_STRING($crlf)
|
||||
1:
|
||||
hlt /* stick here.. */
|
||||
jmp 1b
|
||||
|
||||
ram_initialize:
|
||||
|
|
|
|||
|
|
@ -38,3 +38,16 @@
|
|||
|
||||
#define SMBUS_BUS 0
|
||||
#define SMBUS_DEVFN ((0x1f << 3) + 3)
|
||||
#define SMBUS_IO_BASE 0x1000
|
||||
|
||||
#define SMBHSTSTAT 0x0
|
||||
#define SMBHSTCTL 0x2
|
||||
#define SMBHSTCMD 0x3
|
||||
#define SMBXMITADD 0x4
|
||||
#define SMBHSTDAT0 0x5
|
||||
#define SMBHSTDAT1 0x6
|
||||
#define SMBBLKDAT 0x7
|
||||
#define SMBTRNSADD 0x9
|
||||
#define SMBSLVDATA 0xa
|
||||
#define SMLINK_PIN_CTL 0xe
|
||||
#define SMBUS_PIN_CTL 0xf
|
||||
|
|
|
|||
|
|
@ -4,21 +4,6 @@
|
|||
#include <southbridge/intel/82801.h>
|
||||
#include "82801.h"
|
||||
|
||||
|
||||
#define SMBUS_IO_BASE 0x1000
|
||||
|
||||
#define SMBHSTSTAT 0x0
|
||||
#define SMBHSTCTL 0x2
|
||||
#define SMBHSTCMD 0x3
|
||||
#define SMBXMITADD 0x4
|
||||
#define SMBHSTDAT0 0x5
|
||||
#define SMBHSTDAT1 0x6
|
||||
#define SMBBLKDAT 0x7
|
||||
#define SMBTRNSADD 0x9
|
||||
#define SMBSLVDATA 0xa
|
||||
#define SMLINK_PIN_CTL 0xe
|
||||
#define SMBUS_PIN_CTL 0xf
|
||||
|
||||
void smbus_setup(void)
|
||||
{
|
||||
pcibios_write_config_dword(SMBUS_BUS, SMBUS_DEVFN, 0x20, SMBUS_IO_BASE | 1);
|
||||
|
|
|
|||
|
|
@ -1,65 +1,43 @@
|
|||
/* Useful macros PCIBUS, and SMBUS functions for getting DRAM going. */
|
||||
/* courtesy Eric Biederman of linuxnetworx.com */
|
||||
/*
|
||||
* Copyright (C) 2002 Eric Biederman
|
||||
*/
|
||||
|
||||
#define CS_WRITE_BYTE(addr, byte) \
|
||||
movl $addr, %eax ; \
|
||||
movl $byte, %edx ; \
|
||||
PCI_WRITE_CONFIG_BYTE
|
||||
|
||||
#define CS_WRITE_WORD(addr, word) \
|
||||
movl $addr, %eax ; \
|
||||
movl $word, %ecx ; \
|
||||
PCI_WRITE_CONFIG_WORD
|
||||
|
||||
#define CS_WRITE_LONG(addr, dword) \
|
||||
movl $addr, %eax ; \
|
||||
movl $dword, %ecx ; \
|
||||
PCI_WRITE_CONFIG_DWORD
|
||||
|
||||
#define DEVFN(device, function) (((device) << 3) + (function))
|
||||
#ifndef CONFIG_ADDR
|
||||
#define CONFIG_ADDR(bus,devfn,where) (((bus) << 16) | ((devfn) << 8) | (where))
|
||||
#endif
|
||||
#include "82801.h"
|
||||
|
||||
/* jump around these subrs */
|
||||
jmp smbus_pcibus_end
|
||||
|
||||
/* generic SMB routines that work for many systems. The only one that might
|
||||
* not work is the enable_smbus.
|
||||
* you have to define PM_FUNCTION for this to work.
|
||||
*/#define SMBUS_IO_BASE 0xf00
|
||||
#define SMBHSTSTAT 0
|
||||
#define SMBHSTCTL 2
|
||||
#define SMBHSTCMD 3
|
||||
#define SMBHSTADD 4
|
||||
#define SMBHSTDAT0 5
|
||||
#define SMBHSTDAT1 6
|
||||
#define SMBBLKDAT 7
|
||||
|
||||
enable_smbus:
|
||||
/* put the SMBUS at port 0xf00 */
|
||||
CS_WRITE_LONG(PM_DEVFN+ 0x90, SMBUS_IO_BASE|1) /* iobase addr */
|
||||
CS_WRITE_BYTE(PM_DEVFN + 0xd2, (0x4 << 1) | 1) /* smbus enable */
|
||||
CS_WRITE_WORD(PM_DEVFN + 0x4, 1) /* iospace enable */
|
||||
RET_LABEL(enable_smbus)
|
||||
jmp smbus_end
|
||||
|
||||
/*
|
||||
* Routine: setup_smbus
|
||||
* Routine: smbus_setup
|
||||
* Arguments: none
|
||||
* Results: none
|
||||
* Trashed: eax, edx
|
||||
* Trashed: eax, edx, ecx
|
||||
* Effects: The smbus is enabled
|
||||
*/
|
||||
setup_smbus:
|
||||
xor %eax,%eax
|
||||
movl $(SMBUS_IO_BASE +SMBHSTSTAT), %edx
|
||||
outb %al, %dx
|
||||
RET_LABEL(setup_smbus)
|
||||
|
||||
#define SMBUS_MEM_DEVICE_0 (0xa << 3)
|
||||
#define SMBUS_MEM_DEVICE_1 (SMBUS_MEM_DEVICE_0 +1)
|
||||
#define SMBUS_MEM_DEVICE_2 (SMBUS_MEM_DEVICE_0 +2)
|
||||
#define SMBUS_MEM_DEVICE_3 (SMBUS_MEM_DEVICE_0 +3)
|
||||
smbus_setup:
|
||||
/* set smbus iobase */
|
||||
movl $((SMBUS_DEVFN << 8) + 0x20), %eax
|
||||
movl $(SMBUS_IO_BASE | 1), %ecx
|
||||
PCI_WRITE_CONFIG_DWORD
|
||||
|
||||
/* Set smbus enable */
|
||||
movl $((SMBUS_DEVFN << 8) + 0x40), %eax
|
||||
movl $1, %edx
|
||||
PCI_WRITE_CONFIG_BYTE
|
||||
|
||||
/* Set smbus iospace enable */
|
||||
movl $((SMBUS_DEVFN << 8) + 0x4), %eax
|
||||
movl $1, %ecx
|
||||
PCI_WRITE_CONFIG_WORD
|
||||
|
||||
/* Diable interrupt generation */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
|
||||
xorl %eax, %eax
|
||||
outb %al, %dx
|
||||
|
||||
RET_LABEL(smbus_setup)
|
||||
|
||||
|
||||
/*
|
||||
* Routine: smbus_wait_until_ready
|
||||
|
|
@ -69,10 +47,10 @@ setup_smbus:
|
|||
* Effects: Upon return the smbus is ready to accept commands
|
||||
*/
|
||||
smbus_wait_until_ready:
|
||||
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
|
||||
1: inb %dx, %al
|
||||
testb $1, %al
|
||||
jnz 1b
|
||||
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
|
||||
1: inb %dx, %al
|
||||
testb $1, %al
|
||||
jnz 1b
|
||||
RET_LABEL(smbus_wait_until_ready)
|
||||
|
||||
/*
|
||||
|
|
@ -83,16 +61,16 @@ smbus_wait_until_ready:
|
|||
* Effects: Upon return the smbus has completed it's most recent transation
|
||||
*/
|
||||
smbus_wait_until_done:
|
||||
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
|
||||
1: inb %dx, %al
|
||||
testb $1, %al
|
||||
jnz 1b
|
||||
2: testb $0xFE, %al
|
||||
jnz 3f
|
||||
inb %dx, %al
|
||||
testb $0xFE, %al
|
||||
jz 2b
|
||||
3: RET_LABEL(smbus_wait_until_done)
|
||||
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
|
||||
1: inb %dx, %al
|
||||
testb $1, %al
|
||||
jnz 1b
|
||||
jmp 3f
|
||||
2:
|
||||
inb %dx, %al
|
||||
3: testb $~((1<<6)|(1<<0)), %al
|
||||
jz 2b
|
||||
RET_LABEL(smbus_wait_until_done)
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -119,414 +97,65 @@ smbus_read_byte:
|
|||
/* poll until the smbus is ready for commands */
|
||||
CALL_LABEL(smbus_wait_until_ready)
|
||||
|
||||
/* clear any lingering errors, so that the transaction will run */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
|
||||
inb %dx, %al
|
||||
outb %al, %dx
|
||||
/* setup transaction */
|
||||
/* disable interrupts */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
|
||||
inb %dx, %al
|
||||
andb $0xFE, %al
|
||||
outb %al, %dx
|
||||
|
||||
/* set the device I'm talking to */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTADD), %edx
|
||||
movb %bl /* device */, %al
|
||||
shlb $1, %al
|
||||
orb $1, %al
|
||||
outb %al, %dx
|
||||
movl $(SMBUS_IO_BASE + SMBXMITADD), %edx
|
||||
movb %bl /* device */, %al
|
||||
shlb $1, %al
|
||||
orb $1, %al
|
||||
outb %al, %dx
|
||||
|
||||
/* set the command address... */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTCMD), %edx
|
||||
movb %bh /* address */, %al
|
||||
outb %al, %dx
|
||||
movl $(SMBUS_IO_BASE + SMBHSTCMD), %edx
|
||||
movb %bh /* address */, %al
|
||||
outb %al, %dx
|
||||
|
||||
/* clear the data byte */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTDAT0), %edx
|
||||
xorl %eax, %eax
|
||||
outb %al, %dx
|
||||
/* setup for a byte data read */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
|
||||
inb %dx, %al
|
||||
andb $0xE3, %al
|
||||
orb $(0x2 << 2), %al
|
||||
outb %al, %dx
|
||||
|
||||
/* clear any lingering errors, so the transaction will run */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
|
||||
inb %dx, %al
|
||||
outb %al, %dx
|
||||
|
||||
/* clear the data byte... */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTDAT0), %edx
|
||||
xorl %eax, %eax
|
||||
outb %al, %dx
|
||||
|
||||
/* start a byte read, with interrupts disabled */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
|
||||
movl $((0x2 << 2) | (1 << 6)), %eax
|
||||
outb %al, %dx
|
||||
movl $(SMBUS_IO_BASE + SMBHSTCTL), %edx
|
||||
inb %dx, %al
|
||||
orb $0x40, %al
|
||||
outb %al, %dx
|
||||
|
||||
/* poll for transaction completion */
|
||||
CALL_LABEL(smbus_wait_until_done)
|
||||
|
||||
/* read the results and see if we succeded */
|
||||
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
|
||||
inb %dx, %al
|
||||
testb $0x02, %al
|
||||
jz 1f
|
||||
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
|
||||
inb %dx, %al
|
||||
andb $~(1 << 6), %al /* Ignore the In Use Status... */
|
||||
cmpb $0x02, %al
|
||||
sete %al
|
||||
testb %al, %al
|
||||
jz 1f
|
||||
|
||||
movl $(SMBUS_IO_BASE + SMBHSTDAT0), %edx
|
||||
inb %dx, %al
|
||||
1:
|
||||
RETSP
|
||||
|
||||
/* now for code to actually do the deed. Eric did such a good job that
|
||||
* this stuff is basically generic.
|
||||
*/
|
||||
/*
|
||||
* Routine: spd_set_drb
|
||||
* Arguments: None
|
||||
*
|
||||
* Trashed: %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp, %eflags
|
||||
* Effects: Uses serial presence detect to set the
|
||||
* DRB registers which holds the ending memory address assigned
|
||||
* to each DIMM.
|
||||
* Notes: %ebp holds the currently detected end of memory.
|
||||
* %ebx holds the configuration port & SMBUS_MEM_DEVICE for
|
||||
* the current iteration through the loop.
|
||||
* %edi holds the memory size for the first side of the DIMM.
|
||||
* %esi holds the memory size for the second side of the DIMM.
|
||||
* memory size is represent as a power of 2.
|
||||
* An unset memory size is represented as -1 ie. 0xFFFFFFFF
|
||||
*/
|
||||
|
||||
spd_set_drb:
|
||||
xorl %ebp, %ebp /* clear the memory address */
|
||||
movl $((DRAM_CONFIG_PORT << 16) |SMBUS_MEM_DEVICE_0), %ebx
|
||||
spd_set_drb_loop_top:
|
||||
// set -1 power-of-two for side 1 (called bank0 in most chipset docs)
|
||||
xorl %edi, %edi
|
||||
subl $1, %edi
|
||||
// set -1 power-of-two for side 2 (called bank1 in most chipset docs)
|
||||
xorl %esi, %esi
|
||||
subl $1, %esi
|
||||
|
||||
movb $3, %bh /* rows */
|
||||
CALLSP(smbus_read_byte)
|
||||
// If it's zero, then we just set current %ebp into the row
|
||||
// end register
|
||||
jz 20f
|
||||
andl $0xf, %eax
|
||||
addl %eax, %edi
|
||||
|
||||
movb $4, %bh /* columns */
|
||||
CALLSP(smbus_read_byte)
|
||||
andl $0xf, %eax
|
||||
addl %eax, %edi
|
||||
|
||||
movb $17, %bh /* banks */
|
||||
CALLSP(smbus_read_byte)
|
||||
andl $0xff, %eax
|
||||
bsrl %eax, %ecx
|
||||
addl %ecx, %edi
|
||||
|
||||
/* Get the module data width and convert it to a power of two */
|
||||
movb $7, %bh /* (high byte) */
|
||||
CALLSP(smbus_read_byte)
|
||||
andl $0xff, %eax
|
||||
movl %eax, %ecx
|
||||
shll $8, %ecx
|
||||
|
||||
movb $6, %bh /* (low byte) */
|
||||
CALLSP(smbus_read_byte)
|
||||
andl $0xff, %eax
|
||||
orl %eax, %ecx
|
||||
bsrl %ecx, %eax
|
||||
addl %eax, %edi
|
||||
|
||||
/* now I have the ram size in bits as a power of two (less 1) */
|
||||
// It is less 1 since we started with -1 above.
|
||||
// OK, BITS as power of two (but minus 1)
|
||||
// So, e.g., 8 MB is 64 Mb, 64 Mb is 26 bits. Subtract
|
||||
// (26-1) or 25
|
||||
subl $25, %edi /* Make it multiples of 8MB */
|
||||
|
||||
/* side two */
|
||||
movb $5, %bh /* number of physical banks */
|
||||
CALLSP(smbus_read_byte)
|
||||
cmp $1, %al
|
||||
// it's only one bank
|
||||
jbe 20f
|
||||
// It's two banks. So assign edi to esi
|
||||
/* for now only handle the symmetrical case */
|
||||
// it's two banks, assume however that they're the same size.
|
||||
// it's stupid to have any other kind, right?
|
||||
movl %edi, %esi
|
||||
20:
|
||||
/* Compute the end address for the DRB register */
|
||||
// If it is >= 8, i.e. >= 2^8 or 256, skip it.
|
||||
// >= 8 is a bogus value.
|
||||
cmpl $8, %edi
|
||||
jae 21f
|
||||
movl $1, %eax
|
||||
movl %edi, %ecx
|
||||
shll %cl, %eax
|
||||
// increment row-end by the size of this DIMM half
|
||||
addl %eax, %ebp
|
||||
21:
|
||||
/* Write the comuputed value for the first half of the DIMM */
|
||||
movl %ebp, %edx /* value to write into %edx */
|
||||
movl %ebx, %eax
|
||||
shrl $16, %eax /* port address into %eax */
|
||||
PCI_WRITE_CONFIG_BYTE
|
||||
|
||||
/* Compute the end address for the DRB register */
|
||||
cmpl $8, %esi
|
||||
jae 30f
|
||||
mov $1, %eax
|
||||
movl %esi, %ecx
|
||||
shll %cl, %eax
|
||||
addl %eax, %ebp
|
||||
30:
|
||||
/* Write the comuputed value for the second half of the DIMM */
|
||||
movl %ebp, %edx /* value to write into %edx */
|
||||
movl %ebx, %eax
|
||||
shrl $16, %eax /* port address into %eax */
|
||||
addl $1, %eax /* The second half uses one port high */
|
||||
PCI_WRITE_CONFIG_BYTE
|
||||
|
||||
addl $0x00020001, %ebx /* increment the smbus device & the config port */
|
||||
cmpb $LAST_SMBUS_MEM_DEVICE, %bl /* see if I have reached the end */
|
||||
jbe spd_set_drb_loop_top
|
||||
|
||||
/* o.k. I'm done return now */
|
||||
RET_LABEL(spd_set_drb)
|
||||
|
||||
/*
|
||||
* Routine: spd_set_dramc
|
||||
* Arguments: None
|
||||
*
|
||||
* Trashed: %eax, %ebx, %edx, %esp, %eflags
|
||||
* Effects: Uses serial presence detect to set the
|
||||
* DRAMC register, which records if ram is registerd or not,
|
||||
* and controls the refresh rate.
|
||||
* The refresh rate is not set here, as memory refresh
|
||||
* cannot be enbaled until after memory is initialized.
|
||||
* see spd_enable_refresh.
|
||||
* Notes:
|
||||
* FIXME: Check for illegal/unsupported ram configurations and abort
|
||||
* FIXME: won't work with non-contiguous DRAM size regs (like VIA)
|
||||
* need an indirect pointer to an array of reg #s
|
||||
*/
|
||||
|
||||
spd_set_dramc:
|
||||
/* auto detect if ram is registered or not. */
|
||||
/* The DRAMC register also contorls the refresh rate but we can't
|
||||
* set that here because we must leave refresh disabled.
|
||||
* see: spd_enable_refresh
|
||||
*/
|
||||
/* Find the first dimm and assume the rest are the same */
|
||||
/* Load the smbus device and port int %ebx */
|
||||
movl $((21 << 8) | SMBUS_MEM_DEVICE_0), %ebx
|
||||
1: CALLSP(smbus_read_byte)
|
||||
jz 2f
|
||||
andl $0x12, %eax
|
||||
jmp spd_set_dramc_out
|
||||
|
||||
2: addl $1, %ebx /* increment the device */
|
||||
cmpb $LAST_SMBUS_MEM_DEVICE, %bl
|
||||
jbe 1b
|
||||
/* We couldn't find anything we must have no memory */
|
||||
jmp no_memory
|
||||
|
||||
spd_set_dramc_out:
|
||||
testb $0x12, %al
|
||||
jz 2f
|
||||
movl REGISTERED_DRAM, %eax
|
||||
jmp 1f
|
||||
2: movl NONREGISTERED_DRAM, %eax
|
||||
1: movl %eax, %edx
|
||||
movl REGISTERED_DRAM_REGISTER, %eax
|
||||
PCI_WRITE_CONFIG_BYTE
|
||||
RET_LABEL(spd_set_dramc)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Routine: spd_read_refresh
|
||||
* Arguments: None
|
||||
*
|
||||
* Trashed: %eax, %ebx, %ecx, %edx, %esp, %eflags
|
||||
* Effects: Uses serial presence detect to find refresh rates.
|
||||
* returns the rate in %eax
|
||||
* It's up to you to set hardware up.
|
||||
* FIXME: Check for illegal/unsupported ram configurations and abort
|
||||
*/
|
||||
|
||||
|
||||
spd_read_refresh:
|
||||
/* Find the first dimm and assume the rest are the same */
|
||||
/* Load the smbus device and port int %ebx */
|
||||
movl $((12 << 8) | SMBUS_MEM_DEVICE_0), %ebx
|
||||
1: CALLSP(smbus_read_byte)
|
||||
jz 2f
|
||||
andl $0x7f, %eax
|
||||
jmp spd_enable_refresh_out
|
||||
|
||||
2: addl $1, %ebx /* increment the device */
|
||||
cmpb $LAST_SMBUS_MEM_DEVICE, %bl
|
||||
jbe 1b
|
||||
/* We couldn't find anything we must have no memory */
|
||||
xorl %eax, %eax
|
||||
spd_enable_refresh_out:
|
||||
RET_LABEL(spd_enable_refresh)
|
||||
|
||||
/*
|
||||
* Routine: spd_set_rps
|
||||
* Arguments: None
|
||||
*
|
||||
* Trashed: %eax, %ebx, %ecx, %edx, %esi, %edi, %esp, %eflags
|
||||
* Effects: Uses serial presence detect to set the row size
|
||||
* on a given DIMM
|
||||
* Notes: %esi accumulates the row sizes of all of the DIMMs
|
||||
* %ecx holds the current bit into into %esi
|
||||
* %bl holds the current SMBUS device
|
||||
* FIXME: Check for illegal/unsupported ram configurations and abort
|
||||
*/
|
||||
|
||||
spd_set_rps:
|
||||
/* The RPS register holds the size of a ``page'' of DRAM on each DIMM */
|
||||
/* default all page sizes to 2KB */
|
||||
xorl %esi, %esi
|
||||
/* Index into %esi of bit to set */
|
||||
movl $0 , %ecx
|
||||
/* Load the smbus device into %ebx */
|
||||
movl $SMBUS_MEM_DEVICE_0, %ebx
|
||||
|
||||
1: movb $3, %bh
|
||||
CALLSP(smbus_read_byte) /* row address bits */
|
||||
jz 2f
|
||||
andl $0xf, %eax
|
||||
movl %eax, %edi
|
||||
/* I now have the row page size as a power of 2 */
|
||||
subl $11, %edi /* Now make it in multiples of 2Kb */
|
||||
jbe 2f
|
||||
/* FIXME: do something with page sizes greather than 8KB!! */
|
||||
shll %cl, %edi
|
||||
orl %edi, %esi
|
||||
/* side two */
|
||||
movb $5, %bh
|
||||
CALLSP(smbus_read_byte) /* number of physical banks */
|
||||
cmp $1, %al
|
||||
jbe 2f
|
||||
/* for now only handle the symmtrical case */
|
||||
shll $2, %edi
|
||||
shll %cl, %edi
|
||||
orl %edi, %esi
|
||||
|
||||
2: addl $1, %ebx /* increment the device */
|
||||
addl $4, %ecx /* increment the shift count */
|
||||
cmpb $LAST_SMBUS_MEM_DEVICE, %bl
|
||||
jbe 1b
|
||||
|
||||
movl $0x7f, %eax
|
||||
/* I'm not sure what we should do here. Do nothing. */
|
||||
/* PCI_WRITE_CONFIG_WORD*/
|
||||
RET_LABEL(spd_set_rps)
|
||||
|
||||
/*
|
||||
* Routine: spd_set_pgpol
|
||||
* Arguments: None
|
||||
*
|
||||
* Trashed: %eax, %ebx, %ecx, %edx, %esi, %esp, %eflags
|
||||
* Effects: Uses serial presence detect to set the number of banks
|
||||
* on a given DIMM
|
||||
* Notes: %esi accumulates the banks sizes of all of the DIMMs
|
||||
* %ecx holds the current bit into into %esi
|
||||
* %bl holds the current SMBUS device
|
||||
* FIXME: Check for illegal/unsupported ram configurations and abort
|
||||
*/
|
||||
|
||||
spd_set_pgpol:
|
||||
/* The PGPOL register stores the number of logical banks per DIMM,
|
||||
* and number of clocks the DRAM controller waits in the idle
|
||||
* state.
|
||||
*/
|
||||
/* default all bank counts 2 */
|
||||
xorl %esi, %esi
|
||||
/* Index into %esi of bit to set */
|
||||
movl $0 , %ecx
|
||||
/* Load the smbus device into %ebx */
|
||||
movl $SMBUS_MEM_DEVICE_0, %ebx
|
||||
|
||||
1: movb $17, %bh
|
||||
CALLSP(smbus_read_byte) /* logical banks */
|
||||
jz 2f
|
||||
cmp $0x4, %eax
|
||||
jl 2f
|
||||
movl $0x1, %eax
|
||||
shll %cl, %eax
|
||||
orl %eax, %esi
|
||||
/* side two */
|
||||
movb $5, %bh
|
||||
CALLSP(smbus_read_byte) /* number of physical banks */
|
||||
cmp $1, %al
|
||||
jbe 2f
|
||||
/* for now only handle the symmtrical case */
|
||||
movl $0x2, %eax
|
||||
shll %cl, %eax
|
||||
orl %eax, %esi
|
||||
|
||||
2: addl $1, %ebx /* increment the device */
|
||||
addl $2, %ecx /* increment the shift count */
|
||||
cmpb $LAST_SMBUS_MEM_DEVICE, %bl
|
||||
jbe 1b
|
||||
|
||||
shll $8, %esi
|
||||
orl $0x7, %esi /* 32 clocks idle time */
|
||||
movl %esi, %ecx
|
||||
movl $0x78, %eax
|
||||
/* I'm unclear on the concept for non-intel devices */
|
||||
/* PCI_WRITE_CONFIG_WORD*/
|
||||
RET_LABEL(spd_set_pgpol)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Routine: spd_enable_nbxcfg
|
||||
* Arguments: None
|
||||
*
|
||||
* Trashed: %eax, %ebx, %ecx, %edx, %esi, %esp, %eflags
|
||||
* Effects: Uses serial presence detect to set the
|
||||
* ECC support flags in the NBXCFG register
|
||||
* Notes: %esi accumulates the ECC support of the individual DIMMs.
|
||||
* %ecx holds the bit that should be flipped for the current DIMM.
|
||||
* %bl holds the smbus device that corresponds to the current DIMM.
|
||||
* FIXME: Check for illegal/unsupported ram configurations and abort
|
||||
*/
|
||||
|
||||
spd_set_nbxcfg:
|
||||
/* say all dimms have no ECC support */
|
||||
movl $0xFF, %esi
|
||||
/* Index into %esi of bit to set */
|
||||
movl $0 , %ecx
|
||||
/* Load the smbus device into %ebx */
|
||||
movl $SMBUS_MEM_DEVICE_0, %ebx
|
||||
|
||||
1: movb $11, %bh
|
||||
CALLSP(smbus_read_byte) /* module error correction type */
|
||||
jz 2f
|
||||
cmp $0x2, %eax /* 0 == None, 1 == Parity, 2 == ECC */
|
||||
jne 2f
|
||||
movl $0x1, %eax
|
||||
shll %cl, %eax
|
||||
xorl %eax, %esi
|
||||
|
||||
/* side two */
|
||||
movb $5, %bh
|
||||
CALLSP(smbus_read_byte) /* number of physical banks */
|
||||
cmp $1, %al
|
||||
jbe 2f
|
||||
/* The only is the symmtrical case */
|
||||
movl $0x2, %eax
|
||||
shll %cl, %eax
|
||||
xorl %eax, %esi
|
||||
|
||||
2: addl $1, %ebx /* increment the device */
|
||||
addl $2, %ecx /* increment the shift count */
|
||||
cmpb $LAST_SMBUS_MEM_DEVICE, %bl
|
||||
jbe 1b
|
||||
|
||||
movl %esi, %edx
|
||||
/* at some point, we need to indicate how to turn ECC on. Not yet.
|
||||
movl $0x53, %eax
|
||||
PCI_WRITE_CONFIG_BYTE
|
||||
*/
|
||||
RET_LABEL(spd_set_nbxcfg)
|
||||
|
||||
|
||||
|
||||
smbus_pcibus_end:
|
||||
CALL_LABEL(enable_smbus)
|
||||
CALL_LABEL(setup_smbus)
|
||||
|
||||
|
||||
smbus_end:
|
||||
CALL_LABEL(smbus_setup)
|
||||
|
|
|
|||
9
src/southbridge/intel/82801ca/watchdog_disable.inc
Normal file
9
src/southbridge/intel/82801ca/watchdog_disable.inc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* Disable the TCO watch dog timer in the southbridge */
|
||||
/* bridge 0, device 1f, function 0, byte d4, bit 1 */
|
||||
|
||||
movl $0x8000f8d4,%eax
|
||||
movl $0x0cf8,%edx
|
||||
outl %eax,%dx
|
||||
movl $0x0cfc,%edx
|
||||
movb $2,%al
|
||||
outb %al,%dx
|
||||
|
|
@ -19,30 +19,31 @@
|
|||
outb %al, $(SIO_BASE)
|
||||
|
||||
#define SIO_WRITE_CONFIG(value, reg) \
|
||||
movb $reg, %al ; \
|
||||
movb reg, %al ; \
|
||||
outb %al, $(SIO_INDEX) ; \
|
||||
movb $value, %al ; \
|
||||
movb value, %al ; \
|
||||
outb %al, $(SIO_DATA)
|
||||
|
||||
#define SIO_READ_CONFIG(value, reg) \
|
||||
movb $reg, %al ; \
|
||||
#define SIO_READ_CONFIG(reg) \
|
||||
movb reg, %al ; \
|
||||
outb %al, $(SIO_INDEX) ; \
|
||||
inb %al, $(SIO_DATA)
|
||||
inb $(SIO_DATA), %al
|
||||
|
||||
#define SIO_SET_LOGICAL_DEVICE(device) \
|
||||
SIO_WRITE_CONFIG(device, 0x07)
|
||||
SIO_WRITE_CONFIG(device, $0x07)
|
||||
|
||||
|
||||
/* Enable pnp */
|
||||
SIO_ENTER_PNP_MODE()
|
||||
|
||||
#if defined(SIO_SYSTEM_CLK_INPUT)
|
||||
/* Setup up the clock input */
|
||||
SIO_WRITE_CONFIG((0x84 | SIO_SYSTEM_CLK_INPUT), 0x24)
|
||||
SIO_WRITE_CONFIG($(0x84 | SIO_SYSTEM_CLK_INPUT), $0x24)
|
||||
#endif
|
||||
/* enable serial 1 */
|
||||
SIO_SET_LOGICAL_DEVICE(COM1_DEVICE)
|
||||
SIO_WRITE_CONFIG(1, 0x30)
|
||||
SIO_WRITE_CONFIG(0x3, 0x60)
|
||||
SIO_WRITE_CONFIG(0xf8, 0x61)
|
||||
SIO_SET_LOGICAL_DEVICE($COM1_DEVICE)
|
||||
SIO_WRITE_CONFIG($1, $0x30)
|
||||
SIO_WRITE_CONFIG($0x3, $0x60)
|
||||
SIO_WRITE_CONFIG($0xf8, $0x61)
|
||||
SIO_EXIT_PNP_MODE()
|
||||
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ def nsuperio(dir, superio_commands):
|
|||
superio_decls = superio_decls + decl;
|
||||
superio_devices.append("&superio_" + superio_decl_name);
|
||||
# note that we're using the new interface
|
||||
option(dir, "USE_NEW_SUPERIO_INTERFACE")
|
||||
option(dir, "USE_NEW_SUPERIO_INTERFACE=1")
|
||||
numsuperio = numsuperio + 1
|
||||
|
||||
|
||||
|
|
@ -705,6 +705,10 @@ def option(dir, option):
|
|||
value = ""
|
||||
if m and m.group(1):
|
||||
(key, value) = m.groups()
|
||||
else:
|
||||
warning("Invalid option specifcation: %s assuming you meant %s=1" %
|
||||
(option, option) )
|
||||
value = "1"
|
||||
m = option_re.match(key)
|
||||
if not m:
|
||||
fatal("Invalid option name: %s" % (key))
|
||||
|
|
|
|||
|
|
@ -12,22 +12,36 @@ void print_lb_records(struct lb_record *rec, struct lb_record *last, unsigned lo
|
|||
|
||||
unsigned long compute_checksum(void *addr, unsigned long length)
|
||||
{
|
||||
unsigned short *ptr;
|
||||
uint8_t *ptr;
|
||||
volatile union {
|
||||
uint8_t byte[2];
|
||||
uint16_t word;
|
||||
} value;
|
||||
unsigned long sum;
|
||||
unsigned long len;
|
||||
/* Assumes len is a multiple of two, and addr is 2 byte aligned. */
|
||||
/* compute an ip style checksum */
|
||||
unsigned long i;
|
||||
/* In the most straight forward way possible,
|
||||
* compute an ip style checksum.
|
||||
*/
|
||||
sum = 0;
|
||||
len = length >> 1;
|
||||
ptr = addr;
|
||||
while (len--) {
|
||||
sum += *(ptr++);
|
||||
if (sum > 0xFFFF)
|
||||
sum -= 0xFFFF;
|
||||
for(i = 0; i < length; i++) {
|
||||
unsigned long value;
|
||||
value = ptr[i];
|
||||
if (i & 1) {
|
||||
value <<= 8;
|
||||
}
|
||||
/* Add the new value */
|
||||
sum += value;
|
||||
/* Wrap around the carry */
|
||||
if (sum > 0xFFFF) {
|
||||
sum = (sum + (sum >> 16)) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
return (~sum) & 0xFFFF;
|
||||
|
||||
value.byte[0] = sum & 0xff;
|
||||
value.byte[1] = (sum >> 8) & 0xff;
|
||||
return (~value.word) & 0xFFFF;
|
||||
}
|
||||
|
||||
#define for_each_lbrec(head, rec) \
|
||||
for(rec = (struct lb_record *)(((char *)head) + sizeof(*head)); \
|
||||
(((char *)rec) < (((char *)head) + sizeof(*head) + head->table_bytes)) && \
|
||||
|
|
@ -157,8 +171,17 @@ void print_mainboard(struct lb_record *ptr, unsigned long addr)
|
|||
rec = (struct lb_mainboard *)ptr;
|
||||
max_size = rec->size - sizeof(*rec);
|
||||
printf("vendor: %.*s part number: %.*s\n",
|
||||
max_size - rec->vendor_idx, rec->strings + rec->vendor_idx,
|
||||
max_size - rec->vendor_idx, rec->strings + rec->part_number_idx);
|
||||
max_size - rec->vendor_idx, rec->strings + rec->vendor_idx,
|
||||
max_size - rec->part_number_idx, rec->strings + rec->part_number_idx);
|
||||
}
|
||||
|
||||
void print_string(struct lb_record *ptr, unsigned long addr)
|
||||
{
|
||||
struct lb_string *rec;
|
||||
int max_size;
|
||||
rec = (struct lb_string *)ptr;
|
||||
max_size = rec->size - sizeof(*rec);
|
||||
printf("%.*s\n", max_size, rec->string);
|
||||
}
|
||||
|
||||
void print_option_table(struct lb_record *ptr, unsigned long addr)
|
||||
|
|
@ -213,6 +236,16 @@ struct {
|
|||
{ LB_TAG_MEMORY, "Memory", print_memory },
|
||||
{ LB_TAG_HWRPB, "HWRPB", nop_print },
|
||||
{ LB_TAG_MAINBOARD, "Mainboard", print_mainboard },
|
||||
{ LB_TAG_VERSION, "Version", print_string },
|
||||
{ LB_TAG_EXTRA_VERSION, "Extra Version", print_string },
|
||||
{ LB_TAG_BUILD, "Build", print_string },
|
||||
{ LB_TAG_COMPILE_TIME, "Compile Time", print_string },
|
||||
{ LB_TAG_COMPILE_BY, "Compile By", print_string },
|
||||
{ LB_TAG_COMPILE_HOST, "Compile Host", print_string },
|
||||
{ LB_TAG_COMPILE_DOMAIN, "Compile Domain", print_string },
|
||||
{ LB_TAG_COMPILER, "Compiler", print_string },
|
||||
{ LB_TAG_LINKER, "Linker", print_string },
|
||||
{ LB_TAG_ASSEMBLER, "Assembler", print_string },
|
||||
{ LB_TAG_CMOS_OPTION_TABLE, "CMOS option table", print_option_table },
|
||||
{ LB_TAG_OPTION, "Option", print_option },
|
||||
{ LB_TAG_OPTION_ENUM, "Option Enumeration", print_option_enumeration },
|
||||
|
|
|
|||
5
util/mkelfImage/News
Normal file
5
util/mkelfImage/News
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
1.14
|
||||
|
||||
- Use much less complex ld magic
|
||||
- Fix a small bug in the LinuxBIOS checksum verification code
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue