diff -Nru a/Documentation/DocBook/gadget.tmpl b/Documentation/DocBook/gadget.tmpl
--- a/Documentation/DocBook/gadget.tmpl Mon Jun 2 04:30:16 2003
+++ b/Documentation/DocBook/gadget.tmpl Wed Jun 18 04:39:17 2003
@@ -6,31 +6,32 @@
02 June 2003
- Permission is granted to copy, distribute, and/or modify
- this document under the terms of the GNU Free Documentation
- License, version 1.2, or any later version published by the
- Free Software Foundation; with the Invariant Sections being
- the "GNU Free Documentation License",
- no Front-Cover Texts,
- and
- no Back-Cover Texts.
-
-
- This documentation 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 Free Documentation License for more details.
-
-
- Note that certain sections of this document are merged
- into Linux kernel source code.
- That content is the bulk of
- and
- ,
- where the "GNU Free Documentation License" is identified
- as an alternate licence for its documentation.
-
-
+
+ This documentation 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., 59 Temple Place, Suite 330, Boston,
+ MA 02111-1307 USA
+
+
+
+ For more details see the file COPYING in the source
+ distribution of Linux.
+ 2003
@@ -325,9 +326,10 @@
of one or more "packets", and packet boundaries are visible to drivers.
Compared to RS-232 serial protocols, USB resembles
synchronous protocols like HDLC
-(N bytes per frame, multipoint addressing from the host)
+(N bytes per frame, multipoint addressing, host as the primary
+station and devices as secondary stations)
more than asynchronous ones
-(tty style, like 8 bytes, no parity, one stop bit).
+(tty style: 8 data bits per frame, no parity, one stop bit).
So for example the controller drivers won't buffer
two single byte writes into a single two-byte USB IN packet,
although gadget drivers may do so when they implement
@@ -527,438 +529,6 @@
-
-
-GNU Free Documentation License
-Version 1.2, November 2002
-
-
- Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
-59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
-
-
-PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or
-other functional and useful document "free" in the sense of freedom: to
-assure everyone the effective freedom to copy and redistribute it, with
-or without modifying it, either commercially or noncommercially.
-Secondarily, this License preserves for the author and publisher a way
-to get credit for their work, while not being considered responsible for
-modifications made by others.
-
-This License is a kind of "copyleft", which means that derivative
-works of the document must themselves be free in the same sense. It
-complements the GNU General Public License, which is a copyleft license
-designed for free software.
-
-We have designed this License in order to use it for manuals for
-free software, because free software needs free documentation: a free
-program should come with manuals providing the same freedoms that the
-software does. But this License is not limited to software manuals; it
-can be used for any textual work, regardless of subject matter or
-whether it is published as a printed book. We recommend this License
-principally for works whose purpose is instruction or reference.
-
-
-APPLICABILITY AND DEFINITIONS
-
-This License applies to any manual or other work, in
-any medium, that contains a notice placed by the copyright holder saying
-it can be distributed under the terms of this License. Such a notice
-grants a world-wide, royalty-free license, unlimited in duration, to use
-that work under the conditions stated herein. The "Document", below,
-refers to any such manual or work. Any member of the public is a
-licensee, and is addressed as "you". You accept the license if you
-copy, modify or distribute the work in a way requiring permission under
-copyright law.
-
-A "Modified Version" of the Document means any
-work containing the Document or a portion of it, either copied verbatim,
-or with modifications and/or translated into another language.
-
-A "Secondary Section" is a named appendix or
-a front-matter section of the Document that deals exclusively with the
-relationship of the publishers or authors of the Document to the
-Document's overall subject (or to related matters) and contains nothing
-that could fall directly within that overall subject. (Thus, if the
-Document is in part a textbook of mathematics, a Secondary Section may
-not explain any mathematics.) The relationship could be a matter of
-historical connection with the subject or with related matters, or of
-legal, commercial, philosophical, ethical or political position
-regarding them.
-
-The "Invariant Sections" are certain Secondary
-Sections whose titles are designated, as being those of Invariant
-Sections, in the notice that says that the Document is released under
-this License. If a section does not fit the above definition of
-Secondary then it is not allowed to be designated as Invariant. The
-Document may contain zero Invariant Sections. If the Document does not
-identify any Invariant Sections then there are none.
-
-The "Cover Texts" are certain short passages of
-text that are listed, as Front-Cover Texts or Back-Cover Texts, in the
-notice that says that the Document is released under this License. A
-Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at
-most 25 words.
-
-A "Transparent" copy of the Document means a
-machine-readable copy, represented in a format whose specification is
-available to the general public, that is suitable for revising the
-document straightforwardly with generic text editors or (for images
-composed of pixels) generic paint programs or (for drawings) some widely
-available drawing editor, and that is suitable for input to text
-formatters or for automatic translation to a variety of formats suitable
-for input to text formatters. A copy made in an otherwise Transparent
-file format whose markup, or absence of markup, has been arranged to
-thwart or discourage subsequent modification by readers is not
-Transparent. An image format is not Transparent if used for any
-substantial amount of text. A copy that is not "Transparent" is called
-"Opaque".
-
-Examples of suitable formats for Transparent copies include plain
-ASCII without markup, Texinfo input format, LaTeX input format, SGML or
-XML using a publicly available DTD, and standard-conforming simple HTML,
-PostScript or PDF designed for human modification. Examples of
-transparent image formats include PNG, XCF and JPG. Opaque formats
-include proprietary formats that can be read and edited only by
-proprietary word processors, SGML or XML for which the DTD and/or
-processing tools are not generally available, and the machine-generated
-HTML, PostScript or PDF produced by some word processors for output
-purposes only.
-
-The "Title Page" means, for a printed book,
-the title page itself, plus such following pages as are needed to hold,
-legibly, the material this License requires to appear in the title page.
-For works in formats which do not have any title page as such, "Title
-Page" means the text near the most prominent appearance of the work's
-title, preceding the beginning of the body of the text.
-
-A section "Entitled XYZ" means a named subunit
-of the Document whose title either is precisely XYZ or contains XYZ in
-parentheses following text that translates XYZ in another language.
-(Here XYZ stands for a specific section name mentioned below, such as
-"Acknowledgements", "Dedications", "Endorsements", or "History".) To
-"Preserve the Title" of such a section when you modify the Document
-means that it remains a section "Entitled XYZ" according to this
-definition.
-
-The Document may include Warranty Disclaimers next to the notice
-which states that this License applies to the Document. These Warranty
-Disclaimers are considered to be included by reference in this License,
-but only as regards disclaiming warranties: any other implication that
-these Warranty Disclaimers may have is void and has no effect on the
-meaning of this License.
-
-
-VERBATIM COPYING
-
-You may copy and distribute the Document in any medium, either
-commercially or noncommercially, provided that this License, the
-copyright notices, and the license notice saying this License applies to
-the Document are reproduced in all copies, and that you add no other
-conditions whatsoever to those of this License. You may not use
-technical measures to obstruct or control the reading or further copying
-of the copies you make or distribute. However, you may accept
-compensation in exchange for copies. If you distribute a large enough
-number of copies you must also follow the conditions in section 3.
-
-
-You may also lend copies, under the same conditions stated above,
-and you may publicly display copies.
-
-
-COPYING IN QUANTITY
-
-If you publish printed copies (or copies in media that commonly
-have printed covers) of the Document, numbering more than 100, and the
-Document's license notice requires Cover Texts, you must enclose the
-copies in covers that carry, clearly and legibly, all these Cover Texts:
-Front-Cover Texts on the front cover, and Back-Cover Texts on the back
-cover. Both covers must also clearly and legibly identify you as the
-publisher of these copies. The front cover must present the full title
-with all words of the title equally prominent and visible. You may add
-other material on the covers in addition. Copying with changes limited
-to the covers, as long as they preserve the title of the Document and
-satisfy these conditions, can be treated as verbatim copying in other
-respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute Opaque copies of the Document
-numbering more than 100, you must either include a machine-readable
-Transparent copy along with each Opaque copy, or state in or with each
-Opaque copy a computer-network location from which the general
-network-using public has access to download using public-standard
-network protocols a complete Transparent copy of the Document, free of
-added material. If you use the latter option, you must take reasonably
-prudent steps, when you begin distribution of Opaque copies in quantity,
-to ensure that this Transparent copy will remain thus accessible at the
-stated location until at least one year after the last time you
-distribute an Opaque copy (directly or through your agents or retailers)
-of that edition to the public.
-
-It is requested, but not required, that you contact the authors of
-the Document well before redistributing any large number of copies, to
-give them a chance to provide you with an updated version of the
-Document.
-
-
-MODIFICATIONS
-
-You may copy and distribute a Modified Version of the Document
-under the conditions of sections 2 and 3 above, provided that you
-release the Modified Version under precisely this License, with the
-Modified Version filling the role of the Document, thus licensing
-distribution and modification of the Modified Version to whoever
-possesses a copy of it. In addition, you must do these things in the
-Modified Version:
-
-
-Use in the Title Page (and on the covers, if any) a
- title distinct from that of the Document, and from those of previous
- versions (which should, if there were any, be listed in the History
- section of the Document). You may use the same title as a previous
- version if the original publisher of that version gives permission.
-
-List on the Title Page, as authors, one or more
- persons or entities responsible for authorship of the modifications in
- the Modified Version, together with at least five of the principal
- authors of the Document (all of its principal authors, if it has fewer
- than five), unless they release you from this requirement.
-
-State on the Title page the name of the publisher of
- the Modified Version, as the publisher.
-Preserve all the copyright notices of the Document.
-
-Add an appropriate copyright notice for your
- modifications adjacent to the other copyright notices.
-
-Include, immediately after the copyright notices, a
- license notice giving the public permission to use the Modified
- Version under the terms of this License, in the form shown in the
- Addendum below.
-
-Preserve in that license notice the full lists of
- Invariant Sections and required Cover Texts given in the Document's
- license notice.
-Include an unaltered copy of this License.
-
-Preserve the section Entitled "History", Preserve its
- Title, and add to it an item stating at least the title, year, new
- authors, and publisher of the Modified Version as given on the Title
- Page. If there is no section Entitled "History" in the Document,
- create one stating the title, year, authors, and publisher of the
- Document as given on its Title Page, then add an item describing the
- Modified Version as stated in the previous sentence.
-
-Preserve the network location, if any, given in the
- Document for public access to a Transparent copy of the Document, and
- likewise the network locations given in the Document for previous
- versions it was based on. These may be placed in the "History"
- section. You may omit a network location for a work that was
- published at least four years before the Document itself, or if the
- original publisher of the version it refers to gives permission.
-
-For any section Entitled "Acknowledgements" or
- "Dedications", Preserve the Title of the section, and preserve in the
- section all the substance and tone of each of the contributor
- acknowledgements and/or dedications given therein.
-
-Preserve all the Invariant Sections of the Document,
- unaltered in their text and in their titles. Section numbers or the
- equivalent are not considered part of the section titles.
-
-Delete any section Entitled "Endorsements".
- Such a section may not be included in the Modified Version.
-
-Do not retitle any existing section to be Entitled
- "Endorsements" or to conflict in title with any Invariant Section.
-
-Preserve any Warranty Disclaimers.
-
-
-
-If the Modified Version includes new front-matter sections or
-appendices that qualify as Secondary Sections and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
-These titles must be distinct from any other section titles.
-
-You may add a section Entitled "Endorsements", provided it
-contains nothing but endorsements of your Modified Version by various
-parties--for example, statements of peer review or that the text has
-been approved by an organization as the authoritative definition of a
-standard.
-
-You may add a passage of up to five words as a Front-Cover Text,
-and a passage of up to 25 words as a Back-Cover Text, to the end of the
-list of Cover Texts in the Modified Version. Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or through
-arrangements made by) any one entity. If the Document already includes
-a cover text for the same cover, previously added by you or by
-arrangement made by the same entity you are acting on behalf of, you may
-not add another; but you may replace the old one, on explicit permission
-from the previous publisher that added the old one.
-
-The author(s) and publisher(s) of the Document do not by this
-License give permission to use their names for publicity for or to
-assert or imply endorsement of any Modified Version.
-
-
-COMBINING DOCUMENTS
-
-You may combine the Document with other documents released under
-this License, under the terms defined in section
-4 above for modified versions, provided that you include in the
-combination all of the Invariant Sections of all of the original
-documents, unmodified, and list them all as Invariant Sections of your
-combined work in its license notice, and that you preserve all their
-Warranty Disclaimers.
-
-The combined work need only contain one copy of this License, and
-multiple identical Invariant Sections may be replaced with a single
-copy. If there are multiple Invariant Sections with the same name but
-different contents, make the title of each such section unique by adding
-at the end of it, in parentheses, the name of the original author or
-publisher of that section if known, or else a unique number. Make the
-same adjustment to the section titles in the list of Invariant Sections
-in the license notice of the combined work.
-
-In the combination, you must combine any sections Entitled
-"History" in the various original documents, forming one section
-Entitled "History"; likewise combine any sections Entitled
-"Acknowledgements", and any sections Entitled "Dedications". You must
-delete all sections Entitled "Endorsements".
-
-
-COLLECTIONS OF DOCUMENTS
-
-You may make a collection consisting of the Document and other
-documents released under this License, and replace the individual copies
-of this License in the various documents with a single copy that is
-included in the collection, provided that you follow the rules of this
-License for verbatim copying of each of the documents in all other
-respects.
-
-You may extract a single document from such a collection, and
-distribute it individually under this License, provided you insert a
-copy of this License into the extracted document, and follow this
-License in all other respects regarding verbatim copying of that
-document.
-
-
-AGGREGATION WITH INDEPENDENT WORKS
-
-A compilation of the Document or its derivatives with other
-separate and independent documents or works, in or on a volume of a
-storage or distribution medium, is called an "aggregate" if the
-copyright resulting from the compilation is not used to limit the legal
-rights of the compilation's users beyond what the individual works
-permit. When the Document is included an aggregate, this License does
-not apply to the other works in the aggregate which are not themselves
-derivative works of the Document.
-
-If the Cover Text requirement of section 3 is applicable to these
-copies of the Document, then if the Document is less than one half of
-the entire aggregate, the Document's Cover Texts may be placed on covers
-that bracket the Document within the aggregate, or the electronic
-equivalent of covers if the Document is in electronic form. Otherwise
-they must appear on printed covers that bracket the whole
-aggregate.
-
-
-TRANSLATION
-
-Translation is considered a kind of modification, so you may
-distribute translations of the Document under the terms of section 4.
-Replacing Invariant Sections with translations requires special
-permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections. You may include a
-translation of this License, and all the license notices in the
-Document, and any Warranty Disclaimers, provided that you also include
-the original English version of this License and the original versions
-of those notices and disclaimers. In case of a disagreement between the
-translation and the original version of this License or a notice or
-disclaimer, the original version will prevail.
-
-If a section in the Document is Entitled "Acknowledgements",
-"Dedications", or "History", the requirement (section 4) to Preserve its
-Title (section 1) will typically require changing the actual
-title.
-
-
-TERMINATION
-
-You may not copy, modify, sublicense, or distribute the Document
-except as expressly provided for under this License. Any other attempt
-to copy, modify, sublicense or distribute the Document 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.
-
-
-FUTURE REVISIONS OF THIS LICENSE
-
-The Free Software Foundation may publish new, revised versions of
-the GNU Free Documentation 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. See
-http://www.gnu.org/copyleft/.
-
-Each version of the License is given a distinguishing version
-number. If the Document specifies that a particular numbered version of
-this License "or any later version" applies to it, you have the option
-of following the terms and conditions either of that specified version
-or of any later version that has been published (not as a draft) by the
-Free Software Foundation. If the Document does not specify a version
-number of this License, you may choose any version ever published (not
-as a draft) by the Free Software Foundation.
-
-
-ADDENDUM: How to use this License for
- your documents
-
-To use this License in a document you have written, include a copy
-of the License in the document and put the following copyright and
-license notices just after the title page:
-
-
- Copyright (c) YEAR YOUR NAME.
- Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.2
- or any later version published by the Free Software Foundation;
- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
- A copy of the license is included in the section entitled "GNU
- Free Documentation License".
-
-
-If you have Invariant Sections, Front-Cover Texts and Back-Cover
-Texts, replace the "with...Texts." line with this:
-
-
- with the Invariant Sections being LIST THEIR TITLES, with the
- Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
-
-
-If you have Invariant Sections without Cover Texts, or some other
-combination of the three, merge those two alternatives to suit the
-situation.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of free
-software license, such as the GNU General Public License, to permit
-their use in free software.
-
-
physical translation.
*/
page = ioaddr & PAGE_MASK;
@@ -50,7 +49,7 @@
return 0;
}
-static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address,
+static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address,
unsigned long size, unsigned long ioaddr)
{
unsigned long end;
diff -Nru a/arch/mips/baget/bagetIRQ.S b/arch/mips/baget/bagetIRQ.S
--- a/arch/mips/baget/bagetIRQ.S Tue Feb 5 09:40:24 2002
+++ b/arch/mips/baget/bagetIRQ.S Mon Apr 14 20:10:11 2003
@@ -1,9 +1,8 @@
-/* $Id: bagetIRQ.S,v 1.1 1999/01/17 03:49:37 ralf Exp $
+/*
* bagetIRQ.S: Interrupt exception dispatch code for Baget/MIPS
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*/
-
#include
#include
#include
@@ -25,28 +24,28 @@
.set push
.set noreorder
jal a1
- .set pop
- move a0, sp
+ .set pop
+ move a0, sp
la a1, ret_from_irq
jr a1
END(bagetIRQ)
-
+
#define DBE_HANDLER 0x1C
-
+
NESTED(try_read, PT_SIZE, sp)
mfc0 t3, CP0_STATUS # save flags and
CLI # disable interrupts
li t0, KSEG2
- sltu t1, t0, a0 # Is it KSEG2 address ?
- beqz t1, mapped # No - already mapped !
-
- move t0, a0
+ sltu t1, t0, a0 # Is it KSEG2 address ?
+ beqz t1, mapped # No - already mapped !
+
+ move t0, a0
ori t0, 0xfff
xori t0, 0xfff # round address to page
- ori t1, t0, 0xf00 # prepare EntryLo (N,V,D,G)
+ ori t1, t0, 0xf00 # prepare EntryLo (N,V,D,G)
mfc0 t2, CP0_ENTRYHI # save ASID value
mtc0 zero, CP0_INDEX
@@ -57,15 +56,15 @@
tlbwi # ... and write ones
nop
nop
- mtc0 t2, CP0_ENTRYHI
-
-mapped:
+ mtc0 t2, CP0_ENTRYHI
+
+mapped:
la t0, exception_handlers
lw t1, DBE_HANDLER(t0) # save real handler
- la t2, dbe_handler
+ la t2, dbe_handler
sw t2, DBE_HANDLER(t0) # set temporary local handler
li v0, -1 # default (failure) value
-
+
li t2, 1
beq t2, a1, 1f
li t2, 2
@@ -81,13 +80,13 @@
b out
4: lw v0, (a0) # word
-
-out:
+
+out:
sw t1, DBE_HANDLER(t0) # restore real handler
mtc0 t3, CP0_STATUS # restore CPU flags
- jr ra
-
-dbe_handler:
+ jr ra
+
+dbe_handler:
li v0, -1 # mark our failure
.set push
.set noreorder
diff -Nru a/arch/mips/baget/balo.c b/arch/mips/baget/balo.c
--- a/arch/mips/baget/balo.c Tue Feb 5 09:40:24 2002
+++ b/arch/mips/baget/balo.c Mon Apr 14 20:10:11 2003
@@ -1,9 +1,7 @@
-/* $Id$
- *
+/*
* balo.c: BAget LOader
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- *
*/
#include
#include
@@ -18,7 +16,7 @@
static void mem_move (long *to, long *from, long size)
{
- while (size > 0) {
+ while (size > 0) {
*to++ = *from++;
size -= sizeof(long);
}
@@ -42,27 +40,29 @@
static __inline__ void reset_and_jump(int start, int mem_upper)
{
+ unsigned long tmp;
+
__asm__ __volatile__(
".set\tnoreorder\n\t"
".set\tnoat\n\t"
- "mfc0\t$1,$12\n\t"
+ "mfc0\t$1, $12\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
- "ori\t$1,$1,0xff00\n\t"
- "xori\t$1,$1,0xff00\n\t"
- "mtc0\t$1,$12\n\t"
+ "ori\t$1, $1, 0xff00\n\t"
+ "xori\t$1, $1, 0xff00\n\t"
+ "mtc0\t$1, $12\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
- "move\t$4,%1\n\t"
- "jr\t%0\n\t"
+ "move\t%0, %2\n\t"
+ "jr\t%1\n\t"
"nop\n\t"
".set\tat\n\t"
- ".set\treorder"
- : /* no outputs */
- :"Ir" (start), "Ir" (mem_upper)
- :"$1", "$4", "memory");
+ ".set\treorder"
+ : "=&r" (tmp)
+ : "Ir" (start), "Ir" (mem_upper)
+ : "memory");
}
static void start_kernel(void)
@@ -71,7 +71,7 @@
extern char _ramdisk_start, _ramdisk_end;
outs( "Relocating Linux... " );
- mem_move((long*)KSEG0, (long*)&_vmlinux_start,
+ mem_move((long*)KSEG0, (long*)&_vmlinux_start,
&_vmlinux_end-&_vmlinux_start);
outs("done.\n");
@@ -86,7 +86,7 @@
outs("done.\n");
}
- {
+ {
extern void flush_cache_low(int isize, int dsize);
flush_cache_low(256*1024,256*1024);
}
@@ -102,10 +102,10 @@
balo_state = MEM_PROBE;
outs("RAM: <");
while(mem_limit < mem_limit_dbe) {
- if (can_write(mem_limit) && *mem_limit != 0)
+ if (can_write(mem_limit) && *mem_limit != 0)
break; /* cycle found */
outc('.');
- if (can_write(mem_limit))
+ if (can_write(mem_limit))
*mem_limit = -1; /* mark */
mem_limit += 0x40000;
}
@@ -124,7 +124,7 @@
}
void int_handler(struct pt_regs *regs)
-{
+{
switch (balo_state) {
case BALO_INIT:
balo_printf("\nBALO: trap in balo itself.\n");
@@ -162,7 +162,7 @@
while(1) {
*mem_limit_dbe;
- if (can_write(mem_limit_dbe))
+ if (can_write(mem_limit_dbe))
*mem_limit_dbe = 0;
mem_limit_dbe += 0x40000; /* +1M */
@@ -174,7 +174,7 @@
{
extern void except_vec3_generic(void);
- cli();
+ cli();
outs(banner);
memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80);
mem_init();
diff -Nru a/arch/mips/baget/balo_supp.S b/arch/mips/baget/balo_supp.S
--- a/arch/mips/baget/balo_supp.S Tue Feb 5 09:40:24 2002
+++ b/arch/mips/baget/balo_supp.S Mon Apr 14 20:10:11 2003
@@ -1,18 +1,17 @@
-/* $Id: balo_supp.S,v 1.1 1999/01/17 03:49:38 ralf Exp $
+/*
* balo_supp.S: BAget Loader supplement
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*/
-
#include
#include
#include
#include
#include
-
+
.text
.set mips1
-
+
/* General exception vector. */
NESTED(except_vec3_generic, 0, sp)
.set noat
@@ -21,7 +20,7 @@
END(except_vec3_generic)
NESTED(except_vec3_generic_code, 0, sp)
- SAVE_ALL
+ SAVE_ALL
mfc0 k1, CP0_CAUSE
la k0, int_cause
sw k1, (k0)
@@ -34,7 +33,7 @@
la k0, badvaddr
sw k1, (k0)
- la k0, int_handler
+ la k0, int_handler
.set noreorder
jal k0
.set reorder
@@ -48,7 +47,7 @@
.set at
.set macro
.set noreorder
-
+
move t1, a0 # ISIZE
move t2, a1 # DSIZE
@@ -89,7 +88,7 @@
sb zero, -8(t0)
bne t0, t1, 1b
sb zero, -4(t0)
-
+
la v0, 1f
or v0, KSEG1
j v0 # Run uncached
diff -Nru a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c
--- a/arch/mips/baget/irq.c Sat Mar 8 14:50:43 2003
+++ b/arch/mips/baget/irq.c Sun Jun 15 16:54:30 2003
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include
#include
@@ -28,24 +27,24 @@
#include
-unsigned long spurious_count = 0;
+volatile unsigned long irq_err_count;
/*
* This table is a correspondence between IRQ numbers and CPU PILs
*/
-
-static int irq_to_pil_map[BAGET_IRQ_NR] = {
+
+static int irq_to_pil_map[BAGET_IRQ_NR] = {
7/*fixme: dma_err -1*/,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0x00 - 0x0f */
-1,-1,-1,-1, 3,-1,-1,-1, 2, 2, 2,-1, 3,-1,-1,3/*fixme: lance*/, /* 0x10 - 0x1f */
-1,-1,-1,-1,-1,-1, 5,-1,-1,-1,-1,-1, 7,-1,-1,-1, /* 0x20 - 0x2f */
-1, 3, 2/*fixme systimer:3*/, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 /* 0x30 - 0x3f */
};
-static inline int irq_to_pil(int irq_nr)
+static inline int irq_to_pil(int irq_nr)
{
int pil = -1;
- if (irq_nr >= BAGET_IRQ_NR)
+ if (irq_nr >= BAGET_IRQ_NR)
baget_printk("irq_to_pil: too large irq_nr = 0x%x\n", irq_nr);
else {
pil = irq_to_pil_map[irq_nr];
@@ -60,13 +59,13 @@
static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
{
- unsigned long status = read_32bit_cp0_register(CP0_STATUS);
+ unsigned long status = read_c0_status();
status &= ~((clr_mask & 0xFF) << 8);
status |= (set_mask & 0xFF) << 8;
- write_32bit_cp0_register(CP0_STATUS, status);
+ write_c0_status(status);
}
-/*
+/*
* These two functions may be used for unconditional IRQ
* masking via their PIL protection.
*/
@@ -92,26 +91,26 @@
static volatile unsigned int pil_in_use[BAGET_PIL_NR] = { 0, };
-void mask_irq_count(int irq_nr)
+void mask_irq_count(int irq_nr)
{
unsigned long flags;
int pil = irq_to_pil(irq_nr);
-
- save_and_cli(flags);
+
+ local_irq_save(flags);
if (!--pil_in_use[pil])
mask_irq(irq_nr);
- restore_flags(flags);
+ local_irq_restore(flags);
}
-void unmask_irq_count(int irq_nr)
+void unmask_irq_count(int irq_nr)
{
unsigned long flags;
int pil = irq_to_pil(irq_nr);
-
- save_and_cli(flags);
+
+ local_irq_save(flags);
if (!pil_in_use[pil]++)
unmask_irq(irq_nr);
- restore_flags(flags);
+ local_irq_restore(flags);
}
/*
@@ -122,18 +121,18 @@
{
unsigned long flags;
- save_and_cli(flags);
+ local_irq_save(flags);
mask_irq(irq_nr);
- restore_flags(flags);
+ local_irq_restore(flags);
}
void enable_irq(unsigned int irq_nr)
{
unsigned long flags;
- save_and_cli(flags);
+ local_irq_save(flags);
unmask_irq(irq_nr);
- restore_flags(flags);
+ local_irq_restore(flags);
}
/*
@@ -142,31 +141,31 @@
*/
static struct irqaction *irq_action[BAGET_IRQ_NR] = { NULL, };
-int show_interrupts(struct seq_file *p, void *v)
+int get_irq_list(char *buf)
{
- int i;
+ int i, len = 0;
struct irqaction * action;
unsigned long flags;
for (i = 0 ; i < BAGET_IRQ_NR ; i++) {
local_irq_save(flags);
action = irq_action[i];
- if (!action)
- goto skip;
- seq_printf(p, "%2d: %8d %c %s",
+ if (!action)
+ gotos skip;
+ len += sprintf(buf+len, "%2d: %8d %c %s",
i, kstat_cpu(0).irqs[i],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
for (action=action->next; action; action = action->next) {
- seq_printf(p, ",%s %s",
+ len += sprintf(buf+len, ",%s %s",
(action->flags & SA_INTERRUPT) ? " +" : "",
action->name);
}
- seq_putc(p, '\n');
+ len += sprintf(buf+len, "\n");
skip:
local_irq_restore(flags);
}
- return 0;
+ return len;
}
@@ -183,10 +182,10 @@
int do_random, cpu;
cpu = smp_processor_id();
- irq_enter(cpu, irq);
- kstat_cpu(cpu).irqs[irq]++;
+ irq_enter();
+ kstat_cpus(cpu)[irq]++;
- mask_irq(irq);
+ mask_irq(irq);
action = *(irq + irq_action);
if (action) {
if (!(action->flags & SA_INTERRUPT))
@@ -205,7 +204,7 @@
printk("do_IRQ: Unregistered IRQ (0x%X) occurred\n", irq);
}
unmask_irq(irq);
- irq_exit(cpu, irq);
+ irq_exit();
/* unmasking and bottom half handling is done magically for us. */
}
@@ -213,14 +212,14 @@
/*
* What to do in case of 'no VIC register available' for current interrupt
*/
-static void vic_reg_error(unsigned long address, unsigned char active_pils)
+static void vic_reg_error(unsigned long address, unsigned char active_pils)
{
printk("\nNo VIC register found: reg=%08lx active_pils=%02x\n"
- "Current interrupt mask from CP0_CAUSE: %02x\n",
- address, 0xff & active_pils,
- 0xff & (read_32bit_cp0_register(CP0_CAUSE)>>8));
+ "Current interrupt mask from CP0_CAUSE: %02x\n",
+ address, 0xff & active_pils,
+ 0xff & (read_c0_cause()>>8));
{ int i; for (i=0; i<10000; i++) udelay(1000); }
-}
+}
static char baget_fpu_irq = BAGET_FPU_IRQ;
#define BAGET_INT_FPU {(unsigned long)&baget_fpu_irq, 1}
@@ -230,27 +229,27 @@
*/
asmlinkage void baget_interrupt(struct pt_regs *regs)
{
- static struct baget_int_reg int_reg[BAGET_PIL_NR] = {
+ static struct baget_int_reg int_reg[BAGET_PIL_NR] = {
BAGET_INT_NONE, BAGET_INT_NONE, BAGET_INT0_ACK, BAGET_INT1_ACK,
- BAGET_INT_NONE, BAGET_INT_FPU, BAGET_INT_NONE, BAGET_INT5_ACK
+ BAGET_INT_NONE, BAGET_INT_FPU, BAGET_INT_NONE, BAGET_INT5_ACK
};
unsigned char active_pils;
- while ((active_pils = read_32bit_cp0_register(CP0_CAUSE)>>8)) {
+ while ((active_pils = read_c0_cause()>>8)) {
int pil;
struct baget_int_reg* reg;
for (pil = 0; pil < BAGET_PIL_NR; pil++) {
if (!(active_pils & (1<address) {
extern int try_read(unsigned long,int);
int irq = try_read(reg->address, reg->size);
- if (irq != -1)
+ if (irq != -1)
do_IRQ(BAGET_IRQ_MASK(irq), regs);
- else
+ else
vic_reg_error(reg->address, active_pils);
} else {
printk("baget_interrupt: unknown interrupt "
@@ -291,9 +290,9 @@
if (new->flags & SA_SAMPLE_RANDOM)
rand_initialize_irq(irq);
- save_and_cli(flags);
+ local_irq_save(flags);
*p = new;
- restore_flags(flags);
+ local_irq_restore(flags);
if (!shared) {
unmask_irq_count(irq);
@@ -302,9 +301,9 @@
return 0;
}
-int request_irq(unsigned int irq,
+int request_irq(unsigned int irq,
void (*handler)(int, void *, struct pt_regs *),
- unsigned long irqflags,
+ unsigned long irqflags,
const char * devname,
void *dev_id)
{
@@ -315,12 +314,12 @@
return -EINVAL;
if (!handler)
return -EINVAL;
- if (irq_to_pil_map[irq] < 0)
+ if (irq_to_pil_map[irq] < 0)
return -EINVAL;
action = (struct irqaction *)
kmalloc(sizeof(struct irqaction), GFP_KERNEL);
- if (!action)
+ if (!action)
return -ENOMEM;
action->handler = handler;
@@ -337,13 +336,13 @@
return retval;
}
-
+
void free_irq(unsigned int irq, void *dev_id)
{
struct irqaction * action, **p;
unsigned long flags;
- if (irq >= BAGET_IRQ_NR)
+ if (irq >= BAGET_IRQ_NR)
printk("Trying to free IRQ%d\n",irq);
for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
@@ -351,11 +350,11 @@
continue;
/* Found it - now free it */
- save_and_cli(flags);
+ local_irq_save(flags);
*p = action->next;
if (!irq[irq_action])
unmask_irq_count(irq);
- restore_flags(flags);
+ local_irq_restore(flags);
kfree(action);
return;
}
@@ -380,7 +379,7 @@
*(volatile char*) BAGET_WRERR_ACK = 0;
}
-static struct irqaction irq0 =
+static struct irqaction irq0 =
{ write_err_interrupt, SA_INTERRUPT, 0, "bus write error", NULL, NULL};
void __init init_IRQ(void)
@@ -393,6 +392,6 @@
/* Enable interrupts for pils 2 and 3 (lines 0 and 1) */
modify_cp0_intmask(0, (1<<2)|(1<<3));
- if (setup_baget_irq(0, &irq0) < 0)
+ if (setup_baget_irq(0, &irq0) < 0)
printk("init_IRQ: unable to register write_err irq\n");
}
diff -Nru a/arch/mips/baget/ld.script.balo b/arch/mips/baget/ld.script.balo
--- a/arch/mips/baget/ld.script.balo Mon Feb 4 23:41:17 2002
+++ b/arch/mips/baget/ld.script.balo Mon Apr 14 20:10:11 2003
@@ -1,4 +1,4 @@
-OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_FORMAT("elf32-tradbigmips")
OUTPUT_ARCH(mips)
ENTRY(balo_entry)
SECTIONS
@@ -42,13 +42,13 @@
/* Startup code */
. = ALIGN(4096);
__init_begin = .;
- *(.text.init)
- *(.data.init)
+ *(.text.init)
+ *(.data.init)
. = ALIGN(4096); /* Align double page for init_task_union */
__init_end = .;
- *(.fini)
- *(.reginfo)
+ *(.fini)
+ *(.reginfo)
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. It would
be more correct to do this:
@@ -68,18 +68,18 @@
*(.data)
CONSTRUCTORS
- *(.data1)
+ *(.data1)
_gp = . + 0x8000;
- *(.lit8)
- *(.lit4)
- *(.ctors)
- *(.dtors)
- *(.got.plt) *(.got)
- *(.dynamic)
+ *(.lit8)
+ *(.lit4)
+ *(.ctors)
+ *(.dtors)
+ *(.got.plt) *(.got)
+ *(.dynamic)
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
- *(.sdata)
+ *(.sdata)
_edata = .;
PROVIDE (edata = .);
@@ -96,21 +96,21 @@
/* These are needed for ELF backends which have not yet been
converted to the new style linker. */
- *(.stab)
- *(.stabstr)
+ *(.stab)
+ *(.stabstr)
/* DWARF debug sections.
Symbols in the .debug DWARF section are relative to the beginning of the
section so we begin .debug at 0. It's not clear yet what needs to happen
for the others. */
- *(.debug)
- *(.debug_srcinfo)
- *(.debug_aranges)
- *(.debug_pubnames)
- *(.debug_sfnames)
- *(.line)
+ *(.debug)
+ *(.debug_srcinfo)
+ *(.debug_aranges)
+ *(.debug_pubnames)
+ *(.debug_sfnames)
+ *(.line)
/* These must appear regardless of . */
- *(.gptab.data) *(.gptab.sdata)
- *(.gptab.bss) *(.gptab.sbss)
+ *(.gptab.data) *(.gptab.sdata)
+ *(.gptab.bss) *(.gptab.sbss)
_vmlinux_start = .;
*(.vmlinux)
diff -Nru a/arch/mips/baget/print.c b/arch/mips/baget/print.c
--- a/arch/mips/baget/print.c Tue Feb 5 09:40:24 2002
+++ b/arch/mips/baget/print.c Mon Apr 14 20:10:11 2003
@@ -1,9 +1,7 @@
-/* $Id: print.c,v 1.1 1999/01/17 03:49:38 ralf Exp $
- *
+/*
* print.c: Simple print fascility
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- *
*/
#include
#include
@@ -16,7 +14,7 @@
*/
// #define BAGET_PRINTK
-/*
+/*
* This function is same for BALO and Linux baget_printk,
* and normally prints characted to second (UART A) console.
*/
@@ -27,7 +25,7 @@
{
int i;
vac_outb(c, VAC_UART_B_TX);
- for (i=0; i<10000; i++)
+ for (i=0; i<10000; i++)
delay();
}
@@ -38,7 +36,7 @@
outc_low(c);
}
-void outs(char *s)
+void outs(char *s)
{
while(*s) outc(*s++);
}
@@ -79,7 +77,7 @@
void __init balo_printf( char *f, ... )
{
int *arg = (int*)&f + 1;
- char c;
+ char c;
int format = 0;
while((c = *f++) != 0) {
@@ -112,7 +110,7 @@
}
void __init balo_hungup(void)
-{
+{
outs("Hunging up.\n");
- while(1);
+ while(1);
}
diff -Nru a/arch/mips/baget/prom/init.c b/arch/mips/baget/prom/init.c
--- a/arch/mips/baget/prom/init.c Mon Feb 4 23:45:04 2002
+++ b/arch/mips/baget/prom/init.c Mon Apr 14 20:10:11 2003
@@ -1,13 +1,19 @@
/*
* init.c: PROM library initialisation code.
*
- * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
*/
#include
#include
#include
-char arcs_cmdline[COMMAND_LINE_SIZE];
+char arcs_cmdline[CL_SIZE];
+
+const char *get_system_type(void)
+{
+ /* Should probably return one of "BT23-201", "BT23-202" */
+ return "Baget";
+}
void __init prom_init(unsigned int mem_upper)
{
diff -Nru a/arch/mips/baget/setup.c b/arch/mips/baget/setup.c
--- a/arch/mips/baget/setup.c Wed May 22 10:13:45 2002
+++ b/arch/mips/baget/setup.c Mon Apr 14 20:10:11 2003
@@ -1,9 +1,7 @@
-/* $Id: setup.c,v 1.4 1999/10/09 00:00:57 ralf Exp $
- *
+/*
* setup.c: Baget/MIPS specific setup, including init of the feature struct.
*
* Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- *
*/
#include
#include
@@ -17,9 +15,9 @@
long int vac_memory_upper;
#define CACHEABLE_STR(val) ((val) ? "not cached" : "cached")
-
+
static void __init vac_show(void)
-{
+{
int i;
unsigned short val, decode = vac_inw(VAC_DECODE_CTRL);
unsigned short a24_base = vac_inw(VAC_A24_BASE);
@@ -38,7 +36,7 @@
VAC_IOSEL3_CTRL,
VAC_IOSEL4_CTRL,
VAC_IOSEL5_CTRL };
-
+
printk("[DSACKi %s, DRAMCS%s qualified, boundary%s qualified%s]\n",
(decode & VAC_DECODE_DSACKI) ? "on" : "off",
(decode & VAC_DECODE_QFY_DRAMCS) ? "" : " not",
@@ -72,24 +70,24 @@
VAC_ICFSEL_MODULE_VAL(vac_inw(VAC_ICFSEL_BASE)))<<4,
(decode & VAC_DECODE_QFY_ICFSEL) ? "qualified" : "");
-
+
printk("region0 at 00000000 (%dMB)\t[dram, %s, delay %d cpuclk"
", cached]\n",
(vac_inw(VAC_DRAM_MASK)+1)>>4,
(decode & VAC_DECODE_DSACK) ? "D32" : "3state",
VAC_DECODE_CPUCLK_VAL(decode));
-
+
for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) {
- unsigned long from =
+ unsigned long from =
((unsigned long)vac_inw(bndr[i]))<<16;
- unsigned long to =
+ unsigned long to =
((unsigned long)
- ((i+1 == sizeof(bndr)/sizeof(bndr[0])) ?
+ ((i+1 == sizeof(bndr)/sizeof(bndr[0])) ?
0xff00 : vac_inw(bndr[i+1])))<<16;
-
-
+
+
val = vac_inw(regs[i]);
- printk("region%d at %08lx (%dMB)\t[%s %s/%s, %s]\n",
+ printk("region%d at %08lx (%dMB)\t[%s %s/%s, %s]\n",
i+1,
from,
(unsigned int)((to - from) >> 20),
@@ -97,13 +95,13 @@
asiz[VAC_REG_ASIZ_VAL(val)],
((val & VAC_REG_WORD) ? "D16" : "D32"),
CACHEABLE_STR(val&VAC_A24_A24_CACHINH));
-
+
if (a24_addr >= from && a24_addr < to)
printk("\ta24 at %08lx (%dMB)\t[vme, A24/%s, %s]\n",
a24_addr,
min((unsigned int)(a24_addr - from)>>20, 32U),
(a24_base & VAC_A24_DATAPATH) ? "user" :
- ((a24_base & VAC_A24_D32_ENABLE) ?
+ ((a24_base & VAC_A24_D32_ENABLE) ?
"D32" : "D16"),
CACHEABLE_STR(a24_base & VAC_A24_A24_CACHINH));
}
@@ -123,7 +121,7 @@
(VAC_CTRL_DELAY_IOWR_VAL(val)&1) ? ".5" : "",
VAC_CTRL_DELAY_IOSELI_VAL(val)/2,
(VAC_CTRL_DELAY_IOSELI_VAL(val)&1) ? ".5" : "");
-
+
printk("region5 at fff00000 (896KB)\t[local io, %s]\n",
CACHEABLE_STR(vac_inw(VAC_A24_BASE) & VAC_A24_IO_CACHINH));
@@ -132,7 +130,7 @@
printk("\tio%d[ack %d cpuclk%s, %s%srecovery %d cpuclk, "
"\n\t read %d%s cpuclk, write %d%s cpuclk, "
"assert %d%s%s cpuclk]\n",
- i,
+ i,
VAC_CTRL_DELAY_DSACKI_VAL(val),
state[val & (VAC_CTRL_IORD|VAC_CTRL_IOWR)],
(val & VAC_CTRL_DSACK0) ? "dsack0*, " : "",
@@ -144,15 +142,15 @@
(VAC_CTRL_DELAY_IOWR_VAL(val)&1) ? ".5" : "",
VAC_CTRL_DELAY_IOSELI_VAL(val)/2,
(VAC_CTRL_DELAY_IOSELI_VAL(val)&1) ? ".5" : "",
- (vac_inw(VAC_DEV_LOC) & VAC_DEV_LOC_IOSEL(i)) ?
+ (vac_inw(VAC_DEV_LOC) & VAC_DEV_LOC_IOSEL(i)) ?
", id" : "");
}
-
+
printk("region6 at fffe0000 (128KB)\t[vme, A16/%s, "
"not cached]\n",
- (a24_base & VAC_A24_A16D32_ENABLE) ?
+ (a24_base & VAC_A24_A16D32_ENABLE) ?
((a24_base & VAC_A24_A16D32) ? "D32" : "D16") : "user");
-
+
val = vac_inw(VAC_SHRCS_CTRL);
printk("shared[ack %d cpuclk%s, %s%srecovery %d cpuclk, "
"read %d%s, write %d%s, assert %d%s]\n",
@@ -183,8 +181,8 @@
default:
panic("Unknown VAC revision number");
}
-
- vac_outw(mem_limit-1, VAC_DRAM_MASK);
+
+ vac_outw(mem_limit-1, VAC_DRAM_MASK);
vac_outw(mem_limit, VAC_BNDR2);
vac_outw(mem_limit, VAC_BNDR3);
vac_outw(((BAGET_A24M_BASE>>16)&~VAC_A24_D32_ENABLE)|VAC_A24_DATAPATH,
@@ -294,19 +292,19 @@
vac_outw(VAC_INT_CTRL_TIMER_PIO10|
VAC_INT_CTRL_UART_B_PIO7|
VAC_INT_CTRL_UART_A_PIO7,VAC_INT_CTRL);
- /*
+ /*
* Set quadro speed for both UARTs.
* To do it we need use formulae from VIC/VAC manual,
* keeping in mind Baget's 50MHz frequency...
*/
- vac_outw((500000/(384*16))<<8,VAC_CPU_CLK_DIV);
+ vac_outw((500000/(384*16))<<8,VAC_CPU_CLK_DIV);
}
static void __init vic_show(void)
{
unsigned char val;
char *timeout[] = { "4", "16", "32", "64", "128", "256", "disabled" };
- char *deadlock[] = { "[dedlk only]", "[dedlk only]",
+ char *deadlock[] = { "[dedlk only]", "[dedlk only]",
"[dedlk], [halt w/ rmc], [lberr]",
"[dedlk], [halt w/o rmc], [lberr]" };
@@ -319,7 +317,7 @@
printk("metastability delay ");
printk("%s ",
deadlock[VIC_IFACE_CFG_DEADLOCK_VAL(val)]);
-
+
printk("interrupts: ");
val = vic_inb(VIC_ERR_INT);
@@ -332,7 +330,7 @@
if (!(val & VIC_ERR_INT_ACFAIL))
printk("[acfail] ");
printk("\n");
-
+
printk("timeouts: ");
val = vic_inb(VIC_XFER_TIMO);
printk("local %s, vme %s ",
@@ -358,7 +356,7 @@
printk("[local boundary cross]");
if (val & VIC_BXFER_DEF_VME_CROSS)
printk("[vme boundary cross]");
-
+
}
static void __init vic_init(void)
@@ -373,7 +371,7 @@
vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT2);
vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT3);
vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT4);
-/*
+/*
vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE, VIC_VME_INT5);
*/
vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE, VIC_VME_INT6);
@@ -388,7 +386,7 @@
VIC_INT_HIGH|VIC_INT_DISABLE, VIC_LINT3);
vic_outb(VIC_INT_IPL(3)|VIC_INT_NOAUTO|VIC_INT_EDGE|
VIC_INT_LOW|VIC_INT_DISABLE, VIC_LINT4);
-/*
+/*
vic_outb(VIC_INT_IPL(3)|VIC_INT_NOAUTO|VIC_INT_LEVEL|
VIC_INT_LOW|VIC_INT_DISABLE, VIC_LINT5);
*/
@@ -447,7 +445,7 @@
VIC_RELEASE_RWD, VIC_RELEASE);
vic_outb(VIC_IC6_RUN, VIC_IC6);
vic_outb(0, VIC_IC7);
-
+
vic_show();
}
@@ -471,7 +469,7 @@
extern void baget_machine_restart(char *command);
extern void baget_machine_halt(void);
extern void baget_machine_power_off(void);
-
+
void __init baget_setup(void)
{
printk("BT23/63-201n found.\n");
diff -Nru a/arch/mips/baget/time.c b/arch/mips/baget/time.c
--- a/arch/mips/baget/time.c Wed Feb 5 05:04:38 2003
+++ b/arch/mips/baget/time.c Sun Jun 15 16:54:30 2003
@@ -20,23 +20,23 @@
#include
#include
#include
-#include
+#include
#include
-/*
+/*
* To have precision clock, we need to fix available clock frequency
*/
#define FREQ_NOM 79125 /* Baget frequency ratio */
#define FREQ_DEN 10000
-static inline int timer_intr_valid(void)
+static inline int timer_intr_valid(void)
{
static unsigned long long ticks, valid_ticks;
if (ticks++ * FREQ_DEN >= valid_ticks * FREQ_NOM) {
- /*
- * We need no overflow checks,
+ /*
+ * We need no overflow checks,
* due baget unable to work 3000 years...
* At least without reboot...
*/
@@ -62,10 +62,10 @@
vic_outb(ss0cr0, VIC_SS0CR0);
vic_outb(VIC_INT_IPL(6)|VIC_INT_NOAUTO|VIC_INT_EDGE|
- VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2);
+ VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2);
}
-static struct irqaction timer_irq =
+static struct irqaction timer_irq =
{ timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
void __init time_init(void)
@@ -82,17 +82,19 @@
do {
seq = read_seqbegin(&xtime_lock);
- *tv = xtime;
+ tv->tv_sec = xtime.tv_sec;
+ tv->tv_usec = xtime.tv_nsec / 1000;
} while (read_seqretry(&xtime_lock, seq));
}
void do_settimeofday(struct timeval *tv)
{
- write_seqlock_irq (&xtime_lock);
- xtime = *tv;
+ write_seqlock_irq(&xtime_lock);
+ xtime.tv_usec = tv->tv_sec;
+ xtime.tv_nsec = tv->tv_usec;
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
- write_sequnlock_irq (&xtime_lock);
+ write_sequnlock_irq(&xtime_lock);
}
diff -Nru a/arch/mips/baget/vacserial.c b/arch/mips/baget/vacserial.c
--- a/arch/mips/baget/vacserial.c Wed Jun 11 12:32:55 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,2837 +0,0 @@
-/*
- * vacserial.c: VAC UART serial driver
- * This code stealed and adopted from linux/drivers/char/serial.c
- * See that for author info
- *
- * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- */
-
-#undef SERIAL_PARANOIA_CHECK
-#define CONFIG_SERIAL_NOPAUSE_IO
-#define SERIAL_DO_RESTART
-
-#define CONFIG_SERIAL_SHARE_IRQ
-
-/* Set of debugging defines */
-
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-
-#define RS_STROBE_TIME (10*HZ)
-#define RS_ISR_PASS_LIMIT 2 /* Beget is not a super-computer (old=256) */
-
-#define IRQ_T(state) \
- ((state->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
-
-#define SERIAL_INLINE
-
-#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
-#define DBG_CNT(s) baget_printk("(%s):[%x] refc=%d, serc=%d, ttyc=%d-> %s\n", \
- tty->name,(info->flags),serial_driver->refcount,info->count,tty->count,s)
-#else
-#define DBG_CNT(s)
-#endif
-
-#define QUAD_UART_SPEED /* Useful for Baget */
-
-/*
- * End of serial driver configuration section.
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#ifdef CONFIG_SERIAL_CONSOLE
-#include
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define BAGET_VAC_UART_IRQ 0x35
-
-/*
- * Implementation note:
- * It was descovered by means of advanced electronic tools,
- * if the driver works via TX_READY interrupts then VIC generates
- * strange self-eliminating traps. Thus, the driver is rewritten to work
- * via TX_EMPTY
- */
-
-/* VAC-specific check/debug switches */
-
-#undef CHECK_REG_INDEX
-#undef DEBUG_IO_PORT_A
-
-#ifdef SERIAL_INLINE
-#define _INLINE_ inline
-#endif
-
-static char *serial_name = "VAC Serial driver";
-static char *serial_version = "4.26";
-
-static DECLARE_TASK_QUEUE(tq_serial);
-
-static struct tty_driver *serial_driver;
-
-/* number of characters left in xmit buffer before we ask for more */
-#define WAKEUP_CHARS 256
-
-/*
- * IRQ_timeout - How long the timeout should be for each IRQ
- * should be after the IRQ has been active.
- */
-
-static struct async_struct *IRQ_ports[NR_IRQS];
-static int IRQ_timeout[NR_IRQS];
-#ifdef CONFIG_SERIAL_CONSOLE
-static struct console sercons;
-#endif
-
-static void autoconfig(struct serial_state * info);
-static void change_speed(struct async_struct *info);
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
-static void rs_timer(unsigned long dummy);
-
-static struct timer_list vacs_timer;
-
-/*
- * Here we define the default xmit fifo size used for each type of
- * UART
- */
-static struct serial_uart_config uart_config[] = {
- { "unknown", 1, 0 }, /* Must go first -- used as unassigned */
- { "VAC UART", 1, 0 }
-};
-#define VAC_UART_TYPE 1 /* Just index in above array */
-
-static struct serial_state rs_table[] = {
-/*
- * VAC has tricky layout for pair of his SIO registers,
- * so we need special function to access ones.
- * To identify port we use their TX offset
- */
- { 0, 9600, VAC_UART_B_TX, BAGET_VAC_UART_IRQ,
- STD_COM_FLAGS }, /* VAC UART B */
- { 0, 9600, VAC_UART_A_TX, BAGET_VAC_UART_IRQ,
- STD_COM_FLAGS } /* VAC UART A */
-};
-
-#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state))
-
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
-/*
- * tmp_buf is used as a temporary buffer by serial_write. We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf;
-static DECLARE_MUTEX(tmp_buf_sem);
-
-static inline int serial_paranoia_check(struct async_struct *info,
- char *name, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
- static const char *badmagic =
- "Warning: bad magic number for serial struct (%s) in %s\n";
- static const char *badinfo =
- "Warning: null async_struct for (%s) in %s\n";
-
- if (!info) {
- printk(badinfo, name, routine);
- return 1;
- }
- if (info->magic != SERIAL_MAGIC) {
- printk(badmagic, name, routine);
- return 1;
- }
-#endif
- return 0;
-}
-
-/*
- To unify UART A/B access we will use following function
- to compute register offsets by register index.
- */
-
-#define VAC_UART_MODE 0
-#define VAC_UART_TX 1
-#define VAC_UART_RX 2
-#define VAC_UART_INT_MASK 3
-#define VAC_UART_INT_STATUS 4
-
-#define VAC_UART_REG_NR 5
-
-static inline int uart_offset_map(unsigned long port, int reg_index)
-{
- static const unsigned int ind_to_reg[VAC_UART_REG_NR][NR_PORTS] = {
- { VAC_UART_B_MODE, VAC_UART_A_MODE },
- { VAC_UART_B_TX, VAC_UART_A_TX },
- { VAC_UART_B_RX, VAC_UART_A_RX },
- { VAC_UART_B_INT_MASK, VAC_UART_A_INT_MASK },
- { VAC_UART_B_INT_STATUS, VAC_UART_A_INT_STATUS }
- };
-#ifdef CHECK_REG_INDEX
- if (reg_index > VAC_UART_REG_NR) panic("vacserial: bad reg_index");
-#endif
- return ind_to_reg[reg_index][port == VAC_UART_B_TX ? 0 : 1];
-}
-
-static inline unsigned int serial_inw(struct async_struct *info, int offset)
-{
- int val = vac_inw(uart_offset_map(info->port,offset));
-#ifdef DEBUG_IO_PORT_A
- if (info->port == VAC_UART_A_TX)
- printk("UART_A_IN: reg = 0x%04x, val = 0x%04x\n",
- uart_offset_map(info->port,offset), val);
-#endif
- return val;
-}
-
-static inline unsigned int serial_inp(struct async_struct *info, int offset)
-{
- return serial_inw(info, offset);
-}
-
-static inline unsigned int serial_in(struct async_struct *info, int offset)
-{
- return serial_inw(info, offset);
-}
-
-static inline void serial_outw(struct async_struct *info,int offset, int value)
-{
-#ifdef DEBUG_IO_PORT_A
- if (info->port == VAC_UART_A_TX)
- printk("UART_A_OUT: offset = 0x%04x, val = 0x%04x\n",
- uart_offset_map(info->port,offset), value);
-#endif
- vac_outw(value, uart_offset_map(info->port,offset));
-}
-
-static inline void serial_outp(struct async_struct *info,int offset, int value)
-{
- serial_outw(info,offset,value);
-}
-
-static inline void serial_out(struct async_struct *info,int offset, int value)
-{
- serial_outw(info,offset,value);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_stop() and rs_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void rs_stop(struct tty_struct *tty)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_stop"))
- return;
-
- save_flags(flags); cli();
- if (info->IER & VAC_UART_INT_TX_EMPTY) {
- info->IER &= ~VAC_UART_INT_TX_EMPTY;
- serial_out(info, VAC_UART_INT_MASK, info->IER);
- }
- restore_flags(flags);
-}
-
-static void rs_start(struct tty_struct *tty)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_start"))
- return;
-
- save_flags(flags); cli();
- if (info->xmit_cnt && info->xmit_buf
- && !(info->IER & VAC_UART_INT_TX_EMPTY)) {
- info->IER |= VAC_UART_INT_TX_EMPTY;
- serial_out(info, VAC_UART_INT_MASK, info->IER);
- }
- restore_flags(flags);
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines. All of the following
- * subroutines are declared as inline and are folded into
- * rs_interrupt(). They were separated out for readability's sake.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off. People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible. After you are done making modifications, it is not a bad
- * idea to do:
- *
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * - Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver.
- */
-static _INLINE_ void rs_sched_event(struct async_struct *info,
- int event)
-{
- info->event |= 1 << event;
- queue_task(&info->tqueue, &tq_serial);
- mark_bh(SERIAL_BH);
-}
-
-static _INLINE_ void receive_chars(struct async_struct *info,
- int *status)
-{
- struct tty_struct *tty = info->tty;
- unsigned short rx;
- unsigned char ch;
- int ignored = 0;
- struct async_icount *icount;
-
- icount = &info->state->icount;
- do {
- rx = serial_inw(info, VAC_UART_RX);
- ch = VAC_UART_RX_DATA_MASK & rx;
-
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- break;
- *tty->flip.char_buf_ptr = ch;
- icount->rx++;
-
-#ifdef SERIAL_DEBUG_INTR
- baget_printk("DR%02x:%02x...", rx, *status);
-#endif
- *tty->flip.flag_buf_ptr = 0;
- if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE
- | VAC_UART_STATUS_RX_ERR_PARITY
- | VAC_UART_STATUS_RX_ERR_FRAME
- | VAC_UART_STATUS_RX_ERR_OVERRUN)) {
- /*
- * For statistics only
- */
- if (*status & VAC_UART_STATUS_RX_BREAK_CHANGE) {
- *status &= ~(VAC_UART_STATUS_RX_ERR_FRAME
- | VAC_UART_STATUS_RX_ERR_PARITY);
- icount->brk++;
- } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY)
- icount->parity++;
- else if (*status & VAC_UART_STATUS_RX_ERR_FRAME)
- icount->frame++;
- if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN)
- icount->overrun++;
-
- /*
- * Now check to see if character should be
- * ignored, and mask off conditions which
- * should be ignored.
- */
- if (*status & info->ignore_status_mask) {
- if (++ignored > 100)
- break;
- goto ignore_char;
- }
- *status &= info->read_status_mask;
-
- if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE)) {
-#ifdef SERIAL_DEBUG_INTR
- baget_printk("handling break....");
-#endif
- *tty->flip.flag_buf_ptr = TTY_BREAK;
- if (info->flags & ASYNC_SAK)
- do_SAK(tty);
- } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY)
- *tty->flip.flag_buf_ptr = TTY_PARITY;
- else if (*status & VAC_UART_STATUS_RX_ERR_FRAME)
- *tty->flip.flag_buf_ptr = TTY_FRAME;
- if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) {
- /*
- * Overrun is special, since it's
- * reported immediately, and doesn't
- * affect the current character
- */
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- tty->flip.count++;
- tty->flip.flag_buf_ptr++;
- tty->flip.char_buf_ptr++;
- *tty->flip.flag_buf_ptr = TTY_OVERRUN;
- }
- }
- }
- tty->flip.flag_buf_ptr++;
- tty->flip.char_buf_ptr++;
- tty->flip.count++;
- ignore_char:
- *status = serial_inw(info, VAC_UART_INT_STATUS);
- } while ((*status & VAC_UART_STATUS_RX_READY));
- tty_flip_buffer_push(tty);
-}
-
-static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
-{
- int count;
-
- if (info->x_char) {
- serial_outw(info, VAC_UART_TX,
- (((unsigned short)info->x_char)<<8));
- info->state->icount.tx++;
- info->x_char = 0;
- if (intr_done)
- *intr_done = 0;
- return;
- }
- if ((info->xmit_cnt <= 0) || info->tty->stopped ||
- info->tty->hw_stopped) {
- info->IER &= ~VAC_UART_INT_TX_EMPTY;
- serial_outw(info, VAC_UART_INT_MASK, info->IER);
- return;
- }
- count = info->xmit_fifo_size;
- do {
- serial_out(info, VAC_UART_TX,
- (unsigned short)info->xmit_buf[info->xmit_tail++] \
- << 8);
- info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
- info->state->icount.tx++;
- if (--info->xmit_cnt <= 0)
- break;
- } while (--count > 0);
-
- if (info->xmit_cnt < WAKEUP_CHARS)
- rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-
-#ifdef SERIAL_DEBUG_INTR
- baget_printk("THRE...");
-#endif
- if (intr_done)
- *intr_done = 0;
-
- if (info->xmit_cnt <= 0) {
- info->IER &= ~VAC_UART_INT_TX_EMPTY;
- serial_outw(info, VAC_UART_INT_MASK, info->IER);
- }
-}
-
-static _INLINE_ void check_modem_status(struct async_struct *info)
-{
-#if 0 /* VAC hasn't modem control */
- wake_up_interruptible(&info->open_wait);
- rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-#endif
-}
-
-#ifdef CONFIG_SERIAL_SHARE_IRQ
-
-
-/*
- * Specific functions needed for VAC UART interrupt enter/leave
- */
-
-#define VAC_INT_CTRL_UART_ENABLE \
- (VAC_INT_CTRL_TIMER_PIO10|VAC_INT_CTRL_UART_B_PIO7|VAC_INT_CTRL_UART_A_PIO7)
-
-#define VAC_INT_CTRL_UART_DISABLE(info) \
- (VAC_INT_CTRL_TIMER_PIO10 | \
- ((info->port == VAC_UART_A_TX) ? \
- (VAC_INT_CTRL_UART_A_DISABLE|VAC_INT_CTRL_UART_B_PIO7) : \
- (VAC_INT_CTRL_UART_A_PIO7|VAC_INT_CTRL_UART_B_DISABLE)))
-
-/*
- * Following two functions were proposed by Pavel Osipenko
- * to make VAC/VIC behaviour more regular.
- */
-static void intr_begin(struct async_struct* info)
-{
- serial_outw(info, VAC_UART_INT_MASK, 0);
-}
-
-static void intr_end(struct async_struct* info)
-{
- vac_outw(VAC_INT_CTRL_UART_DISABLE(info), VAC_INT_CTRL);
- vac_outw(VAC_INT_CTRL_UART_ENABLE, VAC_INT_CTRL);
-
- serial_outw(info, VAC_UART_INT_MASK, info->IER);
-}
-
-/*
- * This is the serial driver's generic interrupt routine
- */
-static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
- int status;
- struct async_struct * info;
- int pass_counter = 0;
- struct async_struct *end_mark = 0;
-
-#ifdef SERIAL_DEBUG_INTR
- baget_printk("rs_interrupt(%d)...", irq);
-#endif
-
- info = IRQ_ports[irq];
- if (!info)
- return;
-
- do {
- intr_begin(info); /* Mark we begin port handling */
-
- if (!info->tty ||
- (serial_inw (info, VAC_UART_INT_STATUS)
- & VAC_UART_STATUS_INTS) == 0)
- {
- if (!end_mark)
- end_mark = info;
- goto next;
- }
- end_mark = 0;
-
- info->last_active = jiffies;
-
- status = serial_inw(info, VAC_UART_INT_STATUS);
-#ifdef SERIAL_DEBUG_INTR
- baget_printk("status = %x...", status);
-#endif
- if (status & VAC_UART_STATUS_RX_READY) {
- receive_chars(info, &status);
- }
- check_modem_status(info);
- if (status & VAC_UART_STATUS_TX_EMPTY)
- transmit_chars(info, 0);
-
- next:
- intr_end(info); /* Mark this port handled */
-
- info = info->next_port;
- if (!info) {
- info = IRQ_ports[irq];
- if (pass_counter++ > RS_ISR_PASS_LIMIT) {
- break; /* Prevent infinite loops */
- }
- continue;
- }
- } while (end_mark != info);
-#ifdef SERIAL_DEBUG_INTR
- baget_printk("end.\n");
-#endif
-
-
-}
-#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */
-
-
-/* The original driver was simplified here:
- two functions were joined to reduce code */
-
-#define rs_interrupt_single rs_interrupt
-
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-/*
- * This routine is used to handle the "bottom half" processing for the
- * serial driver, known also the "software interrupt" processing.
- * This processing is done at the kernel interrupt level, after the
- * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This
- * is where time-consuming activities which can not be done in the
- * interrupt driver proper are done; the interrupt driver schedules
- * them using rs_sched_event(), and they get done here.
- */
-static void do_serial_bh(void)
-{
- run_task_queue(&tq_serial);
-}
-
-static void do_softint(void *private_)
-{
- struct async_struct *info = (struct async_struct *) private_;
- struct tty_struct *tty;
-
- tty = info->tty;
- if (!tty)
- return;
-
- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
- wake_up_interruptible(&tty->write_wait);
- }
-}
-
-/*
- * ---------------------------------------------------------------
- * Low level utility subroutines for the serial driver: routines to
- * figure out the appropriate timeout for an interrupt chain, routines
- * to initialize and startup a serial port, and routines to shutdown a
- * serial port. Useful stuff like that.
- * ---------------------------------------------------------------
- */
-
-/*
- * This routine figures out the correct timeout for a particular IRQ.
- * It uses the smallest timeout of all of the serial ports in a
- * particular interrupt chain. Now only used for IRQ 0....
- */
-static void figure_IRQ_timeout(int irq)
-{
- struct async_struct *info;
- int timeout = 60*HZ; /* 60 seconds === a long time :-) */
-
- info = IRQ_ports[irq];
- if (!info) {
- IRQ_timeout[irq] = 60*HZ;
- return;
- }
- while (info) {
- if (info->timeout < timeout)
- timeout = info->timeout;
- info = info->next_port;
- }
- if (!irq)
- timeout = timeout / 2;
- IRQ_timeout[irq] = timeout ? timeout : 1;
-}
-
-static int startup(struct async_struct * info)
-{
- unsigned long flags;
- int retval=0;
- void (*handler)(int, void *, struct pt_regs *);
- struct serial_state *state= info->state;
- unsigned long page;
-
- page = get_zeroed_page(GFP_KERNEL);
- if (!page)
- return -ENOMEM;
-
- save_flags(flags); cli();
-
- if (info->flags & ASYNC_INITIALIZED) {
- free_page(page);
- goto errout;
- }
- if (!state->port || !state->type) {
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
- free_page(page);
- goto errout;
- }
- if (info->xmit_buf)
- free_page(page);
- else
- info->xmit_buf = (unsigned char *) page;
-
-#ifdef SERIAL_DEBUG_OPEN
- baget_printk("starting up ttys%d (irq %d)...", info->line, state->irq);
-#endif
-
- if (uart_config[info->state->type].flags & UART_STARTECH) {
- /* Wake up UART */
- serial_outp(info, VAC_UART_MODE, 0);
- serial_outp(info, VAC_UART_INT_MASK, 0);
- }
-
- /*
- * Allocate the IRQ if necessary
- */
- if (state->irq && (!IRQ_ports[state->irq] ||
- !IRQ_ports[state->irq]->next_port)) {
-
- if (IRQ_ports[state->irq]) {
-#ifdef CONFIG_SERIAL_SHARE_IRQ
- free_irq(state->irq, NULL);
- handler = rs_interrupt;
-#else
- retval = -EBUSY;
- goto errout;
-#endif /* CONFIG_SERIAL_SHARE_IRQ */
- } else
- handler = rs_interrupt_single;
-
-
- retval = request_irq(state->irq, handler, IRQ_T(state),
- "serial", NULL);
- if (retval) {
- if (capable(CAP_SYS_ADMIN)) {
- if (info->tty)
- set_bit(TTY_IO_ERROR,
- &info->tty->flags);
- retval = 0;
- }
- goto errout;
- }
- }
-
- /*
- * Insert serial port into IRQ chain.
- */
- info->prev_port = 0;
- info->next_port = IRQ_ports[state->irq];
- if (info->next_port)
- info->next_port->prev_port = info;
- IRQ_ports[state->irq] = info;
- figure_IRQ_timeout(state->irq);
-
- /*
- * Clear the interrupt registers.
- */
- /* (void) serial_inw(info, VAC_UART_INT_STATUS); */ /* (see above) */
- (void) serial_inw(info, VAC_UART_RX);
-
- /*
- * Now, initialize the UART
- */
- serial_outp(info, VAC_UART_MODE, VAC_UART_MODE_INITIAL); /*reset DLAB*/
-
- /*
- * Finally, enable interrupts
- */
- info->IER = VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS | \
- VAC_UART_INT_RX_READY;
- serial_outp(info, VAC_UART_INT_MASK, info->IER); /*enable interrupts*/
-
- /*
- * And clear the interrupt registers again for luck.
- */
- (void)serial_inp(info, VAC_UART_INT_STATUS);
- (void)serial_inp(info, VAC_UART_RX);
-
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
- info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-
- /*
- * Set up serial timers...
- */
- mod_timer(&vacs_timer, jiffies + 2*HZ/100);
-
- /*
- * and set the speed of the serial port
- */
- change_speed(info);
-
- info->flags |= ASYNC_INITIALIZED;
- restore_flags(flags);
- return 0;
-
-errout:
- restore_flags(flags);
- return retval;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void shutdown(struct async_struct * info)
-{
- unsigned long flags;
- struct serial_state *state;
- int retval;
-
- if (!(info->flags & ASYNC_INITIALIZED))
- return;
-
- state = info->state;
-
-#ifdef SERIAL_DEBUG_OPEN
- baget_printk("Shutting down serial port %d (irq %d)....", info->line,
- state->irq);
-#endif
-
- save_flags(flags); cli(); /* Disable interrupts */
-
- /*
- * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
- * here so the queue might never be waken up
- */
- wake_up_interruptible(&info->delta_msr_wait);
-
- /*
- * First unlink the serial port from the IRQ chain...
- */
- if (info->next_port)
- info->next_port->prev_port = info->prev_port;
- if (info->prev_port)
- info->prev_port->next_port = info->next_port;
- else
- IRQ_ports[state->irq] = info->next_port;
- figure_IRQ_timeout(state->irq);
-
- /*
- * Free the IRQ, if necessary
- */
- if (state->irq && (!IRQ_ports[state->irq] ||
- !IRQ_ports[state->irq]->next_port)) {
- if (IRQ_ports[state->irq]) {
- free_irq(state->irq, NULL);
- retval = request_irq(state->irq, rs_interrupt_single,
- IRQ_T(state), "serial", NULL);
-
- if (retval)
- printk("serial shutdown: request_irq: error %d"
- " Couldn't reacquire IRQ.\n", retval);
- } else
- free_irq(state->irq, NULL);
- }
-
- if (info->xmit_buf) {
- free_page((unsigned long) info->xmit_buf);
- info->xmit_buf = 0;
- }
-
- info->IER = 0;
- serial_outp(info, VAC_UART_INT_MASK, 0x00); /* disable all intrs */
-
- /* disable break condition */
- serial_out(info, VAC_UART_MODE, serial_inp(info, VAC_UART_MODE) & \
- ~VAC_UART_MODE_SEND_BREAK);
-
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
-
- info->flags &= ~ASYNC_INITIALIZED;
- restore_flags(flags);
-}
-
-/*
- * When we set line mode, we call this function
- * for Baget-specific adjustments.
- */
-
-static inline unsigned short vac_uart_mode_fixup (unsigned short cval)
-{
-#ifdef QUAD_UART_SPEED
- /*
- * When we are using 4-x advantage in speed:
- *
- * Disadvantage : can't support 75, 150 bauds
- * Advantage : can support 19200, 38400 bauds
- */
- char speed = 7 & (cval >> 10);
- cval &= ~(7 << 10);
- cval |= VAC_UART_MODE_BAUD(speed-2);
-#endif
-
- /*
- * In general, we have Tx and Rx ON all time
- * and use int mask flag for their disabling.
- */
- cval |= VAC_UART_MODE_RX_ENABLE;
- cval |= VAC_UART_MODE_TX_ENABLE;
- cval |= VAC_UART_MODE_CHAR_RX_ENABLE;
- cval |= VAC_UART_MODE_CHAR_TX_ENABLE;
-
- /* Low 4 bits are not used in UART */
- cval &= ~0xf;
-
- return cval;
-}
-
-/*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
- */
-static void change_speed(struct async_struct *info)
-{
- unsigned short port;
- int quot = 0, baud_base, baud;
- unsigned cflag, cval;
- int bits;
- unsigned long flags;
-
- if (!info->tty || !info->tty->termios)
- return;
- cflag = info->tty->termios->c_cflag;
- if (!(port = info->port))
- return;
-
- /* byte size and parity */
- switch (cflag & CSIZE) {
- case CS7: cval = 0x0; bits = 9; break;
- case CS8: cval = VAC_UART_MODE_8BIT_CHAR; bits = 10; break;
- /* Never happens, but GCC is too dumb to figure it out */
- case CS5:
- case CS6:
- default: cval = 0x0; bits = 9; break;
- }
- cval &= ~VAC_UART_MODE_PARITY_ENABLE;
- if (cflag & PARENB) {
- cval |= VAC_UART_MODE_PARITY_ENABLE;
- bits++;
- }
- if (cflag & PARODD)
- cval |= VAC_UART_MODE_PARITY_ODD;
-
- /* Determine divisor based on baud rate */
- baud = tty_get_baud_rate(info->tty);
- if (!baud)
- baud = 9600; /* B0 transition handled in rs_set_termios */
- baud_base = info->state->baud_base;
- if (baud == 38400 &&
- ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
- quot = info->state->custom_divisor;
- else {
- if (baud == 134)
- /* Special case since 134 is really 134.5 */
- quot = (2*baud_base / 269);
- else if (baud)
- quot = baud_base / baud;
- }
- /* If the quotient is ever zero, default to 9600 bps */
- if (!quot)
- quot = baud_base / 9600;
- info->quot = quot;
- info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
- info->timeout += HZ/50; /* Add .02 seconds of slop */
-
- serial_out(info, VAC_UART_INT_MASK, info->IER);
-
- /*
- * Set up parity check flag
- */
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
- info->read_status_mask = VAC_UART_STATUS_RX_ERR_OVERRUN | \
- VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_RX_READY;
- if (I_INPCK(info->tty))
- info->read_status_mask |= VAC_UART_STATUS_RX_ERR_FRAME | \
- VAC_UART_STATUS_RX_ERR_PARITY;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
- info->read_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE;
-
- /*
- * Characters to ignore
- */
- info->ignore_status_mask = 0;
- if (I_IGNPAR(info->tty))
- info->ignore_status_mask |= VAC_UART_STATUS_RX_ERR_PARITY | \
- VAC_UART_STATUS_RX_ERR_FRAME;
- if (I_IGNBRK(info->tty)) {
- info->ignore_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE;
- /*
- * If we're ignore parity and break indicators, ignore
- * overruns too. (For real raw support).
- */
- if (I_IGNPAR(info->tty))
- info->ignore_status_mask |= \
- VAC_UART_STATUS_RX_ERR_OVERRUN;
- }
- /*
- * !!! ignore all characters if CREAD is not set
- */
- if ((cflag & CREAD) == 0)
- info->ignore_status_mask |= VAC_UART_STATUS_RX_READY;
- save_flags(flags); cli();
-
-
- switch (baud) {
- default:
- case 9600:
- cval |= VAC_UART_MODE_BAUD(7);
- break;
- case 4800:
- cval |= VAC_UART_MODE_BAUD(6);
- break;
- case 2400:
- cval |= VAC_UART_MODE_BAUD(5);
- break;
- case 1200:
- cval |= VAC_UART_MODE_BAUD(4);
- break;
- case 600:
- cval |= VAC_UART_MODE_BAUD(3);
- break;
- case 300:
- cval |= VAC_UART_MODE_BAUD(2);
- break;
-#ifndef QUAD_UART_SPEED
- case 150:
-#else
- case 38400:
-#endif
- cval |= VAC_UART_MODE_BAUD(1);
- break;
-#ifndef QUAD_UART_SPEED
- case 75:
-#else
- case 19200:
-#endif
- cval |= VAC_UART_MODE_BAUD(0);
- break;
- }
-
- /* Baget VAC need some adjustments for computed value */
- cval = vac_uart_mode_fixup(cval);
-
- serial_outp(info, VAC_UART_MODE, cval);
- restore_flags(flags);
-}
-
-static void rs_put_char(struct tty_struct *tty, unsigned char ch)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_put_char"))
- return;
-
- if (!tty || !info->xmit_buf)
- return;
-
- save_flags(flags); cli();
- if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
- restore_flags(flags);
- return;
- }
-
- info->xmit_buf[info->xmit_head++] = ch;
- info->xmit_head &= SERIAL_XMIT_SIZE-1;
- info->xmit_cnt++;
- restore_flags(flags);
-}
-
-static void rs_flush_chars(struct tty_struct *tty)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
- return;
-
- if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
- !info->xmit_buf)
- return;
-
- save_flags(flags); cli();
- info->IER |= VAC_UART_INT_TX_EMPTY;
- serial_out(info, VAC_UART_INT_MASK, info->IER);
- restore_flags(flags);
-}
-
-static int rs_write(struct tty_struct * tty, int from_user,
- const unsigned char *buf, int count)
-{
- int c, ret = 0;
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_write"))
- return 0;
-
- if (!tty || !info->xmit_buf || !tmp_buf)
- return 0;
-
- save_flags(flags);
- if (from_user) {
- down(&tmp_buf_sem);
- while (1) {
- c = MIN(count,
- MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - info->xmit_head));
- if (c <= 0)
- break;
-
- c -= copy_from_user(tmp_buf, buf, c);
- if (!c) {
- if (!ret)
- ret = -EFAULT;
- break;
- }
- cli();
- c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - info->xmit_head));
- memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
- info->xmit_head = ((info->xmit_head + c) &
- (SERIAL_XMIT_SIZE-1));
- info->xmit_cnt += c;
- restore_flags(flags);
- buf += c;
- count -= c;
- ret += c;
- }
- up(&tmp_buf_sem);
- } else {
- while (1) {
- cli();
- c = MIN(count,
- MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - info->xmit_head));
- if (c <= 0) {
- restore_flags(flags);
- break;
- }
- memcpy(info->xmit_buf + info->xmit_head, buf, c);
- info->xmit_head = ((info->xmit_head + c) &
- (SERIAL_XMIT_SIZE-1));
- info->xmit_cnt += c;
- restore_flags(flags);
- buf += c;
- count -= c;
- ret += c;
- }
- }
- if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
- !(info->IER & VAC_UART_INT_TX_EMPTY)) {
- info->IER |= VAC_UART_INT_TX_EMPTY;
- serial_out(info, VAC_UART_INT_MASK, info->IER);
- }
- return ret;
-}
-
-static int rs_write_room(struct tty_struct *tty)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- int ret;
-
- if (serial_paranoia_check(info, tty->name, "rs_write_room"))
- return 0;
- ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
- if (ret < 0)
- ret = 0;
- return ret;
-}
-
-static int rs_chars_in_buffer(struct tty_struct *tty)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
-
- if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
- return 0;
- return info->xmit_cnt;
-}
-
-static void rs_flush_buffer(struct tty_struct *tty)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
- return;
-
- save_flags(flags); cli();
- info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- restore_flags(flags);
-
- wake_up_interruptible(&tty->write_wait);
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
-}
-
-/*
- * This function is used to send a high-priority XON/XOFF character to
- * the device
- */
-static void rs_send_xchar(struct tty_struct *tty, char ch)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
-
- if (serial_paranoia_check(info, tty->name, "rs_send_char"))
- return;
-
- info->x_char = ch;
- if (ch) {
- /* Make sure transmit interrupts are on */
- info->IER |= VAC_UART_INT_TX_EMPTY;
- serial_out(info, VAC_UART_INT_MASK, info->IER);
- }
-}
-
-/*
- * ------------------------------------------------------------
- * rs_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void rs_throttle(struct tty_struct * tty)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-#ifdef SERIAL_DEBUG_THROTTLE
- char buf[64];
-
- baget_printk("throttle %s: %d....\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
-#endif
-
- if (serial_paranoia_check(info, tty->name, "rs_throttle"))
- return;
-
- if (I_IXOFF(tty))
- rs_send_xchar(tty, STOP_CHAR(tty));
-}
-
-static void rs_unthrottle(struct tty_struct * tty)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
-#ifdef SERIAL_DEBUG_THROTTLE
- char buf[64];
-
- baget_printk("unthrottle %s: %d....\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
-#endif
-
- if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
- return;
-
- if (I_IXOFF(tty)) {
- if (info->x_char)
- info->x_char = 0;
- else
- rs_send_xchar(tty, START_CHAR(tty));
- }
-}
-
-/*
- * ------------------------------------------------------------
- * rs_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-static int get_serial_info(struct async_struct * info,
- struct serial_struct * retinfo)
-{
- struct serial_struct tmp;
- struct serial_state *state = info->state;
-
- if (!retinfo)
- return -EFAULT;
- memset(&tmp, 0, sizeof(tmp));
- tmp.type = state->type;
- tmp.line = state->line;
- tmp.port = state->port;
- tmp.irq = state->irq;
- tmp.flags = state->flags;
- tmp.xmit_fifo_size = state->xmit_fifo_size;
- tmp.baud_base = state->baud_base;
- tmp.close_delay = state->close_delay;
- tmp.closing_wait = state->closing_wait;
- tmp.custom_divisor = state->custom_divisor;
- tmp.hub6 = state->hub6;
- if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
- return -EFAULT;
- return 0;
-}
-
-static int set_serial_info(struct async_struct * info,
- struct serial_struct * new_info)
-{
- struct serial_struct new_serial;
- struct serial_state old_state, *state;
- unsigned int i,change_irq,change_port;
- int retval = 0;
-
- if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
- return -EFAULT;
- state = info->state;
- old_state = *state;
-
- change_irq = new_serial.irq != state->irq;
- change_port = (new_serial.port != state->port) ||
- (new_serial.hub6 != state->hub6);
-
- if (!capable(CAP_SYS_ADMIN)) {
- if (change_irq || change_port ||
- (new_serial.baud_base != state->baud_base) ||
- (new_serial.type != state->type) ||
- (new_serial.close_delay != state->close_delay) ||
- (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
- ((new_serial.flags & ~ASYNC_USR_MASK) !=
- (state->flags & ~ASYNC_USR_MASK)))
- return -EPERM;
- state->flags = ((state->flags & ~ASYNC_USR_MASK) |
- (new_serial.flags & ASYNC_USR_MASK));
- info->flags = ((state->flags & ~ASYNC_USR_MASK) |
- (info->flags & ASYNC_USR_MASK));
- state->custom_divisor = new_serial.custom_divisor;
- goto check_and_exit;
- }
-
- new_serial.irq = new_serial.irq;
-
- if ((new_serial.irq >= NR_IRQS) || (new_serial.port > 0xffff) ||
- (new_serial.baud_base == 0) || (new_serial.type < PORT_UNKNOWN) ||
- (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
- (new_serial.type == PORT_STARTECH)) {
- return -EINVAL;
- }
-
- if ((new_serial.type != state->type) ||
- (new_serial.xmit_fifo_size <= 0))
- new_serial.xmit_fifo_size =
- uart_config[state->type].dfl_xmit_fifo_size;
-
- /* Make sure address is not already in use */
- if (new_serial.type) {
- for (i = 0 ; i < NR_PORTS; i++)
- if ((state != &rs_table[i]) &&
- (rs_table[i].port == new_serial.port) &&
- rs_table[i].type)
- return -EADDRINUSE;
- }
-
- if ((change_port || change_irq) && (state->count > 1))
- return -EBUSY;
-
- /*
- * OK, past this point, all the error checking has been done.
- * At this point, we start making changes.....
- */
-
- state->baud_base = new_serial.baud_base;
- state->flags = ((state->flags & ~ASYNC_FLAGS) |
- (new_serial.flags & ASYNC_FLAGS));
- info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
- (info->flags & ASYNC_INTERNAL_FLAGS));
- state->custom_divisor = new_serial.custom_divisor;
- state->type = new_serial.type;
- state->close_delay = new_serial.close_delay * HZ/100;
- state->closing_wait = new_serial.closing_wait * HZ/100;
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
- info->xmit_fifo_size = state->xmit_fifo_size =
- new_serial.xmit_fifo_size;
-
- release_region(state->port,8);
- if (change_port || change_irq) {
- /*
- * We need to shutdown the serial port at the old
- * port/irq combination.
- */
- shutdown(info);
- state->irq = new_serial.irq;
- info->port = state->port = new_serial.port;
- info->hub6 = state->hub6 = new_serial.hub6;
- }
- if (state->type != PORT_UNKNOWN)
- request_region(state->port,8,"serial(set)");
-
-
-check_and_exit:
- if (!state->port || !state->type)
- return 0;
- if (info->flags & ASYNC_INITIALIZED) {
- if (((old_state.flags & ASYNC_SPD_MASK) !=
- (state->flags & ASYNC_SPD_MASK)) ||
- (old_state.custom_divisor != state->custom_divisor)) {
- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- info->tty->alt_speed = 57600;
- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- info->tty->alt_speed = 115200;
- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- info->tty->alt_speed = 230400;
- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- info->tty->alt_speed = 460800;
- change_speed(info);
- }
- } else
- retval = startup(info);
- return retval;
-}
-
-
-/*
- * get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * is emptied. On bus types like RS485, the transmitter must
- * release the bus after transmitting. This must be done when
- * the transmit shift register is empty, not be done when the
- * transmit holding register is empty. This functionality
- * allows an RS485 driver to be written in user space.
- */
-static int get_lsr_info(struct async_struct * info, unsigned int *value)
-{
- unsigned short status;
- unsigned int result;
- unsigned long flags;
-
- save_flags(flags); cli();
- status = serial_inw(info, VAC_UART_INT_STATUS);
- restore_flags(flags);
- result = ((status & VAC_UART_STATUS_TX_EMPTY) ? TIOCSER_TEMT : 0);
- return put_user(result,value);
-}
-
-
-static int get_modem_info(struct async_struct * info, unsigned int *value)
-{
- unsigned int result;
-
- result = TIOCM_CAR | TIOCM_DSR;
- return put_user(result,value);
-}
-
-static int set_modem_info(struct async_struct * info, unsigned int cmd,
- unsigned int *value)
-{
- unsigned int arg;
-
- if (get_user(arg, value))
- return -EFAULT;
- switch (cmd) {
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int do_autoconfig(struct async_struct * info)
-{
- int retval;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if (info->state->count > 1)
- return -EBUSY;
-
- shutdown(info);
-
- autoconfig(info->state);
-
- retval = startup(info);
- if (retval)
- return retval;
- return 0;
-}
-
-/*
- * rs_break() --- routine which turns the break handling on or off
- */
-static void rs_break(struct tty_struct *tty, int break_state)
-{
- struct async_struct * info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_break"))
- return;
-
- if (!info->port)
- return;
- save_flags(flags); cli();
- if (break_state == -1)
- serial_outp(info, VAC_UART_MODE,
- serial_inp(info, VAC_UART_MODE) | \
- VAC_UART_MODE_SEND_BREAK);
- else
- serial_outp(info, VAC_UART_MODE,
- serial_inp(info, VAC_UART_MODE) & \
- ~VAC_UART_MODE_SEND_BREAK);
- restore_flags(flags);
-}
-
-static int rs_ioctl(struct tty_struct *tty, struct file * file,
- unsigned int cmd, unsigned long arg)
-{
- int error;
- struct async_struct * info = (struct async_struct *)tty->driver_data;
- struct async_icount cprev, cnow; /* kernel counter temps */
- struct serial_icounter_struct *p_cuser; /* user space */
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
- return -ENODEV;
-
- if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
- (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
- (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
- }
-
- switch (cmd) {
- case TIOCMGET:
- return get_modem_info(info, (unsigned int *) arg);
- case TIOCMBIS:
- case TIOCMBIC:
- case TIOCMSET:
- return set_modem_info(info, cmd, (unsigned int *) arg);
- case TIOCGSERIAL:
- return get_serial_info(info,
- (struct serial_struct *) arg);
- case TIOCSSERIAL:
- return set_serial_info(info,
- (struct serial_struct *) arg);
- case TIOCSERCONFIG:
- return do_autoconfig(info);
-
- case TIOCSERGETLSR: /* Get line status register */
- return get_lsr_info(info, (unsigned int *) arg);
-
- case TIOCSERGSTRUCT:
- if (copy_to_user((struct async_struct *) arg,
- info, sizeof(struct async_struct)))
- return -EFAULT;
- return 0;
-
- /*
- * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)to change
- * - mask passed in arg for lines of interest
- * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
- * Caller should use TIOCGICOUNT to see which one it was
- */
- case TIOCMIWAIT:
- save_flags(flags); cli();
- /* note the counters on entry */
- cprev = info->state->icount;
- restore_flags(flags);
- while (1) {
- interruptible_sleep_on(&info->delta_msr_wait);
- /* see if a signal did it */
- if (signal_pending(current))
- return -ERESTARTSYS;
- save_flags(flags); cli();
- cnow = info->state->icount; /* atomic copy */
- restore_flags(flags);
- if (cnow.rng == cprev.rng &&
- cnow.dsr == cprev.dsr &&
- cnow.dcd == cprev.dcd &&
- cnow.cts == cprev.cts)
- return -EIO; /* no change => error */
- if ( ((arg & TIOCM_RNG) &&
- (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) &&
- (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) &&
- (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) &&
- (cnow.cts != cprev.cts)) ) {
- return 0;
- }
- cprev = cnow;
- }
- /* NOTREACHED */
-
- /*
- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
- * Return: write counters to the user passed counter struct
- * NB: both 1->0 and 0->1 transitions are counted except for
- * RI where only 0->1 is counted.
- */
- case TIOCGICOUNT:
- save_flags(flags); cli();
- cnow = info->state->icount;
- restore_flags(flags);
- p_cuser = (struct serial_icounter_struct *) arg;
- error = put_user(cnow.cts, &p_cuser->cts);
- if (error) return error;
- error = put_user(cnow.dsr, &p_cuser->dsr);
- if (error) return error;
- error = put_user(cnow.rng, &p_cuser->rng);
- if (error) return error;
- error = put_user(cnow.dcd, &p_cuser->dcd);
- if (error) return error;
- error = put_user(cnow.rx, &p_cuser->rx);
- if (error) return error;
- error = put_user(cnow.tx, &p_cuser->tx);
- if (error) return error;
- error = put_user(cnow.frame, &p_cuser->frame);
- if (error) return error;
- error = put_user(cnow.overrun, &p_cuser->overrun);
- if (error) return error;
- error = put_user(cnow.parity, &p_cuser->parity);
- if (error) return error;
- error = put_user(cnow.brk, &p_cuser->brk);
- if (error) return error;
- error = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
-
- if (error) return error;
- return 0;
-
- case TIOCSERGWILD:
- case TIOCSERSWILD:
- /* "setserial -W" is called in Debian boot */
- printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
- return 0;
-
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned int cflag = tty->termios->c_cflag;
-
- if ( (cflag == old_termios->c_cflag)
- && ( RELEVANT_IFLAG(tty->termios->c_iflag)
- == RELEVANT_IFLAG(old_termios->c_iflag)))
- return;
-
- change_speed(info);
-
- /* Handle turning off CRTSCTS */
- if ((old_termios->c_cflag & CRTSCTS) &&
- !(cflag & CRTSCTS)) {
- tty->hw_stopped = 0;
- rs_start(tty);
- }
-
-}
-
-/*
- * ------------------------------------------------------------
- * rs_close()
- *
- * This routine is called when the serial port gets closed. First, we
- * wait for the last remaining data to be sent. Then, we unlink its
- * async structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- * ------------------------------------------------------------
- */
-static void rs_close(struct tty_struct *tty, struct file * filp)
-{
- struct async_struct * info = (struct async_struct *)tty->driver_data;
- struct serial_state *state;
- unsigned long flags;
-
- if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
- return;
-
- state = info->state;
-
- save_flags(flags); cli();
-
- if (tty_hung_up_p(filp)) {
- DBG_CNT("before DEC-hung");
- MOD_DEC_USE_COUNT;
- restore_flags(flags);
- return;
- }
-
-#ifdef SERIAL_DEBUG_OPEN
- baget_printk("rs_close ttys%d, count = %d\n",
- info->line, state->count);
-#endif
- if ((tty->count == 1) && (state->count != 1)) {
- /*
- * Uh, oh. tty->count is 1, which means that the tty
- * structure will be freed. state->count should always
- * be one in these conditions. If it's greater than
- * one, we've got real problems, since it means the
- * serial port won't be shutdown.
- */
- baget_printk("rs_close: bad serial port count; "
- "tty->count is 1, "
- "state->count is %d\n", state->count);
- state->count = 1;
- }
- if (--state->count < 0) {
- baget_printk("rs_close: bad serial port count for "
- "ttys%d: %d\n",
- info->line, state->count);
- state->count = 0;
- }
- if (state->count) {
- DBG_CNT("before DEC-2");
- MOD_DEC_USE_COUNT;
- restore_flags(flags);
- return;
- }
- info->flags |= ASYNC_CLOSING;
- /*
- * Now we wait for the transmit buffer to clear; and we notify
- * the line discipline to only process XON/XOFF characters.
- */
- tty->closing = 1;
- if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, info->closing_wait);
- /*
- * At this point we stop accepting input. To do this, we
- * disable the receive line status interrupts, and tell the
- * interrupt driver to stop checking the data ready bit in the
- * line status register.
- */
- info->IER &= ~(VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS);
- info->read_status_mask &= ~VAC_UART_STATUS_RX_READY;
- if (info->flags & ASYNC_INITIALIZED) {
- serial_outw(info, VAC_UART_INT_MASK, info->IER);
- /*
- * Before we drop DTR, make sure the UART transmitter
- * has completely drained; this is especially
- * important if there is a transmit FIFO!
- */
- rs_wait_until_sent(tty, info->timeout);
- }
- shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
- tty->closing = 0;
- info->event = 0;
- info->tty = 0;
- if (info->blocked_open) {
- if (info->close_delay) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(info->close_delay);
- }
- wake_up_interruptible(&info->open_wait);
- }
- info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
- MOD_DEC_USE_COUNT;
- restore_flags(flags);
-}
-
-/*
- * rs_wait_until_sent() --- wait until the transmitter is empty
- */
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
-{
- struct async_struct * info = (struct async_struct *)tty->driver_data;
- unsigned long orig_jiffies, char_time;
- int lsr;
-
- if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
- return;
-
- if (info->state->type == PORT_UNKNOWN)
- return;
-
- if (info->xmit_fifo_size == 0)
- return; /* Just in case.... */
-
- orig_jiffies = jiffies;
- /*
- * Set the check interval to be 1/5 of the estimated time to
- * send a single character, and make it at least 1. The check
- * interval should also be less than the timeout.
- *
- * Note: we have to use pretty tight timings here to satisfy
- * the NIST-PCTS.
- */
- char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
- char_time = char_time / 5;
- if (char_time == 0)
- char_time = 1;
- if (timeout)
- char_time = MIN(char_time, timeout);
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
- baget_printk("In rs_wait_until_sent(%d) check=%lu...",
- timeout, char_time);
- baget_printk("jiff=%lu...", jiffies);
-#endif
- while (!((lsr = serial_inp(info, VAC_UART_INT_STATUS)) & \
- VAC_UART_STATUS_TX_EMPTY)) {
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
- baget_printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
-#endif
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(char_time);
- if (signal_pending(current))
- break;
- if (timeout && time_after(jiffies, orig_jiffies + timeout))
- break;
- }
- current->state = TASK_RUNNING;
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
- baget_printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
-#endif
-}
-
-/*
- * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void rs_hangup(struct tty_struct *tty)
-{
- struct async_struct * info = (struct async_struct *)tty->driver_data;
- struct serial_state *state = info->state;
-
- if (serial_paranoia_check(info, tty->name, "rs_hangup"))
- return;
-
- state = info->state;
-
- rs_flush_buffer(tty);
- shutdown(info);
- info->event = 0;
- state->count = 0;
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = 0;
- wake_up_interruptible(&info->open_wait);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_open() and friends
- * ------------------------------------------------------------
- */
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
- struct async_struct *info)
-{
- DECLARE_WAITQUEUE(wait, current);
- struct serial_state *state = info->state;
- int retval;
- int do_clocal = 0, extra_count = 0;
- unsigned long flags;
-
- /*
- * If the device is in the middle of being closed, then block
- * until it's done, and then try again.
- */
- if (tty_hung_up_p(filp) ||
- (info->flags & ASYNC_CLOSING)) {
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
-#ifdef SERIAL_DO_RESTART
- return ((info->flags & ASYNC_HUP_NOTIFY) ?
- -EAGAIN : -ERESTARTSYS);
-#else
- return -EAGAIN;
-#endif
- }
-
- /*
- * If non-blocking mode is set, or the port is not enabled,
- * then make the check up front and then exit.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
- info->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;
- }
-
- if (tty->termios->c_cflag & CLOCAL)
- do_clocal = 1;
-
- /*
- * Block waiting for the carrier detect and the line to become
- * free (i.e., not in use by the callout). While we are in
- * this loop, state->count is dropped by one, so that
- * rs_close() knows when to free things. We restore it upon
- * exit, either normal or abnormal.
- */
- retval = 0;
- add_wait_queue(&info->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
- baget_printk("block_til_ready before block: ttys%d, count = %d\n",
- state->line, state->count);
-#endif
- save_flags(flags); cli();
- if (!tty_hung_up_p(filp)) {
- extra_count = 1;
- state->count--;
- }
- restore_flags(flags);
- info->blocked_open++;
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(info->flags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
- if (info->flags & ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
-#else
- retval = -EAGAIN;
-#endif
- break;
- }
- if (!(info->flags & ASYNC_CLOSING))
- break;
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
-#ifdef SERIAL_DEBUG_OPEN
- baget_printk("block_til_ready blocking: ttys%d, count = %d\n",
- info->line, state->count);
-#endif
- schedule();
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&info->open_wait, &wait);
- if (extra_count)
- state->count++;
- info->blocked_open--;
-#ifdef SERIAL_DEBUG_OPEN
- baget_printk("block_til_ready after blocking: ttys%d, count = %d\n",
- info->line, state->count);
-#endif
- if (retval)
- return retval;
- info->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;
-}
-
-static int get_async_struct(int line, struct async_struct **ret_info)
-{
- struct async_struct *info;
- struct serial_state *sstate;
-
- sstate = rs_table + line;
- sstate->count++;
- if (sstate->info) {
- *ret_info = sstate->info;
- return 0;
- }
- info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
- if (!info) {
- sstate->count--;
- return -ENOMEM;
- }
- memset(info, 0, sizeof(struct async_struct));
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- init_waitqueue_head(&info->delta_msr_wait);
- info->magic = SERIAL_MAGIC;
- info->port = sstate->port;
- info->flags = sstate->flags;
- info->xmit_fifo_size = sstate->xmit_fifo_size;
- info->line = line;
- info->tqueue.routine = do_softint;
- info->tqueue.data = info;
- info->state = sstate;
- if (sstate->info) {
- kfree(info);
- *ret_info = sstate->info;
- return 0;
- }
- *ret_info = sstate->info = info;
- return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened. It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain. It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int rs_open(struct tty_struct *tty, struct file * filp)
-{
- struct async_struct *info;
- int retval, line;
- unsigned long page;
-
- MOD_INC_USE_COUNT;
- line = tty->index;
- if ((line < 0) || (line >= NR_PORTS)) {
- MOD_DEC_USE_COUNT;
- return -ENODEV;
- }
- retval = get_async_struct(line, &info);
- if (retval) {
- MOD_DEC_USE_COUNT;
- return retval;
- }
- tty->driver_data = info;
- info->tty = tty;
- if (serial_paranoia_check(info, tty->name, "rs_open")) {
- /* MOD_DEC_USE_COUNT; "info->tty" will cause this */
- return -ENODEV;
- }
-
-#ifdef SERIAL_DEBUG_OPEN
- baget_printk("rs_open %s, count = %d\n", tty->name,
- info->state->count);
-#endif
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-
- if (!tmp_buf) {
- page = get_zeroed_page(GFP_KERNEL);
- if (!page) {
- /* MOD_DEC_USE_COUNT; "info->tty" will cause this */
- return -ENOMEM;
- }
- if (tmp_buf)
- free_page(page);
- else
- tmp_buf = (unsigned char *) page;
- }
-
- /*
- * If the port is the middle of closing, bail out now
- */
- if (tty_hung_up_p(filp) ||
- (info->flags & ASYNC_CLOSING)) {
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
- /* MOD_DEC_USE_COUNT; "info->tty" will cause this */
-#ifdef SERIAL_DO_RESTART
- return ((info->flags & ASYNC_HUP_NOTIFY) ?
- -EAGAIN : -ERESTARTSYS);
-#else
- return -EAGAIN;
-#endif
- }
-
- /*
- * Start up serial port
- */
- retval = startup(info);
- if (retval) {
- /* MOD_DEC_USE_COUNT; "info->tty" will cause this */
- return retval;
- }
-
- retval = block_til_ready(tty, filp, info);
- if (retval) {
- /* MOD_DEC_USE_COUNT; "info->tty" will cause this */
-#ifdef SERIAL_DEBUG_OPEN
- baget_printk("rs_open returning after block_til_ready "
- "with %d\n",
- retval);
-#endif
- return retval;
- }
-
-#ifdef CONFIG_SERIAL_CONSOLE
- if (sercons.cflag && sercons.index == line) {
- tty->termios->c_cflag = sercons.cflag;
- sercons.cflag = 0;
- change_speed(info);
- }
-#endif
-
-#ifdef SERIAL_DEBUG_OPEN
- baget_printk("rs_open %s successful...", tty->name);
-#endif
- return 0;
-}
-
-/*
- * /proc fs routines....
- */
-
-static inline int line_info(char *buf, struct serial_state *state)
-{
- struct async_struct *info = state->info, scr_info;
- int ret;
-
- ret = sprintf(buf, "%d: uart:%s port:%X irq:%d",
- state->line, uart_config[state->type].name,
- state->port, state->irq);
-
- if (!state->port || (state->type == PORT_UNKNOWN)) {
- ret += sprintf(buf+ret, "\n");
- return ret;
- }
-
- /*
- * Figure out the current RS-232 lines
- */
- if (!info) {
- info = &scr_info; /* This is just for serial_{in,out} */
-
- info->magic = SERIAL_MAGIC;
- info->port = state->port;
- info->flags = state->flags;
- info->quot = 0;
- info->tty = 0;
- }
-
- if (info->quot) {
- ret += sprintf(buf+ret, " baud:%d",
- state->baud_base / info->quot);
- }
-
- ret += sprintf(buf+ret, " tx:%d rx:%d",
- state->icount.tx, state->icount.rx);
-
- if (state->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
-
- if (state->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
-
- if (state->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
-
- if (state->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
-
- return ret;
-}
-
-int rs_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
-{
- int i, len = 0, l;
- off_t begin = 0;
-
- len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
- for (i = 0; i < NR_PORTS && len < 4000; i++) {
- l = line_info(page + len, &rs_table[i]);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
- }
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
-}
-
-/*
- * ---------------------------------------------------------------------
- * rs_init() and friends
- *
- * rs_init() is called at boot-time to initialize the serial driver.
- * ---------------------------------------------------------------------
- */
-
-/*
- * This routine prints out the appropriate serial driver version
- * number, and identifies which options were configured into this
- * driver.
- */
-static _INLINE_ void show_serial_version(void)
-{
- printk(KERN_INFO "%s version %s with", serial_name, serial_version);
-#ifdef CONFIG_SERIAL_SHARE_IRQ
- printk(" SHARE_IRQ");
-#endif
-#define SERIAL_OPT
-#ifdef CONFIG_SERIAL_DETECT_IRQ
- printk(" DETECT_IRQ");
-#endif
-#ifdef SERIAL_OPT
- printk(" enabled\n");
-#else
- printk(" no serial options enabled\n");
-#endif
-#undef SERIAL_OPT
-}
-
-
-/*
- * This routine is called by rs_init() to initialize a specific serial
- * port. It determines what type of UART chip this serial port is
- * using: 8250, 16450, 16550, 16550A. The important question is
- * whether or not this UART is a 16550A or not, since this will
- * determine whether or not we can use its FIFO features or not.
- */
-
-/*
- * Functionality of this function is reduced: we already know we have a VAC,
- * but still need to perform some important actions (see code :-).
- */
-static void autoconfig(struct serial_state * state)
-{
- struct async_struct *info, scr_info;
- unsigned long flags;
-
- /* Setting up important parameters */
- state->type = VAC_UART_TYPE;
- state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size;
-
- info = &scr_info; /* This is just for serial_{in,out} */
-
- info->magic = SERIAL_MAGIC;
- info->port = state->port;
- info->flags = state->flags;
-
- save_flags(flags); cli();
-
- /* + Flush VAC input fifo */
- (void)serial_in(info, VAC_UART_RX);
- (void)serial_in(info, VAC_UART_RX);
- (void)serial_in(info, VAC_UART_RX);
- (void)serial_in(info, VAC_UART_RX);
-
- /* Disable interrupts */
- serial_outp(info, VAC_UART_INT_MASK, 0);
-
- restore_flags(flags);
-}
-
-int register_serial(struct serial_struct *req);
-void unregister_serial(int line);
-
-EXPORT_SYMBOL(register_serial);
-EXPORT_SYMBOL(unregister_serial);
-
-/*
- * Important function for VAC UART check and reanimation.
- */
-
-static void rs_timer(unsigned long dummy)
-{
- static unsigned long last_strobe = 0;
- struct async_struct *info;
- unsigned int i;
- unsigned long flags;
-
- if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
- for (i=1; i < NR_IRQS; i++) {
- info = IRQ_ports[i];
- if (!info)
- continue;
- save_flags(flags); cli();
-#ifdef CONFIG_SERIAL_SHARE_IRQ
- if (info->next_port) {
- do {
- serial_out(info, VAC_UART_INT_MASK, 0);
- info->IER |= VAC_UART_INT_TX_EMPTY;
- serial_out(info, VAC_UART_INT_MASK,
- info->IER);
- info = info->next_port;
- } while (info);
- rs_interrupt(i, NULL, NULL);
- } else
-#endif /* CONFIG_SERIAL_SHARE_IRQ */
- rs_interrupt_single(i, NULL, NULL);
- restore_flags(flags);
- }
- }
- last_strobe = jiffies;
- mod_timer(&vacs_timer, jiffies + RS_STROBE_TIME);
-
- /*
- * It looks this code for case we share IRQ with console...
- */
-
- if (IRQ_ports[0]) {
- save_flags(flags); cli();
-#ifdef CONFIG_SERIAL_SHARE_IRQ
- rs_interrupt(0, NULL, NULL);
-#else
- rs_interrupt_single(0, NULL, NULL);
-#endif
- restore_flags(flags);
-
- mod_timer(&vacs_timer, jiffies + IRQ_timeout[0] - 2);
- }
-}
-
-static struct tty_operations rs_ops = {
- .open = rs_open,
- .close = rs_close,
- .write = rs_write,
- .put_char = rs_put_char,
- .flush_chars = rs_flush_chars,
- .write_room = rs_write_room,
- .chars_in_buffer = rs_chars_in_buffer,
- .flush_buffer = rs_flush_buffer,
- .ioctl = rs_ioctl,
- .throttle = rs_throttle,
- .unthrottle = rs_unthrottle,
- .send_xchar = rs_send_xchar,
- .set_termios = rs_set_termios,
- .stop = rs_stop,
- .start = rs_start,
- .hangup = rs_hangup,
- .break_ctl = rs_break,
- .wait_until_sent = rs_wait_until_sent,
- .read_proc = rs_read_proc,
-};
-
-/*
- * The serial driver boot-time initialization code!
- */
-int __init rs_init(void)
-{
- int i;
- struct serial_state * state;
- extern void atomwide_serial_init (void);
- extern void dualsp_serial_init (void);
-
-#ifdef CONFIG_ATOMWIDE_SERIAL
- atomwide_serial_init ();
-#endif
-#ifdef CONFIG_DUALSP_SERIAL
- dualsp_serial_init ();
-#endif
-
- init_bh(SERIAL_BH, do_serial_bh);
- init_timer(&vacs_timer);
- vacs_timer.function = rs_timer;
- vacs_timer.expires = 0;
-
- for (i = 0; i < NR_IRQS; i++) {
- IRQ_ports[i] = 0;
- IRQ_timeout[i] = 0;
- }
-
-
-/*
- * It is not a good idea to share interrupts with console,
- * but it looks we cannot avoid it.
- */
-#if 0
-
-#ifdef CONFIG_SERIAL_CONSOLE
- /*
- * The interrupt of the serial console port
- * can't be shared.
- */
- if (sercons.flags & CON_CONSDEV) {
- for(i = 0; i < NR_PORTS; i++)
- if (i != sercons.index &&
- rs_table[i].irq == rs_table[sercons.index].irq)
- rs_table[i].irq = 0;
- }
-#endif
-
-#endif
- serial_driver = alloc_tty_driver(NR_PORTS);
- if (!serial_driver)
- return -ENOMEM;
-
- show_serial_version();
-
- /* Initialize the tty_driver structure */
-
- serial_driver->driver_name = "serial";
- serial_driver->name = "ttyS";
- serial_driver->major = TTY_MAJOR;
- serial_driver->minor_start = 64;
- serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
- serial_driver->subtype = SERIAL_TYPE_NORMAL;
- serial_driver->init_termios = tty_std_termios;
- serial_driver->init_termios.c_cflag =
- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- serial_driver->flags = TTY_DRIVER_REAL_RAW;
- tty_set_operations(serial_driver, &rs_ops);
-
- if (tty_register_driver(serial_driver))
- panic("Couldn't register serial driver\n");
-
- for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
- state->magic = SSTATE_MAGIC;
- state->line = i;
- state->type = PORT_UNKNOWN;
- state->custom_divisor = 0;
- state->close_delay = 5*HZ/10;
- state->closing_wait = 30*HZ;
- state->icount.cts = state->icount.dsr =
- state->icount.rng = state->icount.dcd = 0;
- state->icount.rx = state->icount.tx = 0;
- state->icount.frame = state->icount.parity = 0;
- state->icount.overrun = state->icount.brk = 0;
- state->irq = state->irq;
- if (check_region(state->port,8))
- continue;
- if (state->flags & ASYNC_BOOT_AUTOCONF)
- autoconfig(state);
- }
-
- /*
- * Detect the IRQ only once every port is initialised,
- * because some 16450 do not reset to 0 the MCR register.
- */
- for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
- if (state->type == PORT_UNKNOWN)
- continue;
- printk(KERN_INFO "ttyS%02d%s at 0x%04x (irq = %d) is a %s\n",
- state->line,
- (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
- state->port, state->irq,
- uart_config[state->type].name);
- }
- return 0;
-}
-
-/*
- * register_serial and unregister_serial allows for serial ports to be
- * configured at run-time, to support PCMCIA modems.
- */
-int register_serial(struct serial_struct *req)
-{
- int i;
- unsigned long flags;
- struct serial_state *state;
-
- save_flags(flags);
- cli();
- for (i = 0; i < NR_PORTS; i++) {
- if (rs_table[i].port == req->port)
- break;
- }
- if (i == NR_PORTS) {
- for (i = 0; i < NR_PORTS; i++)
- if ((rs_table[i].type == PORT_UNKNOWN) &&
- (rs_table[i].count == 0))
- break;
- }
- if (i == NR_PORTS) {
- restore_flags(flags);
- return -1;
- }
- state = &rs_table[i];
- if (rs_table[i].count) {
- restore_flags(flags);
- printk("Couldn't configure serial #%d (port=%d,irq=%d): "
- "device already open\n", i, req->port, req->irq);
- return -1;
- }
- state->irq = req->irq;
- state->port = req->port;
- state->flags = req->flags;
-
- autoconfig(state);
- if (state->type == PORT_UNKNOWN) {
- restore_flags(flags);
- printk("register_serial(): autoconfig failed\n");
- return -1;
- }
- restore_flags(flags);
-
- printk(KERN_INFO "tty%02d at 0x%04x (irq = %d) is a %s\n",
- state->line, state->port, state->irq,
- uart_config[state->type].name);
- return state->line;
-}
-
-void unregister_serial(int line)
-{
- unsigned long flags;
- struct serial_state *state = &rs_table[line];
-
- save_flags(flags);
- cli();
- if (state->info && state->info->tty)
- tty_hangup(state->info->tty);
- state->type = PORT_UNKNOWN;
- printk(KERN_INFO "tty%02d unloaded\n", state->line);
- restore_flags(flags);
-}
-
-#ifdef MODULE
-int init_module(void)
-{
- return rs_init();
-}
-
-void cleanup_module(void)
-{
- unsigned long flags;
- int e1, e2;
- int i;
-
- printk("Unloading %s: version %s\n", serial_name, serial_version);
- save_flags(flags);
- cli();
-
- del_timer_sync(&vacs_timer);
- remove_bh(SERIAL_BH);
-
- if ((e1 = tty_unregister_driver(serial_driver)))
- printk("SERIAL: failed to unregister serial driver (%d)\n",
- e1);
- restore_flags(flags);
- put_tty_driver(serial_driver);
-
- for (i = 0; i < NR_PORTS; i++) {
- if (rs_table[i].type != PORT_UNKNOWN)
- release_region(rs_table[i].port, 8);
- }
- if (tmp_buf) {
- free_page((unsigned long) tmp_buf);
- tmp_buf = NULL;
- }
-}
-#endif /* MODULE */
-
-
-/*
- * ------------------------------------------------------------
- * Serial console driver
- * ------------------------------------------------------------
- */
-#ifdef CONFIG_SERIAL_CONSOLE
-
-#define BOTH_EMPTY (VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_TX_EMPTY)
-
-/*
- * Wait for transmitter & holding register to empty
- */
-static inline void wait_for_xmitr(struct async_struct *info)
-{
- int lsr;
- unsigned int tmout = 1000000;
-
- do {
- lsr = serial_inp(info, VAC_UART_INT_STATUS);
- if (--tmout == 0) break;
- } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
-}
-
-/*
- * Print a string to the serial port trying not to disturb
- * any possible real use of the port...
- */
-static void serial_console_write(struct console *co, const char *s,
- unsigned count)
-{
- struct serial_state *ser;
- int ier;
- unsigned i;
- struct async_struct scr_info; /* serial_{in,out} because HUB6 */
-
- ser = rs_table + co->index;
- scr_info.magic = SERIAL_MAGIC;
- scr_info.port = ser->port;
- scr_info.flags = ser->flags;
-
- /*
- * First save the IER then disable the interrupts
- */
- ier = serial_inp(&scr_info, VAC_UART_INT_MASK);
- serial_outw(&scr_info, VAC_UART_INT_MASK, 0x00);
-
- /*
- * Now, do each character
- */
- for (i = 0; i < count; i++, s++) {
- wait_for_xmitr(&scr_info);
-
- /*
- * Send the character out.
- * If a LF, also do CR...
- */
- serial_outp(&scr_info, VAC_UART_TX, (unsigned short)*s << 8);
- if (*s == 10) {
- wait_for_xmitr(&scr_info);
- serial_outp(&scr_info, VAC_UART_TX, 13 << 8);
- }
- }
-
- /*
- * Finally, Wait for transmitter & holding register to empty
- * and restore the IER
- */
- wait_for_xmitr(&scr_info);
- serial_outp(&scr_info, VAC_UART_INT_MASK, ier);
-}
-
-static struct tty_driver *serial_console_device(struct console *c, int *index)
-{
- *index = c->index;
- return serial_driver;
-}
-
-/*
- * Setup initial baud/bits/parity. We do two things here:
- * - construct a cflag setting for the first rs_open()
- * - initialize the serial port
- * Return non-zero if we didn't find a serial port.
- */
-static int __init serial_console_setup(struct console *co, char *options)
-{
- struct serial_state *ser;
- unsigned cval;
- int baud = 9600;
- int bits = 8;
- int parity = 'n';
- int cflag = CREAD | HUPCL | CLOCAL;
- int quot = 0;
- char *s;
- struct async_struct scr_info; /* serial_{in,out} because HUB6 */
-
- if (options) {
- baud = simple_strtoul(options, NULL, 10);
- s = options;
- while(*s >= '0' && *s <= '9')
- s++;
- if (*s) parity = *s++;
- if (*s) bits = *s - '0';
- }
-
- /*
- * Now construct a cflag setting.
- */
- switch(baud) {
- case 1200:
- cflag |= B1200;
- break;
- case 2400:
- cflag |= B2400;
- break;
- case 4800:
- cflag |= B4800;
- break;
- case 19200:
- cflag |= B19200;
- break;
- case 38400:
- cflag |= B38400;
- break;
- case 57600:
- cflag |= B57600;
- break;
- case 115200:
- cflag |= B115200;
- break;
- case 9600:
- default:
- cflag |= B9600;
- break;
- }
- switch(bits) {
- case 7:
- cflag |= CS7;
- break;
- default:
- case 8:
- cflag |= CS8;
- break;
- }
- switch(parity) {
- case 'o': case 'O':
- cflag |= PARODD;
- break;
- case 'e': case 'E':
- cflag |= PARENB;
- break;
- }
- co->cflag = cflag;
-
- /*
- * Divisor, bytesize and parity
- */
- ser = rs_table + co->index;
- scr_info.magic = SERIAL_MAGIC;
- scr_info.port = ser->port;
- scr_info.flags = ser->flags;
-
- quot = ser->baud_base / baud;
- cval = cflag & (CSIZE | CSTOPB);
-
- cval >>= 4;
-
- cval &= ~VAC_UART_MODE_PARITY_ENABLE;
- if (cflag & PARENB)
- cval |= VAC_UART_MODE_PARITY_ENABLE;
- if (cflag & PARODD)
- cval |= VAC_UART_MODE_PARITY_ODD;
-
- /*
- * Disable UART interrupts, set DTR and RTS high
- * and set speed.
- */
- switch (baud) {
- default:
- case 9600:
- cval |= VAC_UART_MODE_BAUD(7);
- break;
- case 4800:
- cval |= VAC_UART_MODE_BAUD(6);
- break;
- case 2400:
- cval |= VAC_UART_MODE_BAUD(5);
- break;
- case 1200:
- cval |= VAC_UART_MODE_BAUD(4);
- break;
- case 600:
- cval |= VAC_UART_MODE_BAUD(3);
- break;
- case 300:
- cval |= VAC_UART_MODE_BAUD(2);
- break;
-#ifndef QUAD_UART_SPEED
- case 150:
-#else
- case 38400:
-#endif
- cval |= VAC_UART_MODE_BAUD(1);
- break;
-#ifndef QUAD_UART_SPEED
- case 75:
-#else
- case 19200:
-#endif
- cval |= VAC_UART_MODE_BAUD(0);
- break;
- }
-
- /* Baget VAC need some adjustments for computed value */
- cval = vac_uart_mode_fixup(cval);
-
- serial_outp(&scr_info, VAC_UART_MODE, cval);
- serial_outp(&scr_info, VAC_UART_INT_MASK, 0);
-
- return 0;
-}
-
-static struct console sercons = {
- .name = "ttyS",
- .write = serial_console_write,
- .device = serial_console_device,
- .setup = serial_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
-};
-
-/*
- * Register console.
- */
-long __init serial_console_init(long kmem_start, long kmem_end)
-{
- register_console(&sercons);
- return kmem_start;
-}
-#endif
-
-#ifdef CONFIG_REMOTE_DEBUG
-#undef PRINT_DEBUG_PORT_INFO
-
-/*
- * This is the interface to the remote debugger stub.
- * I've put that here to be able to control the serial
- * device more directly.
- */
-
-static int initialized;
-
-static int rs_debug_init(struct async_struct *info)
-{
- int quot;
-
- autoconfig(info); /* autoconfigure ttyS0, whatever that is */
-
-#ifdef PRINT_DEBUG_PORT_INFO
- baget_printk("kgdb debug interface:: tty%02d at 0x%04x",
- info->line, info->port);
- switch (info->type) {
- case PORT_8250:
- baget_printk(" is a 8250\n");
- break;
- case PORT_16450:
- baget_printk(" is a 16450\n");
- break;
- case PORT_16550:
- baget_printk(" is a 16550\n");
- break;
- case PORT_16550A:
- baget_printk(" is a 16550A\n");
- break;
- case PORT_16650:
- baget_printk(" is a 16650\n");
- break;
- default:
- baget_printk(" is of unknown type -- unusable\n");
- break;
- }
-#endif
-
- if (info->port == PORT_UNKNOWN)
- return -1;
-
- /*
- * Clear all interrupts
- */
-
- (void)serial_inp(info, VAC_UART_INT_STATUS);
- (void)serial_inp(info, VAC_UART_RX);
-
- /*
- * Now, initialize the UART
- */
- serial_outp(info,VAC_UART_MODE,VAC_UART_MODE_INITIAL); /* reset DLAB */
- if (info->flags & ASYNC_FOURPORT) {
- info->MCR = UART_MCR_DTR | UART_MCR_RTS;
- info->MCR_noint = UART_MCR_DTR | UART_MCR_OUT1;
- } else {
- info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
- info->MCR_noint = UART_MCR_DTR | UART_MCR_RTS;
- }
-
- info->MCR = info->MCR_noint; /* no interrupts, please */
- /*
- * and set the speed of the serial port
- * (currently hardwired to 9600 8N1
- */
-
- quot = info->baud_base / 9600; /* baud rate is fixed to 9600 */
- /* FIXME: if rs_debug interface is needed, we need to set speed here */
-
- return 0;
-}
-
-int putDebugChar(char c)
-{
- struct async_struct *info = rs_table;
-
- if (!initialized) { /* need to init device first */
- if (rs_debug_init(info) == 0)
- initialized = 1;
- else
- return 0;
- }
-
- while ((serial_inw(info, VAC_UART_INT_STATUS) & \
- VAC_UART_STATUS_TX_EMPTY) == 0)
- ;
- serial_out(info, VAC_UART_TX, (unsigned short)c << 8);
-
- return 1;
-}
-
-char getDebugChar(void)
-{
- struct async_struct *info = rs_table;
-
- if (!initialized) { /* need to init device first */
- if (rs_debug_init(info) == 0)
- initialized = 1;
- else
- return 0;
- }
- while (!(serial_inw(info, VAC_UART_INT_STATUS) & \
- VAC_UART_STATUS_RX_READY))
- ;
-
- return(serial_inp(info, VAC_UART_RX));
-}
-
-#endif /* CONFIG_REMOTE_DEBUG */
diff -Nru a/arch/mips/baget/wbflush.c b/arch/mips/baget/wbflush.c
--- a/arch/mips/baget/wbflush.c Tue Feb 25 01:38:33 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,24 +0,0 @@
-/*
- * Setup the right wbflush routine for Baget/MIPS.
- *
- * Copyright (C) 1999 Gleb Raiko & Vladimir Roganov
- */
-
-#include
-#include
-
-void (*__wbflush) (void);
-
-static void wbflush_baget(void);
-
-void __init wbflush_setup(void)
-{
- __wbflush = wbflush_baget;
-}
-
-/*
- * Baget/MIPS doesn't need to write back the WB.
- */
-static void wbflush_baget(void)
-{
-}
diff -Nru a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
--- a/arch/mips/boot/Makefile Sat Dec 14 04:38:56 2002
+++ b/arch/mips/boot/Makefile Mon Apr 14 20:10:11 2003
@@ -3,11 +3,9 @@
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
-# Copyright (C) 1995, 1998, 2001 by Ralf Baechle
+# Copyright (C) 1995, 1998, 2001, 2002 by Ralf Baechle
#
-OBJS = milo.o a.out.o
-
#
# Some DECstations need all possible sections of an ECOFF executable
#
@@ -21,25 +19,33 @@
# Drop some uninteresting sections in the kernel.
# This is only relevant for ELF kernels but doesn't hurt a.out
#
-drop-sections = .reginfo .mdebug
+drop-sections = .reginfo .mdebug .comment .note
strip-flags = $(addprefix --remove-section=,$(drop-sections))
all: vmlinux.ecoff addinitrd
-vmlinux.ecoff: elf2ecoff $(TOPDIR)/vmlinux
- ./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS)
+vmlinux.rm200: vmlinux
+ $(OBJCOPY) \
+ --change-addresses=0xfffffffc \
+ -O elf32-tradlittlemips \
+ $(strip-flags) \
+ $< $@
+
+vmlinux.ecoff: $(obj)/elf2ecoff vmlinux
+ ./elf2ecoff vmlinux $(obj)/vmlinux.ecoff $(E2EFLAGS)
-elf2ecoff: elf2ecoff.c
+$(obj)/elf2ecoff: $(obj)/elf2ecoff.c
$(HOSTCC) -o $@ $^
-addinitrd: addinitrd.c
+$(obj)/addinitrd: $(obj)/addinitrd.c
$(HOSTCC) -o $@ $^
-clean:
- rm -f vmlinux.ecoff
- rm -f zImage zImage.tmp
-
-mrproper:
- rm -f vmlinux.ecoff
- rm -f addinitrd
- rm -f elf2ecoff
+archhelp:
+ @echo '* vmlinux.rm200 - Bootable kernel image for RM200C'
+
+CLEAN_FILES += addinitrd \
+ elf2ecoff \
+ vmlinux.ecoff \
+ vmlinux.rm200 \
+ zImage.tmp \
+ zImage
diff -Nru a/arch/mips/boot/addinitrd.c b/arch/mips/boot/addinitrd.c
--- a/arch/mips/boot/addinitrd.c Tue Feb 5 09:40:23 2002
+++ b/arch/mips/boot/addinitrd.c Mon Apr 14 20:10:11 2003
@@ -8,6 +8,8 @@
#include
#include
#include
+#include
+#include
#include "ecoff.h"
@@ -44,7 +46,7 @@
char buf[1024];
unsigned long loadaddr;
unsigned long initrd_header[2];
- int i;
+ int i,cnt;
int swab = 0;
if (argc != 4) {
@@ -60,7 +62,6 @@
die ("read aout header");
if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
die ("read section headers");
-
/*
* check whether the file is good for us
*/
@@ -81,7 +82,7 @@
die ("open initrd");
if (fstat (fd_initrd, &st) < 0)
die ("fstat initrd");
- loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
+ loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
+ MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
loadaddr += MIPS_PAGE_SIZE;
@@ -98,9 +99,20 @@
die ("write aout header");
if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
die ("write section headers");
- while ((i = read (fd_vmlinux, buf, sizeof buf)) > 0)
+ /* skip padding */
+ if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
+ die ("lseek vmlinux");
+ if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
+ die ("lseek outfile");
+ /* copy text segment */
+ cnt = SWAB(eaout.tsize);
+ while (cnt) {
+ if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0)
+ die ("read vmlinux");
if (write (fd_outfile, buf, i) != i)
die ("write vmlinux");
+ cnt -= i;
+ }
if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
die ("write initrd header");
while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
diff -Nru a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c
--- a/arch/mips/boot/elf2ecoff.c Mon Feb 4 23:38:16 2002
+++ b/arch/mips/boot/elf2ecoff.c Mon Apr 14 20:10:11 2003
@@ -41,487 +41,114 @@
#include
#include
#include
+#include
+#include
#include "ecoff.h"
/*
* Some extra ELF definitions
*/
-#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
/* -------------------------------------------------------------------- */
struct sect {
- unsigned long vaddr;
- unsigned long len;
+ unsigned long vaddr;
+ unsigned long len;
};
-int phcmp ();
-char *saveRead (int file, off_t offset, off_t len, char *name);
-int copy (int, int, off_t, off_t);
-int translate_syms (int, int, off_t, off_t, off_t, off_t);
-void convert_elf_hdr (Elf32_Ehdr *);
-void convert_elf_phdrs (Elf32_Phdr *, int);
-void convert_elf_shdrs (Elf32_Shdr *, int);
-void convert_ecoff_filehdr(struct filehdr *);
-void convert_ecoff_aouthdr(struct aouthdr *);
-void convert_ecoff_esecs(struct scnhdr *, int);
-extern int errno;
int *symTypeTable;
int must_convert_endian = 0;
int format_bigendian = 0;
-main (int argc, char **argv, char **envp)
+static void copy(int out, int in, off_t offset, off_t size)
{
- Elf32_Ehdr ex;
- Elf32_Phdr *ph;
- Elf32_Shdr *sh;
- Elf32_Sym *symtab;
- char *shstrtab;
- int strtabix, symtabix;
- int i, pad;
- struct sect text, data, bss;
- struct filehdr efh;
- struct aouthdr eah;
- struct scnhdr esecs [6];
- int infile, outfile;
- unsigned long cur_vma = ULONG_MAX;
- int addflag = 0;
- int nosecs;
-
- text.len = data.len = bss.len = 0;
- text.vaddr = data.vaddr = bss.vaddr = 0;
-
- /* Check args... */
- if (argc < 3 || argc > 4)
- {
- usage:
- fprintf (stderr,
- "usage: elf2aout [-a]\n");
- exit (1);
- }
- if (argc == 4)
- {
- if (strcmp (argv [3], "-a"))
- goto usage;
- addflag = 1;
- }
-
- /* Try the input file... */
- if ((infile = open (argv [1], O_RDONLY)) < 0)
- {
- fprintf (stderr, "Can't open %s for read: %s\n",
- argv [1], strerror (errno));
- exit (1);
- }
-
- /* Read the header, which is at the beginning of the file... */
- i = read (infile, &ex, sizeof ex);
- if (i != sizeof ex)
- {
- fprintf (stderr, "ex: %s: %s.\n",
- argv [1], i ? strerror (errno) : "End of file reached");
- exit (1);
- }
-
- if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
- format_bigendian = 1;
-
- if (ntohs (0xaa55) == 0xaa55) {
- if (!format_bigendian)
- must_convert_endian = 1;
- } else {
- if (format_bigendian)
- must_convert_endian = 1;
- }
- if (must_convert_endian)
- convert_elf_hdr (&ex);
-
- /* Read the program headers... */
- ph = (Elf32_Phdr *)saveRead (infile, ex.e_phoff,
- ex.e_phnum * sizeof (Elf32_Phdr), "ph");
- if (must_convert_endian)
- convert_elf_phdrs (ph, ex.e_phnum);
- /* Read the section headers... */
- sh = (Elf32_Shdr *)saveRead (infile, ex.e_shoff,
- ex.e_shnum * sizeof (Elf32_Shdr), "sh");
- if (must_convert_endian)
- convert_elf_shdrs (sh, ex.e_shnum);
- /* Read in the section string table. */
- shstrtab = saveRead (infile, sh [ex.e_shstrndx].sh_offset,
- sh [ex.e_shstrndx].sh_size, "shstrtab");
-
- /* Figure out if we can cram the program header into an ECOFF
- header... Basically, we can't handle anything but loadable
- segments, but we can ignore some kinds of segments. We can't
- handle holes in the address space. Segments may be out of order,
- so we sort them first. */
-
- qsort (ph, ex.e_phnum, sizeof (Elf32_Phdr), phcmp);
-
- for (i = 0; i < ex.e_phnum; i++)
- {
- /* Section types we can ignore... */
- if (ph [i].p_type == PT_NULL || ph [i].p_type == PT_NOTE ||
- ph [i].p_type == PT_PHDR || ph [i].p_type == PT_MIPS_REGINFO)
- continue;
- /* Section types we can't handle... */
- else if (ph [i].p_type != PT_LOAD)
- {
- fprintf (stderr, "Program header %d type %d can't be converted.\n");
- exit (1);
- }
- /* Writable (data) segment? */
- if (ph [i].p_flags & PF_W)
- {
- struct sect ndata, nbss;
-
- ndata.vaddr = ph [i].p_vaddr;
- ndata.len = ph [i].p_filesz;
- nbss.vaddr = ph [i].p_vaddr + ph [i].p_filesz;
- nbss.len = ph [i].p_memsz - ph [i].p_filesz;
-
- combine (&data, &ndata, 0);
- combine (&bss, &nbss, 1);
- }
- else
- {
- struct sect ntxt;
-
- ntxt.vaddr = ph [i].p_vaddr;
- ntxt.len = ph [i].p_filesz;
-
- combine (&text, &ntxt, 0);
- }
- /* Remember the lowest segment start address. */
- if (ph [i].p_vaddr < cur_vma)
- cur_vma = ph [i].p_vaddr;
- }
-
- /* Sections must be in order to be converted... */
- if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
- text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr)
- {
- fprintf (stderr, "Sections ordering prevents a.out conversion.\n");
- exit (1);
- }
-
- /* If there's a data section but no text section, then the loader
- combined everything into one section. That needs to be the
- text section, so just make the data section zero length following
- text. */
- if (data.len && !text.len)
- {
- text = data;
- data.vaddr = text.vaddr + text.len;
- data.len = 0;
- }
-
- /* If there is a gap between text and data, we'll fill it when we copy
- the data, so update the length of the text segment as represented in
- a.out to reflect that, since a.out doesn't allow gaps in the program
- address space. */
- if (text.vaddr + text.len < data.vaddr)
- text.len = data.vaddr - text.vaddr;
-
- /* We now have enough information to cons up an a.out header... */
- eah.magic = OMAGIC;
- eah.vstamp = 200;
- eah.tsize = text.len;
- eah.dsize = data.len;
- eah.bsize = bss.len;
- eah.entry = ex.e_entry;
- eah.text_start = text.vaddr;
- eah.data_start = data.vaddr;
- eah.bss_start = bss.vaddr;
- eah.gprmask = 0xf3fffffe;
- memset (&eah.cprmask, '\0', sizeof eah.cprmask);
- eah.gp_value = 0; /* unused. */
-
- if (format_bigendian)
- efh.f_magic = MIPSEBMAGIC;
- else
- efh.f_magic = MIPSELMAGIC;
- if (addflag)
- nosecs = 6;
- else
- nosecs = 3;
- efh.f_nscns = nosecs;
- efh.f_timdat = 0; /* bogus */
- efh.f_symptr = 0;
- efh.f_nsyms = 0;
- efh.f_opthdr = sizeof eah;
- efh.f_flags = 0x100f; /* Stripped, not sharable. */
-
- memset (esecs, 0, sizeof esecs);
- strcpy (esecs [0].s_name, ".text");
- strcpy (esecs [1].s_name, ".data");
- strcpy (esecs [2].s_name, ".bss");
- if (addflag) {
- strcpy (esecs [3].s_name, ".rdata");
- strcpy (esecs [4].s_name, ".sdata");
- strcpy (esecs [5].s_name, ".sbss");
- }
- esecs [0].s_paddr = esecs [0].s_vaddr = eah.text_start;
- esecs [1].s_paddr = esecs [1].s_vaddr = eah.data_start;
- esecs [2].s_paddr = esecs [2].s_vaddr = eah.bss_start;
- if (addflag) {
- esecs [3].s_paddr = esecs [3].s_vaddr = 0;
- esecs [4].s_paddr = esecs [4].s_vaddr = 0;
- esecs [5].s_paddr = esecs [5].s_vaddr = 0;
- }
- esecs [0].s_size = eah.tsize;
- esecs [1].s_size = eah.dsize;
- esecs [2].s_size = eah.bsize;
- if (addflag) {
- esecs [3].s_size = 0;
- esecs [4].s_size = 0;
- esecs [5].s_size = 0;
- }
- esecs [0].s_scnptr = N_TXTOFF (efh, eah);
- esecs [1].s_scnptr = N_DATOFF (efh, eah);
-#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10
-#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1))
- esecs [2].s_scnptr = esecs [1].s_scnptr +
- ECOFF_ROUND (esecs [1].s_size, ECOFF_SEGMENT_ALIGNMENT (&eah));
- if (addflag) {
- esecs [3].s_scnptr = 0;
- esecs [4].s_scnptr = 0;
- esecs [5].s_scnptr = 0;
- }
- esecs [0].s_relptr = esecs [1].s_relptr
- = esecs [2].s_relptr = 0;
- esecs [0].s_lnnoptr = esecs [1].s_lnnoptr
- = esecs [2].s_lnnoptr = 0;
- esecs [0].s_nreloc = esecs [1].s_nreloc = esecs [2].s_nreloc = 0;
- esecs [0].s_nlnno = esecs [1].s_nlnno = esecs [2].s_nlnno = 0;
- if (addflag) {
- esecs [3].s_relptr = esecs [4].s_relptr
- = esecs [5].s_relptr = 0;
- esecs [3].s_lnnoptr = esecs [4].s_lnnoptr
- = esecs [5].s_lnnoptr = 0;
- esecs [3].s_nreloc = esecs [4].s_nreloc = esecs [5].s_nreloc = 0;
- esecs [3].s_nlnno = esecs [4].s_nlnno = esecs [5].s_nlnno = 0;
- }
- esecs [0].s_flags = 0x20;
- esecs [1].s_flags = 0x40;
- esecs [2].s_flags = 0x82;
- if (addflag) {
- esecs [3].s_flags = 0x100;
- esecs [4].s_flags = 0x200;
- esecs [5].s_flags = 0x400;
- }
-
- /* Make the output file... */
- if ((outfile = open (argv [2], O_WRONLY | O_CREAT, 0777)) < 0)
- {
- fprintf (stderr, "Unable to create %s: %s\n", argv [2], strerror (errno));
- exit (1);
- }
-
- if (must_convert_endian)
- convert_ecoff_filehdr (&efh);
- /* Write the headers... */
- i = write (outfile, &efh, sizeof efh);
- if (i != sizeof efh)
- {
- perror ("efh: write");
- exit (1);
-
- for (i = 0; i < nosecs; i++)
- {
- printf ("Section %d: %s phys %x size %x file offset %x\n",
- i, esecs [i].s_name, esecs [i].s_paddr,
- esecs [i].s_size, esecs [i].s_scnptr);
- }
- }
- fprintf (stderr, "wrote %d byte file header.\n", i);
-
- if (must_convert_endian)
- convert_ecoff_aouthdr (&eah);
- i = write (outfile, &eah, sizeof eah);
- if (i != sizeof eah)
- {
- perror ("eah: write");
- exit (1);
- }
- fprintf (stderr, "wrote %d byte a.out header.\n", i);
-
- if (must_convert_endian)
- convert_ecoff_esecs (&esecs[0], nosecs);
- i = write (outfile, &esecs, nosecs * sizeof(struct scnhdr));
- if (i != nosecs * sizeof(struct scnhdr))
- {
- perror ("esecs: write");
- exit (1);
- }
- fprintf (stderr, "wrote %d bytes of section headers.\n", i);
-
- if (pad = ((sizeof efh + sizeof eah + nosecs * sizeof(struct scnhdr)) & 15))
- {
- pad = 16 - pad;
- i = write (outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad);
- if (i < 0)
- {
- perror ("ipad: write");
- exit (1);
- }
- fprintf (stderr, "wrote %d byte pad.\n", i);
- }
+ char ibuf[4096];
+ int remaining, cur, count;
- /* Copy the loadable sections. Zero-fill any gaps less than 64k;
- complain about any zero-filling, and die if we're asked to zero-fill
- more than 64k. */
- for (i = 0; i < ex.e_phnum; i++)
- {
- /* Unprocessable sections were handled above, so just verify that
- the section can be loaded before copying. */
- if (ph [i].p_type == PT_LOAD && ph [i].p_filesz)
- {
- if (cur_vma != ph [i].p_vaddr)
- {
- unsigned long gap = ph [i].p_vaddr - cur_vma;
- char obuf [1024];
- if (gap > 65536)
- {
- fprintf (stderr, "Intersegment gap (%d bytes) too large.\n",
- gap);
- exit (1);
+ /* Go to the start of the ELF symbol table... */
+ if (lseek(in, offset, SEEK_SET) < 0) {
+ perror("copy: lseek");
+ exit(1);
+ }
+
+ remaining = size;
+ while (remaining) {
+ cur = remaining;
+ if (cur > sizeof ibuf)
+ cur = sizeof ibuf;
+ remaining -= cur;
+ if ((count = read(in, ibuf, cur)) != cur) {
+ fprintf(stderr, "copy: read: %s\n",
+ count ? strerror(errno) :
+ "premature end of file");
+ exit(1);
}
- fprintf (stderr, "Warning: %d byte intersegment gap.\n", gap);
- memset (obuf, 0, sizeof obuf);
- while (gap)
- {
- int count = write (outfile, obuf, (gap > sizeof obuf
- ? sizeof obuf : gap));
- if (count < 0)
- {
- fprintf (stderr, "Error writing gap: %s\n",
- strerror (errno));
- exit (1);
- }
- gap -= count;
+ if ((count = write(out, ibuf, cur)) != cur) {
+ perror("copy: write");
+ exit(1);
}
- }
-fprintf (stderr, "writing %d bytes...\n", ph [i].p_filesz);
- copy (outfile, infile, ph [i].p_offset, ph [i].p_filesz);
- cur_vma = ph [i].p_vaddr + ph [i].p_filesz;
- }
- }
-
- /*
- * Write a page of padding for boot PROMS that read entire pages.
- * Without this, they may attempt to read past the end of the
- * data section, incur an error, and refuse to boot.
- */
- {
- char obuf[4096];
- memset(obuf, 0, sizeof obuf);
- if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) {
- fprintf(stderr, "Error writing PROM padding: %s\n",
- strerror(errno));
- exit(1);
- }
- }
-
- /* Looks like we won... */
- exit (0);
-}
-
-copy (out, in, offset, size)
- int out, in;
- off_t offset, size;
-{
- char ibuf [4096];
- int remaining, cur, count;
-
- /* Go to the start of the ELF symbol table... */
- if (lseek (in, offset, SEEK_SET) < 0)
- {
- perror ("copy: lseek");
- exit (1);
- }
-
- remaining = size;
- while (remaining)
- {
- cur = remaining;
- if (cur > sizeof ibuf)
- cur = sizeof ibuf;
- remaining -= cur;
- if ((count = read (in, ibuf, cur)) != cur)
- {
- fprintf (stderr, "copy: read: %s\n",
- count ? strerror (errno) : "premature end of file");
- exit (1);
- }
- if ((count = write (out, ibuf, cur)) != cur)
- {
- perror ("copy: write");
- exit (1);
}
- }
}
-/* Combine two segments, which must be contiguous. If pad is true, it's
- okay for there to be padding between. */
-combine (base, new, pad)
- struct sect *base, *new;
- int pad;
-{
- if (!base -> len)
- *base = *new;
- else if (new -> len)
- {
- if (base -> vaddr + base -> len != new -> vaddr)
- {
- if (pad)
- base -> len = new -> vaddr - base -> vaddr;
- else
- {
- fprintf (stderr,
- "Non-contiguous data can't be converted.\n");
- exit (1);
- }
+/*
+ * Combine two segments, which must be contiguous. If pad is true, it's
+ * okay for there to be padding between.
+ */
+static void combine(struct sect *base, struct sect *new, int pad)
+{
+ if (!base->len)
+ *base = *new;
+ else if (new->len) {
+ if (base->vaddr + base->len != new->vaddr) {
+ if (pad)
+ base->len = new->vaddr - base->vaddr;
+ else {
+ fprintf(stderr,
+ "Non-contiguous data can't be converted.\n");
+ exit(1);
+ }
+ }
+ base->len += new->len;
}
- base -> len += new -> len;
- }
}
-phcmp (h1, h2)
- Elf32_Phdr *h1, *h2;
+static int phcmp(const void *v1, const void *v2)
{
- if (h1 -> p_vaddr > h2 -> p_vaddr)
- return 1;
- else if (h1 -> p_vaddr < h2 -> p_vaddr)
- return -1;
- else
- return 0;
+ const Elf32_Phdr *h1 = v1;
+ const Elf32_Phdr *h2 = v2;
+
+ if (h1->p_vaddr > h2->p_vaddr)
+ return 1;
+ else if (h1->p_vaddr < h2->p_vaddr)
+ return -1;
+ else
+ return 0;
}
-char *saveRead (int file, off_t offset, off_t len, char *name)
+static char *saveRead(int file, off_t offset, off_t len, char *name)
{
- char *tmp;
- int count;
- off_t off;
- if ((off = lseek (file, offset, SEEK_SET)) < 0)
- {
- fprintf (stderr, "%s: fseek: %s\n", name, strerror (errno));
- exit (1);
- }
- if (!(tmp = (char *)malloc (len)))
- {
- fprintf (stderr, "%s: Can't allocate %d bytes.\n", name, len);
- exit (1);
- }
- count = read (file, tmp, len);
- if (count != len)
- {
- fprintf (stderr, "%s: read: %s.\n",
- name, count ? strerror (errno) : "End of file reached");
- exit (1);
- }
- return tmp;
+ char *tmp;
+ int count;
+ off_t off;
+ if ((off = lseek(file, offset, SEEK_SET)) < 0) {
+ fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno));
+ exit(1);
+ }
+ if (!(tmp = (char *) malloc(len))) {
+ fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name,
+ len);
+ exit(1);
+ }
+ count = read(file, tmp, len);
+ if (count != len) {
+ fprintf(stderr, "%s: read: %s.\n",
+ name,
+ count ? strerror(errno) : "End of file reached");
+ exit(1);
+ }
+ return tmp;
}
#define swab16(x) \
@@ -536,101 +163,454 @@
(((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
(((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
-void convert_elf_hdr (Elf32_Ehdr *e)
+static void convert_elf_hdr(Elf32_Ehdr * e)
{
- e->e_type = swab16(e->e_type);
- e->e_machine = swab16(e->e_machine);
- e->e_version = swab32(e->e_version);
- e->e_entry = swab32(e->e_entry);
- e->e_phoff = swab32(e->e_phoff);
- e->e_shoff = swab32(e->e_shoff);
- e->e_flags = swab32(e->e_flags);
- e->e_ehsize = swab16(e->e_ehsize);
+ e->e_type = swab16(e->e_type);
+ e->e_machine = swab16(e->e_machine);
+ e->e_version = swab32(e->e_version);
+ e->e_entry = swab32(e->e_entry);
+ e->e_phoff = swab32(e->e_phoff);
+ e->e_shoff = swab32(e->e_shoff);
+ e->e_flags = swab32(e->e_flags);
+ e->e_ehsize = swab16(e->e_ehsize);
e->e_phentsize = swab16(e->e_phentsize);
- e->e_phnum = swab16(e->e_phnum);
+ e->e_phnum = swab16(e->e_phnum);
e->e_shentsize = swab16(e->e_shentsize);
- e->e_shnum = swab16(e->e_shnum);
- e->e_shstrndx = swab16(e->e_shstrndx);
+ e->e_shnum = swab16(e->e_shnum);
+ e->e_shstrndx = swab16(e->e_shstrndx);
}
-void convert_elf_phdrs (Elf32_Phdr *p, int num)
+static void convert_elf_phdrs(Elf32_Phdr * p, int num)
{
int i;
- for (i = 0; i < num; i++,p++) {
- p->p_type = swab32(p->p_type);
+ for (i = 0; i < num; i++, p++) {
+ p->p_type = swab32(p->p_type);
p->p_offset = swab32(p->p_offset);
- p->p_vaddr = swab32(p->p_vaddr);
- p->p_paddr = swab32(p->p_paddr);
+ p->p_vaddr = swab32(p->p_vaddr);
+ p->p_paddr = swab32(p->p_paddr);
p->p_filesz = swab32(p->p_filesz);
- p->p_memsz = swab32(p->p_memsz);
- p->p_flags = swab32(p->p_flags);
- p->p_align = swab32(p->p_align);
+ p->p_memsz = swab32(p->p_memsz);
+ p->p_flags = swab32(p->p_flags);
+ p->p_align = swab32(p->p_align);
}
}
-void convert_elf_shdrs (Elf32_Shdr *s, int num)
+static void convert_elf_shdrs(Elf32_Shdr * s, int num)
{
int i;
- for (i = 0; i < num; i++,s++) {
- s->sh_name = swab32(s->sh_name);
- s->sh_type = swab32(s->sh_type);
- s->sh_flags = swab32(s->sh_flags);
- s->sh_addr = swab32(s->sh_addr);
- s->sh_offset = swab32(s->sh_offset);
- s->sh_size = swab32(s->sh_size);
- s->sh_link = swab32(s->sh_link);
- s->sh_info = swab32(s->sh_info);
+ for (i = 0; i < num; i++, s++) {
+ s->sh_name = swab32(s->sh_name);
+ s->sh_type = swab32(s->sh_type);
+ s->sh_flags = swab32(s->sh_flags);
+ s->sh_addr = swab32(s->sh_addr);
+ s->sh_offset = swab32(s->sh_offset);
+ s->sh_size = swab32(s->sh_size);
+ s->sh_link = swab32(s->sh_link);
+ s->sh_info = swab32(s->sh_info);
s->sh_addralign = swab32(s->sh_addralign);
- s->sh_entsize = swab32(s->sh_entsize);
+ s->sh_entsize = swab32(s->sh_entsize);
}
}
-void convert_ecoff_filehdr(struct filehdr *f)
+static void convert_ecoff_filehdr(struct filehdr *f)
{
- f->f_magic = swab16(f->f_magic);
- f->f_nscns = swab16(f->f_nscns);
+ f->f_magic = swab16(f->f_magic);
+ f->f_nscns = swab16(f->f_nscns);
f->f_timdat = swab32(f->f_timdat);
f->f_symptr = swab32(f->f_symptr);
- f->f_nsyms = swab32(f->f_nsyms);
+ f->f_nsyms = swab32(f->f_nsyms);
f->f_opthdr = swab16(f->f_opthdr);
- f->f_flags = swab16(f->f_flags);
+ f->f_flags = swab16(f->f_flags);
}
-void convert_ecoff_aouthdr(struct aouthdr *a)
+static void convert_ecoff_aouthdr(struct aouthdr *a)
{
- a->magic = swab16(a->magic);
- a->vstamp = swab16(a->vstamp);
- a->tsize = swab32(a->tsize);
- a->dsize = swab32(a->dsize);
- a->bsize = swab32(a->bsize);
- a->entry = swab32(a->entry);
+ a->magic = swab16(a->magic);
+ a->vstamp = swab16(a->vstamp);
+ a->tsize = swab32(a->tsize);
+ a->dsize = swab32(a->dsize);
+ a->bsize = swab32(a->bsize);
+ a->entry = swab32(a->entry);
a->text_start = swab32(a->text_start);
a->data_start = swab32(a->data_start);
- a->bss_start = swab32(a->bss_start);
- a->gprmask = swab32(a->gprmask);
+ a->bss_start = swab32(a->bss_start);
+ a->gprmask = swab32(a->gprmask);
a->cprmask[0] = swab32(a->cprmask[0]);
a->cprmask[1] = swab32(a->cprmask[1]);
a->cprmask[2] = swab32(a->cprmask[2]);
a->cprmask[3] = swab32(a->cprmask[3]);
- a->gp_value = swab32(a->gp_value);
+ a->gp_value = swab32(a->gp_value);
}
-void convert_ecoff_esecs(struct scnhdr *s, int num)
+static void convert_ecoff_esecs(struct scnhdr *s, int num)
{
int i;
for (i = 0; i < num; i++, s++) {
- s->s_paddr = swab32(s->s_paddr);
- s->s_vaddr = swab32(s->s_vaddr);
- s->s_size = swab32(s->s_size);
- s->s_scnptr = swab32(s->s_scnptr);
- s->s_relptr = swab32(s->s_relptr);
+ s->s_paddr = swab32(s->s_paddr);
+ s->s_vaddr = swab32(s->s_vaddr);
+ s->s_size = swab32(s->s_size);
+ s->s_scnptr = swab32(s->s_scnptr);
+ s->s_relptr = swab32(s->s_relptr);
s->s_lnnoptr = swab32(s->s_lnnoptr);
- s->s_nreloc = swab16(s->s_nreloc);
- s->s_nlnno = swab16(s->s_nlnno);
- s->s_flags = swab32(s->s_flags);
+ s->s_nreloc = swab16(s->s_nreloc);
+ s->s_nlnno = swab16(s->s_nlnno);
+ s->s_flags = swab32(s->s_flags);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ Elf32_Ehdr ex;
+ Elf32_Phdr *ph;
+ Elf32_Shdr *sh;
+ char *shstrtab;
+ int i, pad;
+ struct sect text, data, bss;
+ struct filehdr efh;
+ struct aouthdr eah;
+ struct scnhdr esecs[6];
+ int infile, outfile;
+ unsigned long cur_vma = ULONG_MAX;
+ int addflag = 0;
+ int nosecs;
+
+ text.len = data.len = bss.len = 0;
+ text.vaddr = data.vaddr = bss.vaddr = 0;
+
+ /* Check args... */
+ if (argc < 3 || argc > 4) {
+ usage:
+ fprintf(stderr,
+ "usage: elf2ecoff [-a]\n");
+ exit(1);
+ }
+ if (argc == 4) {
+ if (strcmp(argv[3], "-a"))
+ goto usage;
+ addflag = 1;
+ }
+
+ /* Try the input file... */
+ if ((infile = open(argv[1], O_RDONLY)) < 0) {
+ fprintf(stderr, "Can't open %s for read: %s\n",
+ argv[1], strerror(errno));
+ exit(1);
+ }
+
+ /* Read the header, which is at the beginning of the file... */
+ i = read(infile, &ex, sizeof ex);
+ if (i != sizeof ex) {
+ fprintf(stderr, "ex: %s: %s.\n",
+ argv[1],
+ i ? strerror(errno) : "End of file reached");
+ exit(1);
+ }
+
+ if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
+ format_bigendian = 1;
+
+ if (ntohs(0xaa55) == 0xaa55) {
+ if (!format_bigendian)
+ must_convert_endian = 1;
+ } else {
+ if (format_bigendian)
+ must_convert_endian = 1;
+ }
+ if (must_convert_endian)
+ convert_elf_hdr(&ex);
+
+ /* Read the program headers... */
+ ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
+ ex.e_phnum * sizeof(Elf32_Phdr),
+ "ph");
+ if (must_convert_endian)
+ convert_elf_phdrs(ph, ex.e_phnum);
+ /* Read the section headers... */
+ sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff,
+ ex.e_shnum * sizeof(Elf32_Shdr),
+ "sh");
+ if (must_convert_endian)
+ convert_elf_shdrs(sh, ex.e_shnum);
+ /* Read in the section string table. */
+ shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
+ sh[ex.e_shstrndx].sh_size, "shstrtab");
+
+ /* Figure out if we can cram the program header into an ECOFF
+ header... Basically, we can't handle anything but loadable
+ segments, but we can ignore some kinds of segments. We can't
+ handle holes in the address space. Segments may be out of order,
+ so we sort them first. */
+
+ qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp);
+
+ for (i = 0; i < ex.e_phnum; i++) {
+ /* Section types we can ignore... */
+ if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE ||
+ ph[i].p_type == PT_PHDR
+ || ph[i].p_type == PT_MIPS_REGINFO)
+ continue;
+ /* Section types we can't handle... */
+ else if (ph[i].p_type != PT_LOAD) {
+ fprintf(stderr,
+ "Program header %d type %d can't be converted.\n",
+ ex.e_phnum, ph[i].p_type);
+ exit(1);
+ }
+ /* Writable (data) segment? */
+ if (ph[i].p_flags & PF_W) {
+ struct sect ndata, nbss;
+
+ ndata.vaddr = ph[i].p_vaddr;
+ ndata.len = ph[i].p_filesz;
+ nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+ nbss.len = ph[i].p_memsz - ph[i].p_filesz;
+
+ combine(&data, &ndata, 0);
+ combine(&bss, &nbss, 1);
+ } else {
+ struct sect ntxt;
+
+ ntxt.vaddr = ph[i].p_vaddr;
+ ntxt.len = ph[i].p_filesz;
+
+ combine(&text, &ntxt, 0);
+ }
+ /* Remember the lowest segment start address. */
+ if (ph[i].p_vaddr < cur_vma)
+ cur_vma = ph[i].p_vaddr;
+ }
+
+ /* Sections must be in order to be converted... */
+ if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
+ text.vaddr + text.len > data.vaddr
+ || data.vaddr + data.len > bss.vaddr) {
+ fprintf(stderr,
+ "Sections ordering prevents a.out conversion.\n");
+ exit(1);
+ }
+
+ /* If there's a data section but no text section, then the loader
+ combined everything into one section. That needs to be the
+ text section, so just make the data section zero length following
+ text. */
+ if (data.len && !text.len) {
+ text = data;
+ data.vaddr = text.vaddr + text.len;
+ data.len = 0;
+ }
+
+ /* If there is a gap between text and data, we'll fill it when we copy
+ the data, so update the length of the text segment as represented in
+ a.out to reflect that, since a.out doesn't allow gaps in the program
+ address space. */
+ if (text.vaddr + text.len < data.vaddr)
+ text.len = data.vaddr - text.vaddr;
+
+ /* We now have enough information to cons up an a.out header... */
+ eah.magic = OMAGIC;
+ eah.vstamp = 200;
+ eah.tsize = text.len;
+ eah.dsize = data.len;
+ eah.bsize = bss.len;
+ eah.entry = ex.e_entry;
+ eah.text_start = text.vaddr;
+ eah.data_start = data.vaddr;
+ eah.bss_start = bss.vaddr;
+ eah.gprmask = 0xf3fffffe;
+ memset(&eah.cprmask, '\0', sizeof eah.cprmask);
+ eah.gp_value = 0; /* unused. */
+
+ if (format_bigendian)
+ efh.f_magic = MIPSEBMAGIC;
+ else
+ efh.f_magic = MIPSELMAGIC;
+ if (addflag)
+ nosecs = 6;
+ else
+ nosecs = 3;
+ efh.f_nscns = nosecs;
+ efh.f_timdat = 0; /* bogus */
+ efh.f_symptr = 0;
+ efh.f_nsyms = 0;
+ efh.f_opthdr = sizeof eah;
+ efh.f_flags = 0x100f; /* Stripped, not sharable. */
+
+ memset(esecs, 0, sizeof esecs);
+ strcpy(esecs[0].s_name, ".text");
+ strcpy(esecs[1].s_name, ".data");
+ strcpy(esecs[2].s_name, ".bss");
+ if (addflag) {
+ strcpy(esecs[3].s_name, ".rdata");
+ strcpy(esecs[4].s_name, ".sdata");
+ strcpy(esecs[5].s_name, ".sbss");
+ }
+ esecs[0].s_paddr = esecs[0].s_vaddr = eah.text_start;
+ esecs[1].s_paddr = esecs[1].s_vaddr = eah.data_start;
+ esecs[2].s_paddr = esecs[2].s_vaddr = eah.bss_start;
+ if (addflag) {
+ esecs[3].s_paddr = esecs[3].s_vaddr = 0;
+ esecs[4].s_paddr = esecs[4].s_vaddr = 0;
+ esecs[5].s_paddr = esecs[5].s_vaddr = 0;
+ }
+ esecs[0].s_size = eah.tsize;
+ esecs[1].s_size = eah.dsize;
+ esecs[2].s_size = eah.bsize;
+ if (addflag) {
+ esecs[3].s_size = 0;
+ esecs[4].s_size = 0;
+ esecs[5].s_size = 0;
}
+ esecs[0].s_scnptr = N_TXTOFF(efh, eah);
+ esecs[1].s_scnptr = N_DATOFF(efh, eah);
+#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10
+#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1))
+ esecs[2].s_scnptr = esecs[1].s_scnptr +
+ ECOFF_ROUND(esecs[1].s_size, ECOFF_SEGMENT_ALIGNMENT(&eah));
+ if (addflag) {
+ esecs[3].s_scnptr = 0;
+ esecs[4].s_scnptr = 0;
+ esecs[5].s_scnptr = 0;
+ }
+ esecs[0].s_relptr = esecs[1].s_relptr = esecs[2].s_relptr = 0;
+ esecs[0].s_lnnoptr = esecs[1].s_lnnoptr = esecs[2].s_lnnoptr = 0;
+ esecs[0].s_nreloc = esecs[1].s_nreloc = esecs[2].s_nreloc = 0;
+ esecs[0].s_nlnno = esecs[1].s_nlnno = esecs[2].s_nlnno = 0;
+ if (addflag) {
+ esecs[3].s_relptr = esecs[4].s_relptr
+ = esecs[5].s_relptr = 0;
+ esecs[3].s_lnnoptr = esecs[4].s_lnnoptr
+ = esecs[5].s_lnnoptr = 0;
+ esecs[3].s_nreloc = esecs[4].s_nreloc = esecs[5].s_nreloc =
+ 0;
+ esecs[3].s_nlnno = esecs[4].s_nlnno = esecs[5].s_nlnno = 0;
+ }
+ esecs[0].s_flags = 0x20;
+ esecs[1].s_flags = 0x40;
+ esecs[2].s_flags = 0x82;
+ if (addflag) {
+ esecs[3].s_flags = 0x100;
+ esecs[4].s_flags = 0x200;
+ esecs[5].s_flags = 0x400;
+ }
+
+ /* Make the output file... */
+ if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) {
+ fprintf(stderr, "Unable to create %s: %s\n", argv[2],
+ strerror(errno));
+ exit(1);
+ }
+
+ if (must_convert_endian)
+ convert_ecoff_filehdr(&efh);
+ /* Write the headers... */
+ i = write(outfile, &efh, sizeof efh);
+ if (i != sizeof efh) {
+ perror("efh: write");
+ exit(1);
+
+ for (i = 0; i < nosecs; i++) {
+ printf
+ ("Section %d: %s phys %lx size %lx file offset %lx\n",
+ i, esecs[i].s_name, esecs[i].s_paddr,
+ esecs[i].s_size, esecs[i].s_scnptr);
+ }
+ }
+ fprintf(stderr, "wrote %d byte file header.\n", i);
+
+ if (must_convert_endian)
+ convert_ecoff_aouthdr(&eah);
+ i = write(outfile, &eah, sizeof eah);
+ if (i != sizeof eah) {
+ perror("eah: write");
+ exit(1);
+ }
+ fprintf(stderr, "wrote %d byte a.out header.\n", i);
+
+ if (must_convert_endian)
+ convert_ecoff_esecs(&esecs[0], nosecs);
+ i = write(outfile, &esecs, nosecs * sizeof(struct scnhdr));
+ if (i != nosecs * sizeof(struct scnhdr)) {
+ perror("esecs: write");
+ exit(1);
+ }
+ fprintf(stderr, "wrote %d bytes of section headers.\n", i);
+
+ pad = (sizeof(efh) + sizeof(eah) + nosecs * sizeof(struct scnhdr)) & 15;
+ if (pad) {
+ pad = 16 - pad;
+ i = write(outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad);
+ if (i < 0) {
+ perror("ipad: write");
+ exit(1);
+ }
+ fprintf(stderr, "wrote %d byte pad.\n", i);
+ }
+
+ /*
+ * Copy the loadable sections. Zero-fill any gaps less than 64k;
+ * complain about any zero-filling, and die if we're asked to zero-fill
+ * more than 64k.
+ */
+ for (i = 0; i < ex.e_phnum; i++) {
+ /* Unprocessable sections were handled above, so just verify that
+ the section can be loaded before copying. */
+ if (ph[i].p_type == PT_LOAD && ph[i].p_filesz) {
+ if (cur_vma != ph[i].p_vaddr) {
+ unsigned long gap =
+ ph[i].p_vaddr - cur_vma;
+ char obuf[1024];
+ if (gap > 65536) {
+ fprintf(stderr,
+ "Intersegment gap (%ld bytes) too large.\n",
+ gap);
+ exit(1);
+ }
+ fprintf(stderr,
+ "Warning: %ld byte intersegment gap.\n",
+ gap);
+ memset(obuf, 0, sizeof obuf);
+ while (gap) {
+ int count =
+ write(outfile, obuf,
+ (gap >
+ sizeof obuf ? sizeof
+ obuf : gap));
+ if (count < 0) {
+ fprintf(stderr,
+ "Error writing gap: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ gap -= count;
+ }
+ }
+ fprintf(stderr, "writing %d bytes...\n",
+ ph[i].p_filesz);
+ copy(outfile, infile, ph[i].p_offset,
+ ph[i].p_filesz);
+ cur_vma = ph[i].p_vaddr + ph[i].p_filesz;
+ }
+ }
+
+ /*
+ * Write a page of padding for boot PROMS that read entire pages.
+ * Without this, they may attempt to read past the end of the
+ * data section, incur an error, and refuse to boot.
+ */
+ {
+ char obuf[4096];
+ memset(obuf, 0, sizeof obuf);
+ if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) {
+ fprintf(stderr, "Error writing PROM padding: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ }
+
+ /* Looks like we won... */
+ exit(0);
}
diff -Nru a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/mips/cobalt/Makefile Sun Jun 15 16:54:30 2003
@@ -0,0 +1,7 @@
+#
+# Makefile for the Cobalt micro systems family specific parts of the kernel
+#
+
+obj-y := irq.o int-handler.o reset.o setup.o via.o promcon.o
+
+EXTRA_AFLAGS := $(CFLAGS)
diff -Nru a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/mips/cobalt/int-handler.S Mon Apr 14 20:10:17 2003
@@ -0,0 +1,104 @@
+/*
+ * Cobalt interrupt handler
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ */
+#include
+#include
+#include
+#include
+#include
+
+/*
+ * cobalt_handle_int: Interrupt handler for Cobalt boards
+ */
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+ NESTED(cobalt_handle_int, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+
+ /*
+ * Get pending Interrupts
+ */
+ mfc0 s0,CP0_CAUSE # get raw irq status
+ mfc0 a0,CP0_STATUS # get irq mask
+ and s0,s0,a0 # compute masked irq status
+
+ andi a0,s0,CAUSEF_IP2 /* Check for Galileo timer */
+ beq a0,zero,1f
+ andi a0,s0,CAUSEF_IP6 /* Check for Via chip */
+
+ /* Galileo interrupt */
+ jal galileo_irq
+ move a0,sp
+ j ret_from_irq
+ nop
+
+1:
+ beq a0,zero,1f /* Check IP6 */
+ andi a0,s0,CAUSEF_IP3
+
+ /* Via interrupt */
+ jal via_irq
+ move a0,sp
+ j ret_from_irq
+ nop
+
+1:
+ beq a0,zero,1f /* Check IP3 */
+ andi a0,s0,CAUSEF_IP4
+
+ /* Ethernet 0 interrupt */
+ li a0,COBALT_ETH0_IRQ
+ jal do_IRQ
+ move a1,sp
+
+ j ret_from_irq
+ nop
+
+1:
+ beq a0,zero,1f /* Check IP4 */
+ andi a0,s0,CAUSEF_IP5
+
+ /* Ethernet 1 interrupt */
+ li a0,COBALT_ETH1_IRQ
+ jal do_IRQ
+ move a1,sp
+
+ j ret_from_irq
+ nop
+1:
+ beq a0,zero,1f /* Check IP5 */
+ andi a0,s0,CAUSEF_IP7
+
+ /* Serial interrupt */
+ li a0,COBALT_SERIAL_IRQ
+ jal do_IRQ
+ move a1,sp
+
+ j ret_from_irq
+ nop
+1:
+ beq a0,zero,1f /* Check IP7 */
+ nop
+
+ /* PCI interrupt */
+ li a0,COBALT_QUBE_SLOT_IRQ
+ jal do_IRQ
+ move a1,sp
+
+1:
+ j ret_from_irq
+ nop
+
+ END(cobalt_handle_int)
+
diff -Nru a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/mips/cobalt/irq.c Wed Apr 16 09:51:41 2003
@@ -0,0 +1,143 @@
+/*
+ * IRQ vector handles
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+/* Cobalt Exception handler */
+extern void cobalt_handle_int(void);
+
+/* Via masking routines */
+extern void unmask_irq(unsigned int irqr);
+extern void mask_irq(unsigned int irq);
+
+
+/*
+ * We have two types of interrupts that we handle, ones that come
+ * in through the CPU interrupt lines, and ones that come in on
+ * the via chip. The CPU mappings are:
+ * 0,1 - S/W (ignored)
+ * 2 - Galileo chip (timer)
+ * 3 - Tulip 0 + NCR SCSI
+ * 4 - Tulip 1
+ * 5 - 16550 UART
+ * 6 - VIA southbridge PIC
+ * 7 - unused
+ *
+ * The VIA chip is a master/slave 8259 setup and has the
+ * following interrupts
+ * 8 - RTC
+ * 9 - PCI
+ * 14 - IDE0
+ * 15 - IDE1
+ *
+ * In the table we use a 1 to indicate that we use a VIA interrupt
+ * line, and IE_IRQx to indicate that we use a CPU interrupt line
+ *
+ * We map all of these onto linux IRQ #s 0-15 and forget the rest
+ */
+#define NOINT_LINE 0
+#define CPUINT_LINE(x) IE_IRQ##x
+#define VIAINT_LINE 1
+
+#define COBALT_IRQS 16
+
+static unsigned short irqnr_to_type[COBALT_IRQS] =
+{ CPUINT_LINE(0), NOINT_LINE, VIAINT_LINE, NOINT_LINE,
+ CPUINT_LINE(1), NOINT_LINE, NOINT_LINE, CPUINT_LINE(3),
+ VIAINT_LINE, VIAINT_LINE, NOINT_LINE, NOINT_LINE,
+ NOINT_LINE, CPUINT_LINE(2), VIAINT_LINE, VIAINT_LINE };
+
+/*
+ * Cobalt CPU irq
+ */
+
+static void enable_cpu_irq(unsigned int irq)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ change_c0_status(irqnr_to_type[irq], irqnr_to_type[irq]);
+ local_irq_restore(flags);
+}
+
+static unsigned startup_cpu_irq(unsigned int irq)
+{
+ enable_cpu_irq(irq);
+
+ return 0;
+}
+
+static void disable_cpu_irq(unsigned int irq)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ change_c0_status(irqnr_to_type[irq], ~(irqnr_to_type[irq]));
+ local_irq_restore(flags);
+}
+
+#define shutdown_cpu_irq disable_cpu_irq
+#define mask_and_ack_cpu_irq disable_cpu_irq
+
+static void end_cpu_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ enable_cpu_irq(irq);
+}
+
+static struct hw_interrupt_type cobalt_cpu_irq_type = {
+ "Cobalt CPU",
+ startup_cpu_irq,
+ shutdown_cpu_irq,
+ enable_cpu_irq,
+ disable_cpu_irq,
+ mask_and_ack_cpu_irq,
+ end_cpu_irq,
+ NULL
+};
+
+void __init init_IRQ(void)
+{
+ int i;
+
+ /* Initialise all of the IRQ descriptors */
+ init_i8259_irqs();
+
+ /* Map the irqnr to the type int we have */
+ for (i=0; i < COBALT_IRQS; i++) {
+ if (irqnr_to_type[i] >= CPUINT_LINE(0))
+ /* cobalt_cpu_irq_type */
+ irq_desc[i].handler = &cobalt_cpu_irq_type;
+ }
+
+ /* Mask all cpu interrupts
+ (except IE4, we already masked those at VIA level) */
+ clear_c0_status(ST0_IM);
+ set_c0_status(IE_IRQ4);
+
+ cli();
+
+ set_except_vector(0, cobalt_handle_int);
+}
diff -Nru a/arch/mips/cobalt/promcon.c b/arch/mips/cobalt/promcon.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/mips/cobalt/promcon.c Mon Apr 14 20:10:17 2003
@@ -0,0 +1,91 @@
+/*
+ * PROM console for Cobalt Raq2
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+static unsigned long port = 0xc800000;
+
+static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr)
+{
+ char lsr;
+
+ do {
+ lsr = inb(ioaddr + UART_LSR);
+ } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+ outb(ch, ioaddr + UART_TX);
+}
+
+static __inline__ char ns16550_cons_get_char(unsigned long ioaddr)
+{
+ while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0)
+ udelay(1);
+ return inb(ioaddr + UART_RX);
+}
+
+void ns16550_console_write(struct console *co, const char *s, unsigned count)
+{
+ char lsr, ier;
+ unsigned i;
+
+ ier = inb(port + UART_IER);
+ outb(0x00, port + UART_IER);
+ for (i=0; i < count; i++, s++) {
+
+ if(*s == '\n')
+ ns16550_cons_put_char('\r', port);
+ ns16550_cons_put_char(*s, port);
+ }
+
+ do {
+ lsr = inb(port + UART_LSR);
+ } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
+
+ outb(ier, port + UART_IER);
+}
+
+char getDebugChar(void)
+{
+ return ns16550_cons_get_char(port);
+}
+
+void putDebugChar(char kgdb_char)
+{
+ ns16550_cons_put_char(kgdb_char, port);
+}
+
+static kdev_t
+ns16550_console_dev(struct console *c)
+{
+ return mk_kdev(TTY_MAJOR, 64 + c->index);
+}
+
+static struct console ns16550_console = {
+ .name = "prom",
+ .setup = NULL,
+ .write = ns16550_console_write,
+ .device = ns16550_console_dev,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+void __init ns16550_setup_console(void)
+{
+ register_console(&ns16550_console);
+}
diff -Nru a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/mips/cobalt/reset.c Mon Apr 14 20:10:17 2003
@@ -0,0 +1,68 @@
+/*
+ * Cobalt Reset operations
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+void cobalt_machine_restart(char *command)
+{
+ *(volatile char *)0xbc000000 = 0x0f;
+
+ /*
+ * Ouch, we're still alive ... This time we take the silver bullet ...
+ * ... and find that we leave the hardware in a state in which the
+ * kernel in the flush locks up somewhen during of after the PCI
+ * detection stuff.
+ */
+ set_c0_status(ST0_BEV | ST0_ERL);
+ change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+ flush_cache_all();
+ write_c0_wired(0);
+ __asm__ __volatile__(
+ "jr\t%0"
+ :
+ : "r" (0xbfc00000));
+}
+
+extern int led_state;
+#define kLED 0xBC000000
+#define LEDSet(x) (*(volatile unsigned char *) kLED) = (( unsigned char)x)
+
+void cobalt_machine_halt(void)
+{
+ int mark;
+
+ /* Blink our cute? little LED (number 3)... */
+ while (1) {
+ led_state = led_state | ( 1 << 3 );
+ LEDSet(led_state);
+ mark = jiffies;
+ while (jiffies<(mark+HZ));
+ led_state = led_state & ~( 1 << 3 );
+ LEDSet(led_state);
+ mark = jiffies;
+ while (jiffies<(mark+HZ));
+ }
+}
+
+/*
+ * This triggers the luser mode device driver for the power switch ;-)
+ */
+void cobalt_machine_power_off(void)
+{
+ printk("You can switch the machine off now.\n");
+ cobalt_machine_halt();
+}
diff -Nru a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/mips/cobalt/setup.c Mon Apr 14 20:10:17 2003
@@ -0,0 +1,113 @@
+/*
+ * Setup pointers to hardware dependent routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+extern void cobalt_machine_restart(char *command);
+extern void cobalt_machine_halt(void);
+extern void cobalt_machine_power_off(void);
+
+extern struct rtc_ops std_rtc_ops;
+extern struct ide_ops std_ide_ops;
+
+
+char arcs_cmdline[CL_SIZE] = {
+ "console=ttyS0,115200 "
+#ifdef CONFIG_IP_PNP
+ "ip=on "
+#endif
+#ifdef CONFIG_ROOT_NFS
+ "root=/dev/nfs "
+#else
+ "root=/dev/hda1 "
+#endif
+ };
+
+const char *get_system_type(void)
+{
+ return "MIPS Cobalt";
+}
+
+
+static void __init cobalt_time_init(void)
+{
+ rtc_ops = &std_rtc_ops;
+}
+
+static void __init cobalt_timer_setup(struct irqaction *irq)
+{
+ /* Load timer value for 150 Hz */
+ GALILEO_OUTL(500000, GT_TC0_OFS);
+
+ /* Register our timer interrupt */
+ setup_irq(COBALT_TIMER_IRQ, irq);
+
+ /* Enable timer ints */
+ GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS);
+ /* Unmask timer int */
+ GALILEO_OUTL(0x100, GT_INTRMASK_OFS);
+}
+
+
+void __init cobalt_setup(void)
+{
+
+ _machine_restart = cobalt_machine_restart;
+ _machine_halt = cobalt_machine_halt;
+ _machine_power_off = cobalt_machine_power_off;
+
+ board_time_init = cobalt_time_init;
+ board_timer_setup = cobalt_timer_setup;
+
+#ifdef CONFIG_BLK_DEV_IDE
+ ide_ops = &std_ide_ops;
+#endif
+
+ set_io_port_base(KSEG1ADDR(0x10000000));
+
+ /*
+ * This is a prom style console. We just poke at the
+ * UART to make it talk.
+ * Only use this console if you really screw up and can't
+ * get to the stage of setting up a real serial console.
+ */
+ /*ns16550_setup_console();*/
+}
+
+/* Prom init. We read our one and only communication with the
+ firmware. Grab the amount of installed memory */
+void __init prom_init(int argc)
+{
+ mips_machgroup = MACH_GROUP_COBALT;
+
+ add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* Nothing to do! */
+}
diff -Nru a/arch/mips/cobalt/via.c b/arch/mips/cobalt/via.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/arch/mips/cobalt/via.c Wed Apr 16 09:51:41 2003
@@ -0,0 +1,67 @@
+/*
+ * VIA chipset irq handling
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+
+asmlinkage void via_irq(struct pt_regs *regs)
+{
+ char mstat, sstat;
+
+ /* Read Master Status */
+ outb(0x0C, 0x20);
+ mstat = inb(0x20);
+
+ if (mstat < 0) {
+ mstat &= 0x7f;
+ if (mstat != 2) {
+ do_IRQ(mstat, regs);
+ outb(mstat | 0x20, 0x20);
+ } else {
+ sstat = inb(0xA0);
+
+ /* Slave interrupt */
+ outb(0x0C, 0xA0);
+ sstat = inb(0xA0);
+
+ if (sstat < 0) {
+ do_IRQ((sstat + 8) & 0x7f, regs);
+ outb(0x22, 0x20);
+ outb((sstat & 0x7f) | 0x20, 0xA0);
+ } else {
+ printk("Spurious slave interrupt...\n");
+ }
+ }
+ } else
+ printk("Spurious master interrupt...");
+}
+
+asmlinkage void galileo_irq(struct pt_regs *regs)
+{
+ unsigned long irq_src;
+
+ irq_src = GALILEO_INL(GT_INTRCAUSE_OFS);
+
+ /* Check for timer irq ... */
+ if (irq_src & GALILEO_T0EXP) {
+ /* Clear the int line */
+ GALILEO_OUTL(0, GT_INTRCAUSE_OFS);
+ do_IRQ(COBALT_TIMER_IRQ, regs);
+ } else
+ printk("Spurious Galileo interrupt...\n");
+}
diff -Nru a/arch/mips/ddb5074/Makefile b/arch/mips/ddb5074/Makefile
--- a/arch/mips/ddb5074/Makefile Sat Dec 14 04:38:56 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,8 +0,0 @@
-#
-# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines
-# under Linux.
-#
-
-EXTRA_AFLAGS := $(CFLAGS)
-
-obj-y := setup.o irq.o time.o prom.o pci.o int-handler.o nile4.o
diff -Nru a/arch/mips/ddb5074/int-handler.S b/arch/mips/ddb5074/int-handler.S
--- a/arch/mips/ddb5074/int-handler.S Mon Feb 4 23:39:24 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,120 +0,0 @@
-/*
- * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
- *
- * Based on arch/mips/sgi/kernel/indyIRQ.S
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-#include
-#include
-
-/* A lot of complication here is taken away because:
- *
- * 1) We handle one interrupt and return, sitting in a loop and moving across
- * all the pending IRQ bits in the cause register is _NOT_ the answer, the
- * common case is one pending IRQ so optimize in that direction.
- *
- * 2) We need not check against bits in the status register IRQ mask, that
- * would make this routine slow as hell.
- *
- * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
- * between like BSD spl() brain-damage.
- *
- * Furthermore, the IRQs on the INDY look basically (barring software IRQs
- * which we don't use at all) like:
- *
- * MIPS IRQ Source
- * -------- ------
- * 0 Software (ignored)
- * 1 Software (ignored)
- * 2 Local IRQ level zero
- * 3 Local IRQ level one
- * 4 8254 Timer zero
- * 5 8254 Timer one
- * 6 Bus Error
- * 7 R4k timer (what we use)
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ---- R4k Timer
- * Local IRQ zero
- * Local IRQ one
- * Bus Error
- * 8254 Timer zero
- * Lowest ---- 8254 Timer one
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
- .text
- .set noreorder
- .set noat
- .align 5
- NESTED(ddbIRQ, PT_SIZE, sp)
- SAVE_ALL
- CLI
- .set at
- mfc0 s0, CP0_CAUSE # get irq mask
-
-#if 1
- mfc0 t2,CP0_STATUS # get enabled interrupts
- and s0,t2 # isolate allowed ones
-#endif
- /* First we check for r4k counter/timer IRQ. */
- andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP3 # delay slot, check local level one
-
- /* Wheee, local level zero interrupt. */
- jal ddb_local0_irqdispatch
- move a0, sp # delay slot
-
- j ret_from_irq
- nop # delay slot
-
-1:
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP6 # delay slot, check bus error
-
- /* Wheee, local level one interrupt. */
- move a0, sp
- jal ddb_local1_irqdispatch
- nop
-
- j ret_from_irq
- nop
-
-1:
- beq a0, zero, 1f
- nop
-
- /* Wheee, an asynchronous bus error... */
- move a0, sp
- jal ddb_buserror_irq
- nop
-
- j ret_from_irq
- nop
-
-1:
- /* Here by mistake? This is possible, what can happen
- * is that by the time we take the exception the IRQ
- * pin goes low, so just leave if this is the case.
- */
- andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
- beq a0, zero, 1f
-
- /* Must be one of the 8254 timers... */
- move a0, sp
- jal ddb_8254timer_irq
- nop
-1:
- j ret_from_irq
- nop
- END(ddbIRQ)
diff -Nru a/arch/mips/ddb5074/irq.c b/arch/mips/ddb5074/irq.c
--- a/arch/mips/ddb5074/irq.c Mon Feb 4 23:39:24 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,226 +0,0 @@
-/*
- * arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-
-extern void __init i8259_init(void);
-extern void i8259_disable_irq(unsigned int irq_nr);
-extern void i8259_enable_irq(unsigned int irq_nr);
-
-extern asmlinkage void ddbIRQ(void);
-extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs);
-extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
-
-
-void no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
-}
-
-
-#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */
-#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */
-#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */
-
-#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */
-#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */
-#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */
-
-#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */
-#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */
-
-#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */
-#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */
-
-#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */
-#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */
-
-
-static void m1543_irq_setup(void)
-{
- /*
- * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all
- * the possible IO sources in the M1543 are in use by us. We will
- * use the following mapping:
- *
- * IRQ1 - keyboard (default set by M1543)
- * IRQ3 - reserved for UART B (default set by M1543) (note that
- * the schematics for the DDB Vrc-5074 board seem to
- * indicate that IRQ3 is connected to the DS1386
- * watchdog timer interrupt output so we might have
- * a conflict)
- * IRQ4 - reserved for UART A (default set by M1543)
- * IRQ5 - parallel (default set by M1543)
- * IRQ8 - DS1386 time of day (RTC) interrupt
- * IRQ12 - mouse
- */
-
- /*
- * Assing mouse interrupt to IRQ12
- */
-
- /* Enter configuration mode */
- outb(0x51, M1543_PNP_CONFIG);
- outb(0x23, M1543_PNP_CONFIG);
-
- /* Select logical device 7 (Keyboard) */
- outb(0x07, M1543_PNP_INDEX);
- outb(0x07, M1543_PNP_DATA);
-
- /* Select IRQ12 */
- outb(0x72, M1543_PNP_INDEX);
- outb(0x0c, M1543_PNP_DATA);
-
- /* Leave configration mode */
- outb(0xbb, M1543_PNP_CONFIG);
-
-
- /* Initialize the 8259 PIC in the M1543 */
- i8259_init();
-
- /* Enable the interrupt cascade */
- nile4_enable_irq(NILE4_INT_INTE);
-
- request_region(M1543_PNP_CONFIG, 2, "M1543 config");
- request_region(M1543_INT1_MASTER_ELCR, 2, "pic ELCR");
-}
-
-static void nile4_irq_setup(void)
-{
- int i;
-
- /* Map all interrupts to CPU int #0 */
- nile4_map_irq_all(0);
-
- /* PCI INTA#-E# must be level triggered */
- nile4_set_pci_irq_level_or_edge(0, 1);
- nile4_set_pci_irq_level_or_edge(1, 1);
- nile4_set_pci_irq_level_or_edge(2, 1);
- nile4_set_pci_irq_level_or_edge(3, 1);
- nile4_set_pci_irq_level_or_edge(4, 1);
-
- /* PCI INTA#-D# must be active low, INTE# must be active high */
- nile4_set_pci_irq_polarity(0, 0);
- nile4_set_pci_irq_polarity(1, 0);
- nile4_set_pci_irq_polarity(2, 0);
- nile4_set_pci_irq_polarity(3, 0);
- nile4_set_pci_irq_polarity(4, 1);
-
- for (i = 0; i < 16; i++)
- nile4_clear_irq(i);
-
- /* Enable CPU int #0 */
- nile4_enable_irq_output(0);
-
- request_mem_region(NILE4_BASE, NILE4_SIZE, "Nile 4");
-}
-
-
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL };
-
-
-void disable_irq(unsigned int irq_nr)
-{
- if (is_i8259_irq(irq_nr))
- i8259_disable_irq(irq_nr);
- else
- nile4_disable_irq(irq_to_nile4(irq_nr));
-}
-
-void enable_irq(unsigned int irq_nr)
-{
- if (is_i8259_irq(irq_nr))
- i8259_enable_irq(irq_nr);
- else
- nile4_enable_irq(irq_to_nile4(irq_nr));
-}
-
-int table[16] = { 0, };
-
-void ddb_local0_irqdispatch(struct pt_regs *regs)
-{
- u32 mask;
- int nile4_irq;
-#if 1
- volatile static int nesting = 0;
- if (nesting++ == 0)
- ddb5074_led_d3(1);
- ddb5074_led_hex(nesting < 16 ? nesting : 15);
-#endif
-
- mask = nile4_get_irq_stat(0);
- nile4_clear_irq_mask(mask);
-
- /* Handle the timer interrupt first */
- if (mask & (1 << NILE4_INT_GPT)) {
- nile4_disable_irq(NILE4_INT_GPT);
- do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs);
- nile4_enable_irq(NILE4_INT_GPT);
- mask &= ~(1 << NILE4_INT_GPT);
- }
- for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1)
- if (mask & 1) {
- nile4_disable_irq(nile4_irq);
- if (nile4_irq == NILE4_INT_INTE) {
- int i8259_irq = nile4_i8259_iack();
- i8259_do_irq(i8259_irq, regs);
- } else
- do_IRQ(nile4_to_irq(nile4_irq), regs);
- nile4_enable_irq(nile4_irq);
- }
-#if 1
- if (--nesting == 0)
- ddb5074_led_d3(0);
- ddb5074_led_hex(nesting < 16 ? nesting : 15);
-#endif
-}
-
-void ddb_local1_irqdispatch(void)
-{
- printk("ddb_local1_irqdispatch called\n");
-}
-
-void ddb_buserror_irq(void)
-{
- printk("ddb_buserror_irq called\n");
-}
-
-void ddb_8254timer_irq(void)
-{
- printk("ddb_8254timer_irq called\n");
-}
-
-void __init ddb_irq_setup(void)
-{
-#ifdef CONFIG_REMOTE_DEBUG
- if (remote_debug)
- set_debug_traps();
- breakpoint(); /* you may move this line to whereever you want :-) */
-#endif
- request_region(0x20, 0x20, "pic1");
- request_region(0xa0, 0x20, "pic2");
- i8259_setup_irq(2, &irq2);
-
- nile4_irq_setup();
- m1543_irq_setup();
-
- set_except_vector(0, ddbIRQ);
-}
diff -Nru a/arch/mips/ddb5074/nile4.c b/arch/mips/ddb5074/nile4.c
--- a/arch/mips/ddb5074/nile4.c Mon Feb 4 23:39:24 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,292 +0,0 @@
-/*
- * arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-
-#include
-
-
-/*
- * Physical Device Address Registers
- *
- * Note: 32 bit addressing only!
- */
-void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width,
- int on_memory_bus, int visible)
-{
- u32 maskbits;
- u32 widthbits;
-
- if (pdar > NILE4_BOOTCS || (pdar & 7)) {
- printk("nile4_set_pdar: invalid pdar %d\n", pdar);
- return;
- }
- if (pdar == NILE4_INTCS && size != 0x00200000) {
- printk("nile4_set_pdar: INTCS size must be 2 MB\n");
- return;
- }
- switch (size) {
-#if 0 /* We don't support 4 GB yet */
- case 0x100000000: /* 4 GB */
- maskbits = 4;
- break;
-#endif
- case 0x80000000: /* 2 GB */
- maskbits = 5;
- break;
- case 0x40000000: /* 1 GB */
- maskbits = 6;
- break;
- case 0x20000000: /* 512 MB */
- maskbits = 7;
- break;
- case 0x10000000: /* 256 MB */
- maskbits = 8;
- break;
- case 0x08000000: /* 128 MB */
- maskbits = 9;
- break;
- case 0x04000000: /* 64 MB */
- maskbits = 10;
- break;
- case 0x02000000: /* 32 MB */
- maskbits = 11;
- break;
- case 0x01000000: /* 16 MB */
- maskbits = 12;
- break;
- case 0x00800000: /* 8 MB */
- maskbits = 13;
- break;
- case 0x00400000: /* 4 MB */
- maskbits = 14;
- break;
- case 0x00200000: /* 2 MB */
- maskbits = 15;
- break;
- case 0: /* OFF */
- maskbits = 0;
- break;
- default:
- printk("nile4_set_pdar: unsupported size %p\n", (void *) size);
- return;
- }
- switch (width) {
- case 8:
- widthbits = 0;
- break;
- case 16:
- widthbits = 1;
- break;
- case 32:
- widthbits = 2;
- break;
- case 64:
- widthbits = 3;
- break;
- default:
- printk("nile4_set_pdar: unsupported width %d\n", width);
- return;
- }
- nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) |
- (visible ? 0x20 : 0) | (widthbits << 6) |
- (phys & 0xffe00000));
- nile4_out32(pdar + 4, 0);
- /*
- * When programming a PDAR, the register should be read immediately
- * after writing it. This ensures that address decoders are properly
- * configured.
- */
- nile4_in32(pdar);
- nile4_in32(pdar + 4);
-}
-
-
-/*
- * PCI Master Registers
- *
- * Note: 32 bit addressing only!
- */
-void nile4_set_pmr(u32 pmr, u32 type, u32 addr)
-{
- if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) {
- printk("nile4_set_pmr: invalid pmr %d\n", pmr);
- return;
- }
- switch (type) {
- case NILE4_PCICMD_IACK: /* PCI Interrupt Acknowledge */
- case NILE4_PCICMD_IO: /* PCI I/O Space */
- case NILE4_PCICMD_MEM: /* PCI Memory Space */
- case NILE4_PCICMD_CFG: /* PCI Configuration Space */
- break;
- default:
- printk("nile4_set_pmr: invalid type %d\n", type);
- return;
- }
- nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000));
- nile4_out32(pmr + 4, 0);
-}
-
-
-/*
- * Interrupt Programming
- */
-void nile4_map_irq(int nile4_irq, int cpu_irq)
-{
- u32 offset, t;
-
- offset = NILE4_INTCTRL;
- if (nile4_irq >= 8) {
- offset += 4;
- nile4_irq -= 8;
- }
- t = nile4_in32(offset);
- t &= ~(7 << (nile4_irq * 4));
- t |= cpu_irq << (nile4_irq * 4);
- nile4_out32(offset, t);
-}
-
-void nile4_map_irq_all(int cpu_irq)
-{
- u32 all, t;
-
- all = cpu_irq;
- all |= all << 4;
- all |= all << 8;
- all |= all << 16;
- t = nile4_in32(NILE4_INTCTRL);
- t &= 0x88888888;
- t |= all;
- nile4_out32(NILE4_INTCTRL, t);
- t = nile4_in32(NILE4_INTCTRL + 4);
- t &= 0x88888888;
- t |= all;
- nile4_out32(NILE4_INTCTRL + 4, t);
-}
-
-void nile4_enable_irq(int nile4_irq)
-{
- u32 offset, t;
-
- offset = NILE4_INTCTRL;
- if (nile4_irq >= 8) {
- offset += 4;
- nile4_irq -= 8;
- }
- t = nile4_in32(offset);
- t |= 8 << (nile4_irq * 4);
- nile4_out32(offset, t);
-}
-
-void nile4_disable_irq(int nile4_irq)
-{
- u32 offset, t;
-
- offset = NILE4_INTCTRL;
- if (nile4_irq >= 8) {
- offset += 4;
- nile4_irq -= 8;
- }
- t = nile4_in32(offset);
- t &= ~(8 << (nile4_irq * 4));
- nile4_out32(offset, t);
-}
-
-void nile4_disable_irq_all(void)
-{
- nile4_out32(NILE4_INTCTRL, 0);
- nile4_out32(NILE4_INTCTRL + 4, 0);
-}
-
-u16 nile4_get_irq_stat(int cpu_irq)
-{
- return nile4_in16(NILE4_INTSTAT0 + cpu_irq * 2);
-}
-
-void nile4_enable_irq_output(int cpu_irq)
-{
- u32 t;
-
- t = nile4_in32(NILE4_INTSTAT1 + 4);
- t |= 1 << (16 + cpu_irq);
- nile4_out32(NILE4_INTSTAT1, t);
-}
-
-void nile4_disable_irq_output(int cpu_irq)
-{
- u32 t;
-
- t = nile4_in32(NILE4_INTSTAT1 + 4);
- t &= ~(1 << (16 + cpu_irq));
- nile4_out32(NILE4_INTSTAT1, t);
-}
-
-void nile4_set_pci_irq_polarity(int pci_irq, int high)
-{
- u32 t;
-
- t = nile4_in32(NILE4_INTPPES);
- if (high)
- t &= ~(1 << (pci_irq * 2));
- else
- t |= 1 << (pci_irq * 2);
- nile4_out32(NILE4_INTPPES, t);
-}
-
-void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
-{
- u32 t;
-
- t = nile4_in32(NILE4_INTPPES);
- if (level)
- t |= 2 << (pci_irq * 2);
- else
- t &= ~(2 << (pci_irq * 2));
- nile4_out32(NILE4_INTPPES, t);
-}
-
-void nile4_clear_irq(int nile4_irq)
-{
- nile4_out32(NILE4_INTCLR, 1 << nile4_irq);
-}
-
-void nile4_clear_irq_mask(u32 mask)
-{
- nile4_out32(NILE4_INTCLR, mask);
-}
-
-u8 nile4_i8259_iack(void)
-{
- u8 irq;
-
- /* Set window 0 for interrupt acknowledge */
- nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0);
- irq = *(volatile u8 *) NILE4_PCI_IACK_BASE;
- /* Set window 0 for PCI I/O space */
- nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0);
- return irq;
-}
-
-#if 0
-void nile4_dump_irq_status(void)
-{
- printk("CPUSTAT = %p:%p\n", (void *) nile4_in32(NILE4_CPUSTAT + 4),
- (void *) nile4_in32(NILE4_CPUSTAT));
- printk("INTCTRL = %p:%p\n", (void *) nile4_in32(NILE4_INTCTRL + 4),
- (void *) nile4_in32(NILE4_INTCTRL));
- printk("INTSTAT0 = %p:%p\n",
- (void *) nile4_in32(NILE4_INTSTAT0 + 4),
- (void *) nile4_in32(NILE4_INTSTAT0));
- printk("INTSTAT1 = %p:%p\n",
- (void *) nile4_in32(NILE4_INTSTAT1 + 4),
- (void *) nile4_in32(NILE4_INTSTAT1));
- printk("INTCLR = %p:%p\n", (void *) nile4_in32(NILE4_INTCLR + 4),
- (void *) nile4_in32(NILE4_INTCLR));
- printk("INTPPES = %p:%p\n", (void *) nile4_in32(NILE4_INTPPES + 4),
- (void *) nile4_in32(NILE4_INTPPES));
-}
-#endif
diff -Nru a/arch/mips/ddb5074/pci.c b/arch/mips/ddb5074/pci.c
--- a/arch/mips/ddb5074/pci.c Wed Jun 4 07:34:32 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,366 +0,0 @@
-/*
- * arch/mips/ddb5074/pci.c -- NEC DDB Vrc-5074 PCI access routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Albert Dorofeev
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-
-static u32 nile4_pre_pci_access0(int slot_num)
-{
- u32 pci_addr = 0;
- u32 virt_addr = NILE4_PCI_CFG_BASE;
-
- /* Set window 1 address 8000000 - 64 bit - 2 MB (PCI config space) */
- nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x00200000, 64, 0,
- 0);
- if (slot_num > 2)
- pci_addr = 0x00040000 << slot_num;
- else
- virt_addr += 0x00040000 << slot_num;
- nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr);
- return virt_addr;
-}
-
-static void nile4_post_pci_access0(void)
-{
- /*
- * Set window 1 back to address 8000000 - 64 bit - 128 MB
- * (PCI IO space)
- */
- nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE),
- 0x08000000, 64, 1, 1);
- nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0);
-}
-
-
-static int nile4_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 * val)
-{
- int status, slot_num, func_num;
- u32 result, base;
-
- switch (size) {
- case 4:
- /*
- * For starters let's do configuration cycle 0 only
- * (one bus only)
- */
- if (bus->number)
- return PCIBIOS_FUNC_NOT_SUPPORTED;
-
- slot_num = PCI_SLOT(devfn);
- func_num = PCI_FUNC(devfn);
- if (slot_num == 5) {
- /*
- * This is Nile 4 and it will crash if we access it
- * like other devices
- */
- *val = nile4_in32(NILE4_PCI_BASE + where);
- return PCIBIOS_SUCCESSFUL;
- }
- base = nile4_pre_pci_access0(slot_num);
- *val = *((volatile u32 *) (base + (func_num << 8) +
- (where & 0xfc)));
- nile4_post_pci_access0();
- return PCIBIOS_SUCCESSFUL;
-
- case 2:
- status = nile4_pci_read(bus, devfn, where, 4, &result);
- if (status != PCIBIOS_SUCCESSFUL)
- return status;
- if (where & 2)
- result >>= 16;
- *val = (u16)(result & 0xffff);
- break;
- case 1:
- status = nile4_pci_read(bus, devfn, where, 4, &result);
- if (status != PCIBIOS_SUCCESSFUL)
- return status;
- if (where & 1)
- result >>= 8;
- if (where & 2)
- result >>= 16;
- *val = (u8)(result & 0xff);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-
-static int nile4_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 val)
-{
- int status, slot_num, func_num, shift = 0;
- u32 result, base;
-
- switch (size) {
- case 4:
- /*
- * For starters let's do configuration cycle 0 only
- * (one bus only)
- */
- if (bus->number)
- return PCIBIOS_FUNC_NOT_SUPPORTED;
-
- slot_num = PCI_SLOT(devfn);
- func_num = PCI_FUNC(devfn);
- if (slot_num == 5) {
- /*
- * This is Nile 4 and it will crash if we access
- * it like other devices
- */
- nile4_out32(NILE4_PCI_BASE + where, val);
- return PCIBIOS_SUCCESSFUL;
- }
- base = nile4_pre_pci_access0(slot_num);
- *((volatile u32 *) (base + (func_num << 8) +
- (where & 0xfc))) = val;
- nile4_post_pci_access0();
- return PCIBIOS_SUCCESSFUL;
-
- case 2:
- status = nile4_pci_read(bus, devfn, where, 4, &result);
- if (status != PCIBIOS_SUCCESSFUL)
- return status;
- if (where & 2)
- shift += 16;
- result &= ~(0xffff << shift);
- result |= (u16)(val << shift);
- break;
- case 1:
- status = nile4_pci_read(bus, devfn, where, 4, &result);
- if (status != PCIBIOS_SUCCESSFUL)
- return status;
- if (where & 2)
- shift += 16;
- if (where & 1)
- shift += 8;
- result &= ~(0xff << shift);
- result |= (u8)(val << shift);
- break;
- }
- return nile4_pci_write(bus, devfn, where, 4, result);
-}
-
-struct pci_ops nile4_pci_ops = {
- .read = nile4_pci_read,
- .write = nile4_pci_write,
-};
-
-struct {
- struct resource ram;
- struct resource flash;
- struct resource isa_io;
- struct resource pci_io;
- struct resource isa_mem;
- struct resource pci_mem;
- struct resource nile4;
- struct resource boot;
-} ddb5074_resources = {
- { "RAM", 0x00000000, 0x03ffffff,
- IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64},
- { "Flash ROM", 0x04000000, 0x043fffff},
- { "Nile4 ISA I/O", 0x06000000, 0x060fffff},
- { "Nile4 PCI I/O", 0x06100000, 0x07ffffff},
- { "Nile4 ISA mem", 0x08000000, 0x08ffffff, IORESOURCE_MEM},
- { "Nile4 PCI mem", 0x09000000, 0x0fffffff, IORESOURCE_MEM},
- { "Nile4 ctrl", 0x1fa00000, 0x1fbfffff,
- IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64},
- { "Boot ROM", 0x1fc00000, 0x1fffffff}
-};
-
-static void __init ddb5074_pci_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- if (dev->vendor == PCI_VENDOR_ID_NEC &&
- dev->device == PCI_DEVICE_ID_NEC_NILE4) {
- /*
- * The first 64-bit PCI base register should point to
- * the Nile4 control registers. Unfortunately this
- * isn't the case, so we fix it ourselves. This allows
- * the serial driver to find the UART.
- */
- dev->resource[0] = ddb5074_resources.nile4;
- request_resource(&iomem_resource,
- &dev->resource[0]);
- /*
- * The second 64-bit PCI base register points to the
- * first memory bank. Unfortunately the address is
- * wrong, so we fix it (again).
- */
- dev->resource[2] = ddb5074_resources.ram;
- request_resource(&iomem_resource,
- &dev->resource[2]);
- } else if (dev->vendor == PCI_VENDOR_ID_AL
- && dev->device == PCI_DEVICE_ID_AL_M7101) {
- /*
- * It's nice to have the LEDs on the GPIO pins
- * available for debugging
- */
- extern struct pci_dev *pci_pmu;
- u8 t8;
-
- pci_pmu = dev; /* for LEDs D2 and D3 */
- /* Program the lines for LEDs D2 and D3 to output */
- nile4_pci_read_config_byte(dev, 0x7d, &t8);
- t8 |= 0xc0;
- nile4_pci_write_config_byte(dev, 0x7d, t8);
- /* Turn LEDs D2 and D3 off */
- nile4_pci_read_config_byte(dev, 0x7e, &t8);
- t8 |= 0xc0;
- nile4_pci_write_config_byte(dev, 0x7e, t8);
- }
- }
-}
-
-static void __init pcibios_fixup_irqs(void)
-{
- struct pci_dev *dev = NULL;
- int slot_num;
-
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- slot_num = PCI_SLOT(dev->devfn);
- switch (slot_num) {
- case 0:
- dev->irq = nile4_to_irq(NILE4_INT_INTE);
- break;
- case 1:
- dev->irq = nile4_to_irq(NILE4_INT_INTA);
- break;
- case 2: /* slot 1 */
- dev->irq = nile4_to_irq(NILE4_INT_INTA);
- break;
- case 3: /* slot 2 */
- dev->irq = nile4_to_irq(NILE4_INT_INTB);
- break;
- case 4: /* slot 3 */
- dev->irq = nile4_to_irq(NILE4_INT_INTC);
- break;
- case 5:
- /*
- * Fixup so the serial driver can use the UART
- */
- dev->irq = nile4_to_irq(NILE4_INT_UART);
- break;
- case 13:
- dev->irq = nile4_to_irq(NILE4_INT_INTE);
- break;
- default:
- break;
- }
- }
-}
-
-void __init pcibios_init(void)
-{
- printk("PCI: Probing PCI hardware\n");
- ioport_resource.end = 0x1ffffff; /* 32 MB */
- iomem_resource.end = 0x1fffffff; /* 512 MB */
- /* `ram' and `nile4' are requested through the Nile4 pci_dev */
- request_resource(&iomem_resource, &ddb5074_resources.flash);
- request_resource(&iomem_resource, &ddb5074_resources.isa_io);
- request_resource(&iomem_resource, &ddb5074_resources.pci_io);
- request_resource(&iomem_resource, &ddb5074_resources.isa_mem);
- request_resource(&iomem_resource, &ddb5074_resources.pci_mem);
- request_resource(&iomem_resource, &ddb5074_resources.boot);
-
- pci_scan_bus(0, &nile4_pci_ops, NULL);
- ddb5074_pci_fixup();
- pci_assign_unassigned_resources();
- pcibios_fixup_irqs();
-}
-
-void __init pcibios_fixup_bus(struct pci_bus *bus)
-{
- bus->resource[1] = &ddb5074_resources.pci_mem;
-}
-
-char *pcibios_setup(char *str)
-{
- return str;
-}
-
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
-int pcibios_enable_resources(struct pci_dev *dev)
-{
- u16 cmd, old_cmd;
- int idx;
- struct resource *r;
-
- /*
- * Don't touch the Nile 4
- */
- if (dev->vendor == PCI_VENDOR_ID_NEC &&
- dev->device == PCI_DEVICE_ID_NEC_NILE4) return 0;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- old_cmd = cmd;
- for (idx = 0; idx < 6; idx++) {
- r = &dev->resource[idx];
- if (!r->start && r->end) {
- printk(KERN_ERR "PCI: Device %s not available because "
- "of resource collisions\n", dev->slot_name);
- return -EINVAL;
- }
- if (r->flags & IORESOURCE_IO)
- cmd |= PCI_COMMAND_IO;
- if (r->flags & IORESOURCE_MEM)
- cmd |= PCI_COMMAND_MEMORY;
- }
- if (cmd != old_cmd) {
- printk("PCI: Enabling device %s (%04x -> %04x)\n",
- dev->slot_name, old_cmd, cmd);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
- return 0;
-}
-
-int pcibios_enable_device(struct pci_dev *dev)
-{
- return pcibios_enable_resources(dev);
-}
-
-void pcibios_align_resource(void *data, struct resource *res,
- unsigned long size, unsigned long align)
-{
- struct pci_dev *dev = data;
-
- if (res->flags & IORESOURCE_IO) {
- unsigned long start = res->start;
-
- /* We need to avoid collisions with `mirrored' VGA ports
- and other strange ISA hardware, so we always want the
- addresses kilobyte aligned. */
- if (size > 0x100) {
- printk(KERN_ERR "PCI: I/O Region %s/%d too large"
- " (%ld bytes)\n", dev->slot_name,
- dev->resource - res, size);
- }
-
- start = (start + 1024 - 1) & ~(1024 - 1);
- res->start = start;
- }
-}
-
-unsigned __init int pcibios_assign_all_busses(void)
-{
- return 1;
-}
-
-struct pci_fixup pcibios_fixups[] = { };
diff -Nru a/arch/mips/ddb5074/prom.c b/arch/mips/ddb5074/prom.c
--- a/arch/mips/ddb5074/prom.c Mon Feb 4 23:39:24 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,36 +0,0 @@
-/*
- * arch/mips/ddb5074/prom.c -- NEC DDB Vrc-5074 PROM routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-
-char arcs_cmdline[COMMAND_LINE_SIZE];
-
-void __init prom_init(const char *s)
-{
- int i = 0;
-
- if (s != (void *) -1)
- while (*s && i < sizeof(arcs_cmdline) - 1)
- arcs_cmdline[i++] = *s++;
- arcs_cmdline[i] = '\0';
-
- mips_machgroup = MACH_GROUP_NEC_DDB;
- mips_machtype = MACH_NEC_DDB5074;
-
- /* 64 MB non-upgradable */
- add_memory_region(0, 64 << 20, BOOT_MEM_RAM);
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
diff -Nru a/arch/mips/ddb5074/setup.c b/arch/mips/ddb5074/setup.c
--- a/arch/mips/ddb5074/setup.c Mon Feb 4 23:39:24 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,246 +0,0 @@
-/*
- * arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 setup routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-
-#ifdef CONFIG_REMOTE_DEBUG
-extern void rs_kgdb_hook(int);
-extern void breakpoint(void);
-#endif
-
-#if defined(CONFIG_SERIAL_CONSOLE)
-extern void console_setup(char *);
-#endif
-
-extern struct ide_ops std_ide_ops;
-extern struct rtc_ops ddb_rtc_ops;
-
-static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
-
-static void ddb_machine_restart(char *command)
-{
- u32 t;
-
- /* PCI cold reset */
- t = nile4_in32(NILE4_PCICTRL + 4);
- t |= 0x40000000;
- nile4_out32(NILE4_PCICTRL + 4, t);
- /* CPU cold reset */
- t = nile4_in32(NILE4_CPUSTAT);
- t |= 1;
- nile4_out32(NILE4_CPUSTAT, t);
- /* Call the PROM */
- back_to_prom();
-}
-
-static void ddb_machine_halt(void)
-{
- printk("DDB Vrc-5074 halted.\n");
- do {
- } while (1);
-}
-
-static void ddb_machine_power_off(void)
-{
- printk("DDB Vrc-5074 halted. Please turn off the power.\n");
- do {
- } while (1);
-}
-
-extern void ddb_irq_setup(void);
-
-void (*board_time_init) (struct irqaction * irq);
-
-
-static void __init ddb_time_init(struct irqaction *irq)
-{
- /* set the clock to 1 Hz */
- nile4_out32(NILE4_T2CTRL, 1000000);
- /* enable the General-Purpose Timer */
- nile4_out32(NILE4_T2CTRL + 4, 0x00000001);
- /* reset timer */
- nile4_out32(NILE4_T2CNTR, 0);
- /* enable interrupt */
- nile4_enable_irq(NILE4_INT_GPT);
- i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq);
- change_cp0_status(ST0_IM,
- IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
-}
-
-void __init ddb_setup(void)
-{
- extern int panic_timeout;
-
- irq_setup = ddb_irq_setup;
- mips_io_port_base = NILE4_PCI_IO_BASE;
- isa_slot_offset = NILE4_PCI_MEM_BASE;
- request_region(0x00, 0x20, "dma1");
- request_region(0x40, 0x20, "timer");
- request_region(0x70, 0x10, "rtc");
- request_region(0x80, 0x10, "dma page reg");
- request_region(0xc0, 0x20, "dma2");
- board_time_init = ddb_time_init;
-
- _machine_restart = ddb_machine_restart;
- _machine_halt = ddb_machine_halt;
- _machine_power_off = ddb_machine_power_off;
-
-#ifdef CONFIG_BLK_DEV_IDE
- ide_ops = &std_ide_ops;
-#endif
- rtc_ops = &ddb_rtc_ops;
-
- /* Reboot on panic */
- panic_timeout = 180;
-}
-
-
-#define USE_NILE4_SERIAL 0
-
-#if USE_NILE4_SERIAL
-#define ns16550_in(reg) nile4_in8((reg)*8)
-#define ns16550_out(reg, val) nile4_out8((reg)*8, (val))
-#else
-#define NS16550_BASE (NILE4_PCI_IO_BASE+0x03f8)
-static inline u8 ns16550_in(u32 reg)
-{
- return *(volatile u8 *) (NS16550_BASE + reg);
-}
-
-static inline void ns16550_out(u32 reg, u8 val)
-{
- *(volatile u8 *) (NS16550_BASE + reg) = val;
-}
-#endif
-
-#define NS16550_RBR 0
-#define NS16550_THR 0
-#define NS16550_DLL 0
-#define NS16550_IER 1
-#define NS16550_DLM 1
-#define NS16550_FCR 2
-#define NS16550_IIR 2
-#define NS16550_LCR 3
-#define NS16550_MCR 4
-#define NS16550_LSR 5
-#define NS16550_MSR 6
-#define NS16550_SCR 7
-
-#define NS16550_LSR_DR 0x01 /* Data ready */
-#define NS16550_LSR_OE 0x02 /* Overrun */
-#define NS16550_LSR_PE 0x04 /* Parity error */
-#define NS16550_LSR_FE 0x08 /* Framing error */
-#define NS16550_LSR_BI 0x10 /* Break */
-#define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */
-#define NS16550_LSR_TEMT 0x40 /* Xmitter empty */
-#define NS16550_LSR_ERR 0x80 /* Error */
-
-
-void _serinit(void)
-{
-#if USE_NILE4_SERIAL
- ns16550_out(NS16550_LCR, 0x80);
- ns16550_out(NS16550_DLM, 0x00);
- ns16550_out(NS16550_DLL, 0x36); /* 9600 baud */
- ns16550_out(NS16550_LCR, 0x00);
- ns16550_out(NS16550_LCR, 0x03);
- ns16550_out(NS16550_FCR, 0x47);
-#else
- /* done by PMON */
-#endif
-}
-
-void _putc(char c)
-{
- while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
- ns16550_out(NS16550_THR, c);
- if (c == '\n') {
- while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
- ns16550_out(NS16550_THR, '\r');
- }
-}
-
-void _puts(const char *s)
-{
- char c;
- while ((c = *s++))
- _putc(c);
-}
-
-char _getc(void)
-{
- while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR));
- return ns16550_in(NS16550_RBR);
-}
-
-int _testc(void)
-{
- return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0;
-}
-
-
-/*
- * Hexadecimal 7-segment LED
- */
-void ddb5074_led_hex(int hex)
-{
- outb(hex, 0x80);
-}
-
-
-/*
- * LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543
- */
-struct pci_dev *pci_pmu = NULL;
-
-void ddb5074_led_d2(int on)
-{
- u8 t;
-
- if (pci_pmu) {
- pci_read_config_byte(pci_pmu, 0x7e, &t);
- if (on)
- t &= 0x7f;
- else
- t |= 0x80;
- pci_write_config_byte(pci_pmu, 0x7e, t);
- }
-}
-
-void ddb5074_led_d3(int on)
-{
- u8 t;
-
- if (pci_pmu) {
- pci_read_config_byte(pci_pmu, 0x7e, &t);
- if (on)
- t &= 0xbf;
- else
- t |= 0x40;
- pci_write_config_byte(pci_pmu, 0x7e, t);
- }
-}
diff -Nru a/arch/mips/ddb5074/time.c b/arch/mips/ddb5074/time.c
--- a/arch/mips/ddb5074/time.c Mon Feb 4 23:39:24 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- * arch/mips/ddb5074/time.c -- Timer routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-
-static unsigned char ddb_rtc_read_data(unsigned long addr)
-{
- outb_p(addr, RTC_PORT(0));
-
- return inb_p(RTC_PORT(1));
-}
-
-static void ddb_rtc_write_data(unsigned char data, unsigned long addr)
-{
- outb_p(addr, RTC_PORT(0));
- outb_p(data, RTC_PORT(1));
-}
-
-static int ddb_rtc_bcd_mode(void)
-{
- return 1;
-}
-
-struct rtc_ops ddb_rtc_ops = {
- ddb_rtc_read_data,
- ddb_rtc_write_data,
- ddb_rtc_bcd_mode
-};
diff -Nru a/arch/mips/ddb5476/Makefile b/arch/mips/ddb5476/Makefile
--- a/arch/mips/ddb5476/Makefile Sat Dec 14 04:38:56 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,10 +0,0 @@
-#
-# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines
-# under Linux.
-#
-
-EXTRA_AFLAGS := $(CFLAGS)
-
-obj-y += setup.o irq.o time.o prom.o pci.o \
- int-handler.o nile4.o
-obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
diff -Nru a/arch/mips/ddb5476/dbg_io.c b/arch/mips/ddb5476/dbg_io.c
--- a/arch/mips/ddb5476/dbg_io.c Tue Feb 5 10:12:45 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,125 +0,0 @@
-
-#include
-
-#if (defined(CONFIG_DDB5476) && defined(CONFIG_REMOTE_DEBUG))
-
-/* --- CONFIG --- */
-
-/* we need uint32 uint8 */
-/* #include "types.h" */
-typedef unsigned char uint8;
-typedef unsigned int uint32;
-
-/* --- END OF CONFIG --- */
-
-#define UART16550_BAUD_2400 2400
-#define UART16550_BAUD_4800 4800
-#define UART16550_BAUD_9600 9600
-#define UART16550_BAUD_19200 19200
-#define UART16550_BAUD_38400 38400
-#define UART16550_BAUD_57600 57600
-#define UART16550_BAUD_115200 115200
-
-#define UART16550_PARITY_NONE 0
-#define UART16550_PARITY_ODD 0x08
-#define UART16550_PARITY_EVEN 0x18
-#define UART16550_PARITY_MARK 0x28
-#define UART16550_PARITY_SPACE 0x38
-
-#define UART16550_DATA_5BIT 0x0
-#define UART16550_DATA_6BIT 0x1
-#define UART16550_DATA_7BIT 0x2
-#define UART16550_DATA_8BIT 0x3
-
-#define UART16550_STOP_1BIT 0x0
-#define UART16550_STOP_2BIT 0x4
-
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-
-/* [jsun] we use the second serial port for kdb */
-#define BASE 0xa60002f8
-#define MAX_BAUD 115200
-
-/* === END OF CONFIG === */
-
-/* register offset */
-#define OFS_RCV_BUFFER 0
-#define OFS_TRANS_HOLD 0
-#define OFS_SEND_BUFFER 0
-#define OFS_INTR_ENABLE 1
-#define OFS_INTR_ID 2
-#define OFS_DATA_FORMAT 3
-#define OFS_LINE_CONTROL 3
-#define OFS_MODEM_CONTROL 4
-#define OFS_RS232_OUTPUT 4
-#define OFS_LINE_STATUS 5
-#define OFS_MODEM_STATUS 6
-#define OFS_RS232_INPUT 6
-#define OFS_SCRATCH_PAD 7
-
-#define OFS_DIVISOR_LSB 0
-#define OFS_DIVISOR_MSB 1
-
-
-/* memory-mapped read/write of the port */
-#define UART16550_READ(y) (*((volatile uint8*)(BASE + y)))
-#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z)
-
-void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
-{
- /* disable interrupts */
- UART16550_WRITE(OFS_INTR_ENABLE, 0);
-
- /* set up buad rate */
- {
- uint32 divisor;
-
- /* set DIAB bit */
- UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
- /* set divisor */
- divisor = MAX_BAUD / baud;
- UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
- UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
- /* clear DIAB bit */
- UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
- }
-
- /* set data format */
- UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized = 0;
-
-uint8 getDebugChar(void)
-{
- if (!remoteDebugInitialized) {
- remoteDebugInitialized = 1;
- debugInit(UART16550_BAUD_38400,
- UART16550_DATA_8BIT,
- UART16550_PARITY_NONE, UART16550_STOP_1BIT);
- }
-
- while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
- return UART16550_READ(OFS_RCV_BUFFER);
-}
-
-
-int putDebugChar(uint8 byte)
-{
- if (!remoteDebugInitialized) {
- remoteDebugInitialized = 1;
- debugInit(UART16550_BAUD_9600,
- UART16550_DATA_8BIT,
- UART16550_PARITY_NONE, UART16550_STOP_1BIT);
- }
-
- while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
- UART16550_WRITE(OFS_SEND_BUFFER, byte);
- return 1;
-}
-
-#endif
diff -Nru a/arch/mips/ddb5476/int-handler.S b/arch/mips/ddb5476/int-handler.S
--- a/arch/mips/ddb5476/int-handler.S Mon Feb 4 23:45:04 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,136 +0,0 @@
-/*
- * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
- *
- * Based on arch/mips/sgi/kernel/indyIRQ.S
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-#include
-#include
-
-/*
- * A lot of complication here is taken away because:
- *
- * 1) We handle one interrupt and return, sitting in a loop and moving across
- * all the pending IRQ bits in the cause register is _NOT_ the answer, the
- * common case is one pending IRQ so optimize in that direction.
- *
- * 2) We need not check against bits in the status register IRQ mask, that
- * would make this routine slow as hell.
- *
- * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
- * between like BSD spl() brain-damage.
- *
- * Furthermore, the IRQs on the INDY look basically (barring software IRQs
- * which we don't use at all) like:
- *
- * MIPS IRQ Source
- * -------- ------
- * 0 Software (ignored)
- * 1 Software (ignored)
- * 2 Local IRQ level zero
- * 3 Local IRQ level one
- * 4 8254 Timer zero
- * 5 8254 Timer one
- * 6 Bus Error
- * 7 R4k timer (what we use)
- *
- * We handle the IRQ according to _our_ priority which is:
- *
- * Highest ---- R4k Timer
- * Local IRQ zero
- * Local IRQ one
- * Bus Error
- * 8254 Timer zero
- * Lowest ---- 8254 Timer one
- *
- * then we just return, if multiple IRQs are pending then we will just take
- * another exception, big deal.
- */
-
- .text
- .set noreorder
- .set noat
- .align 5
- NESTED(ddbIRQ, PT_SIZE, sp)
- SAVE_ALL
- CLI
- .set at
- mfc0 s1, CP0_CAUSE # get irq mask
-
-#if 1
- mfc0 t2,CP0_STATUS # get enabled interrupts
- and s0, s1, t2 # isolate allowed ones
-#endif
- /* First we check for r4k counter/timer IRQ. */
- andi a0, s0, CAUSEF_IP7 # cpu timer */
- bnez a0, cpu_timer_irq
- andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP3 # delay slot, check local level one
-
- /* Wheee, local level zero interrupt. */
- jal ddb_local0_irqdispatch
- move a0, sp # delay slot
-
- j ret_from_irq
- nop # delay slot
-
-1:
- beq a0, zero, 1f
- andi a0, s0, CAUSEF_IP6 # delay slot, check bus error
-
- /* Wheee, local level one interrupt. */
- move a0, sp
- jal ddb_local1_irqdispatch
- nop
-
- j ret_from_irq
- nop
-
-1:
- beq a0, zero, 1f
- nop
-
- /* Wheee, an asynchronous bus error... */
- move a0, sp
- jal ddb_buserror_irq
- nop
-
- j ret_from_irq
- nop
-
-1:
- /* Here by mistake? This is possible, what can happen
- * is that by the time we take the exception the IRQ
- * pin goes low, so just leave if this is the case.
- */
- andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
- beq a0, zero, 1f
-
- /* Must be one of the 8254 timers... */
- move a0, sp
- jal ddb_8254timer_irq
- nop
-1:
- /* phamtom interrupt */
- move a0, s1
- jal ddb_phantom_irq
- nop
- j ret_from_irq
- nop
-
-cpu_timer_irq:
- li a0, 0
- move a1, sp
- jal do_IRQ
- /* jal ll_timer_interrupt */
- nop
- j ret_from_irq
- nop
- END(ddbIRQ)
diff -Nru a/arch/mips/ddb5476/irq.c b/arch/mips/ddb5476/irq.c
--- a/arch/mips/ddb5476/irq.c Tue Feb 5 10:12:45 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,251 +0,0 @@
-/*
- * arch/mips/ddb5476/irq.c -- NEC DDB Vrc-5476 interrupt routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-extern void __init i8259_init(void);
-extern void i8259_disable_irq(unsigned int irq_nr);
-extern void i8259_enable_irq(unsigned int irq_nr);
-
-extern asmlinkage void ddbIRQ(void);
-extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs);
-extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
-
-
-void no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
-}
-
-
-#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */
-#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */
-#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */
-
-#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */
-#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */
-#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */
-
-#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */
-#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */
-
-#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */
-#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */
-
-#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */
-#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */
-
-static struct {
- struct resource m1543_config;
- struct resource pic_elcr;
-} m1543_ioport = {
- { "M1543 config", M1543_PNP_CONFIG, M1543_PNP_CONFIG + 1,
- IORESOURCE_BUSY},
- { "pic ELCR", M1543_INT1_MASTER_ELCR, M1543_INT1_MASTER_ELCR + 1,
- IORESOURCE_BUSY}
-};
-
-static void m1543_irq_setup(void)
-{
- /*
- * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all
- * the possible IO sources in the M1543 are in use by us. We will
- * use the following mapping:
- *
- * IRQ1 - keyboard (default set by M1543)
- * IRQ3 - reserved for UART B (default set by M1543) (note that
- * the schematics for the DDB Vrc-5476 board seem to
- * indicate that IRQ3 is connected to the DS1386
- * watchdog timer interrupt output so we might have
- * a conflict)
- * IRQ4 - reserved for UART A (default set by M1543)
- * IRQ5 - parallel (default set by M1543)
- * IRQ8 - DS1386 time of day (RTC) interrupt
- * IRQ9 - USB (hardwired in ddb_setup)
- * IRQ10 - PMU (hardwired in ddb_setup)
- * IRQ12 - mouse
- * IRQ14,15 - IDE controller (need to be confirmed, jsun)
- */
-
- /*
- * Assing mouse interrupt to IRQ12
- */
-
- /* Enter configuration mode */
- outb(0x51, M1543_PNP_CONFIG);
- outb(0x23, M1543_PNP_CONFIG);
-
- /* Select logical device 7 (Keyboard) */
- outb(0x07, M1543_PNP_INDEX);
- outb(0x07, M1543_PNP_DATA);
-
- /* Select IRQ12 */
- outb(0x72, M1543_PNP_INDEX);
- outb(0x0c, M1543_PNP_DATA);
-
- /* Leave configration mode */
- outb(0xbb, M1543_PNP_CONFIG);
-
-
- /* Initialize the 8259 PIC in the M1543 */
- i8259_init();
-
- /* Enable the interrupt cascade from M1543 */
- nile4_enable_irq(NILE4_INT_INTC);
-
- /* request io ports */
- if (request_resource(&ioport_resource, &m1543_ioport.m1543_config)
- || request_resource(&ioport_resource, &m1543_ioport.pic_elcr)) {
- printk("m1543_irq_setup : requesting io ports failed.\n");
- for (;;);
- }
-}
-
-static void nile4_irq_setup(void)
-{
- int i;
-
- /* Map all interrupts to CPU int #0 */
- nile4_map_irq_all(0);
-
- /* PCI INTA#-E# must be level triggered */
- nile4_set_pci_irq_level_or_edge(0, 1);
- nile4_set_pci_irq_level_or_edge(1, 1);
- nile4_set_pci_irq_level_or_edge(2, 1);
- nile4_set_pci_irq_level_or_edge(3, 1);
-
- /* PCI INTA#, B#, D# must be active low, INTC# must be active high */
- nile4_set_pci_irq_polarity(0, 0);
- nile4_set_pci_irq_polarity(1, 0);
- nile4_set_pci_irq_polarity(2, 1);
- nile4_set_pci_irq_polarity(3, 0);
-
- for (i = 0; i < 16; i++)
- nile4_clear_irq(i);
-
- /* Enable CPU int #0 */
- nile4_enable_irq_output(0);
-
- /* memory resource acquire in ddb_setup */
-}
-
-
-/*
- * IRQ2 is cascade interrupt to second interrupt controller
- */
-static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL };
-
-
-void disable_irq(unsigned int irq_nr)
-{
- if (is_i8259_irq(irq_nr))
- i8259_disable_irq(irq_nr);
- else
- nile4_disable_irq(irq_to_nile4(irq_nr));
-}
-
-void enable_irq(unsigned int irq_nr)
-{
- if (is_i8259_irq(irq_nr))
- i8259_enable_irq(irq_nr);
- else
- nile4_enable_irq(irq_to_nile4(irq_nr));
-}
-
-int table[16] = { 0, };
-
-void ddb_local0_irqdispatch(struct pt_regs *regs)
-{
- u32 mask;
- int nile4_irq;
-#if 0
- volatile static int nesting = 0;
- if (nesting++ == 0)
- ddb5476_led_d3(1);
- ddb5476_led_hex(nesting < 16 ? nesting : 15);
-#endif
-
- mask = nile4_get_irq_stat(0);
- nile4_clear_irq_mask(mask);
-
- /* Handle the timer interrupt first */
- if (mask & (1 << NILE4_INT_GPT)) {
- nile4_disable_irq(NILE4_INT_GPT);
- do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs);
- nile4_enable_irq(NILE4_INT_GPT);
- mask &= ~(1 << NILE4_INT_GPT);
- }
- for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1)
- if (mask & 1) {
- nile4_disable_irq(nile4_irq);
- if (nile4_irq == NILE4_INT_INTC) {
- int i8259_irq = nile4_i8259_iack();
- i8259_do_irq(i8259_irq, regs);
- } else {
- do_IRQ(nile4_to_irq(nile4_irq), regs);
- }
- nile4_enable_irq(nile4_irq);
- }
-#if 0
- if (--nesting == 0)
- ddb5476_led_d3(0);
- ddb5476_led_hex(nesting < 16 ? nesting : 15);
-#endif
-}
-
-void ddb_local1_irqdispatch(void)
-{
- printk("ddb_local1_irqdispatch called\n");
-}
-
-void ddb_buserror_irq(void)
-{
- printk("ddb_buserror_irq called\n");
-}
-
-void ddb_8254timer_irq(void)
-{
- printk("ddb_8254timer_irq called\n");
-}
-
-void ddb_phantom_irq(unsigned long cause)
-{
- printk("phantom interrupts detected : \n");
- printk("\tcause \t\t0x%08x\n", cause);
- printk("\tcause reg\t0x%08x\n",
- read_32bit_cp0_register(CP0_CAUSE));
- printk("\tstatus reg\t0x%08x\n",
- read_32bit_cp0_register(CP0_STATUS));
-}
-
-void __init ddb_irq_setup(void)
-{
-#ifdef CONFIG_REMOTE_DEBUG
- printk("Wait for gdb client connection ...\n");
- set_debug_traps();
- breakpoint(); /* you may move this line to whereever you want :-) */
-#endif
- i8259_setup_irq(2, &irq2);
-
- nile4_irq_setup();
- m1543_irq_setup();
-
- /* we pin #0 - #4 (no internal timer) */
- change_cp0_status(ST0_IM,
- IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
-
- set_except_vector(0, ddbIRQ);
-}
diff -Nru a/arch/mips/ddb5476/nile4.c b/arch/mips/ddb5476/nile4.c
--- a/arch/mips/ddb5476/nile4.c Tue Feb 5 10:12:45 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,293 +0,0 @@
-/*
- * arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-
-#include
-
-
-/*
- * Physical Device Address Registers
- *
- * Note: 32 bit addressing only!
- */
-void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width,
- int on_memory_bus, int visible)
-{
- u32 maskbits;
- u32 widthbits;
-
- if (pdar > NILE4_BOOTCS || (pdar & 7)) {
- printk("nile4_set_pdar: invalid pdar %d\n", pdar);
- return;
- }
- if (pdar == NILE4_INTCS && size != 0x00200000) {
- printk("nile4_set_pdar: INTCS size must be 2 MB\n");
- return;
- }
- switch (size) {
-#if 0 /* We don't support 4 GB yet */
- case 0x100000000: /* 4 GB */
- maskbits = 4;
- break;
-#endif
- case 0x80000000: /* 2 GB */
- maskbits = 5;
- break;
- case 0x40000000: /* 1 GB */
- maskbits = 6;
- break;
- case 0x20000000: /* 512 MB */
- maskbits = 7;
- break;
- case 0x10000000: /* 256 MB */
- maskbits = 8;
- break;
- case 0x08000000: /* 128 MB */
- maskbits = 9;
- break;
- case 0x04000000: /* 64 MB */
- maskbits = 10;
- break;
- case 0x02000000: /* 32 MB */
- maskbits = 11;
- break;
- case 0x01000000: /* 16 MB */
- maskbits = 12;
- break;
- case 0x00800000: /* 8 MB */
- maskbits = 13;
- break;
- case 0x00400000: /* 4 MB */
- maskbits = 14;
- break;
- case 0x00200000: /* 2 MB */
- maskbits = 15;
- break;
- case 0: /* OFF */
- maskbits = 0;
- break;
- default:
- printk("nile4_set_pdar: unsupported size %p\n",
- (void *) size);
- return;
- }
- switch (width) {
- case 8:
- widthbits = 0;
- break;
- case 16:
- widthbits = 1;
- break;
- case 32:
- widthbits = 2;
- break;
- case 64:
- widthbits = 3;
- break;
- default:
- printk("nile4_set_pdar: unsupported width %d\n", width);
- return;
- }
- nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) |
- (visible ? 0x20 : 0) | (widthbits << 6) |
- (phys & 0xffe00000));
- nile4_out32(pdar + 4, 0);
- /*
- * When programming a PDAR, the register should be read immediately
- * after writing it. This ensures that address decoders are properly
- * configured.
- */
- nile4_in32(pdar);
- nile4_in32(pdar + 4);
-}
-
-
-/*
- * PCI Master Registers
- *
- * Note: 32 bit addressing only!
- */
-void nile4_set_pmr(u32 pmr, u32 type, u32 addr)
-{
- if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) {
- printk("nile4_set_pmr: invalid pmr %d\n", pmr);
- return;
- }
- switch (type) {
- case NILE4_PCICMD_IACK: /* PCI Interrupt Acknowledge */
- case NILE4_PCICMD_IO: /* PCI I/O Space */
- case NILE4_PCICMD_MEM: /* PCI Memory Space */
- case NILE4_PCICMD_CFG: /* PCI Configuration Space */
- break;
- default:
- printk("nile4_set_pmr: invalid type %d\n", type);
- return;
- }
- nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000));
- nile4_out32(pmr + 4, 0);
-}
-
-
-/*
- * Interrupt Programming
- */
-void nile4_map_irq(int nile4_irq, int cpu_irq)
-{
- u32 offset, t;
-
- offset = NILE4_INTCTRL;
- if (nile4_irq >= 8) {
- offset += 4;
- nile4_irq -= 8;
- }
- t = nile4_in32(offset);
- t &= ~(7 << (nile4_irq * 4));
- t |= cpu_irq << (nile4_irq * 4);
- nile4_out32(offset, t);
-}
-
-void nile4_map_irq_all(int cpu_irq)
-{
- u32 all, t;
-
- all = cpu_irq;
- all |= all << 4;
- all |= all << 8;
- all |= all << 16;
- t = nile4_in32(NILE4_INTCTRL);
- t &= 0x88888888;
- t |= all;
- nile4_out32(NILE4_INTCTRL, t);
- t = nile4_in32(NILE4_INTCTRL + 4);
- t &= 0x88888888;
- t |= all;
- nile4_out32(NILE4_INTCTRL + 4, t);
-}
-
-void nile4_enable_irq(int nile4_irq)
-{
- u32 offset, t;
-
- offset = NILE4_INTCTRL;
- if (nile4_irq >= 8) {
- offset += 4;
- nile4_irq -= 8;
- }
- t = nile4_in32(offset);
- t |= 8 << (nile4_irq * 4);
- nile4_out32(offset, t);
-}
-
-void nile4_disable_irq(int nile4_irq)
-{
- u32 offset, t;
-
- offset = NILE4_INTCTRL;
- if (nile4_irq >= 8) {
- offset += 4;
- nile4_irq -= 8;
- }
- t = nile4_in32(offset);
- t &= ~(8 << (nile4_irq * 4));
- nile4_out32(offset, t);
-}
-
-void nile4_disable_irq_all(void)
-{
- nile4_out32(NILE4_INTCTRL, 0);
- nile4_out32(NILE4_INTCTRL + 4, 0);
-}
-
-u16 nile4_get_irq_stat(int cpu_irq)
-{
- return nile4_in16(NILE4_INTSTAT0 + cpu_irq * 2);
-}
-
-void nile4_enable_irq_output(int cpu_irq)
-{
- u32 t;
-
- t = nile4_in32(NILE4_INTSTAT1 + 4);
- t |= 1 << (16 + cpu_irq);
- nile4_out32(NILE4_INTSTAT1, t);
-}
-
-void nile4_disable_irq_output(int cpu_irq)
-{
- u32 t;
-
- t = nile4_in32(NILE4_INTSTAT1 + 4);
- t &= ~(1 << (16 + cpu_irq));
- nile4_out32(NILE4_INTSTAT1, t);
-}
-
-void nile4_set_pci_irq_polarity(int pci_irq, int high)
-{
- u32 t;
-
- t = nile4_in32(NILE4_INTPPES);
- if (high)
- t &= ~(1 << (pci_irq * 2));
- else
- t |= 1 << (pci_irq * 2);
- nile4_out32(NILE4_INTPPES, t);
-}
-
-void nile4_set_pci_irq_level_or_edge(int pci_irq, int level)
-{
- u32 t;
-
- t = nile4_in32(NILE4_INTPPES);
- if (level)
- t |= 2 << (pci_irq * 2);
- else
- t &= ~(2 << (pci_irq * 2));
- nile4_out32(NILE4_INTPPES, t);
-}
-
-void nile4_clear_irq(int nile4_irq)
-{
- nile4_out32(NILE4_INTCLR, 1 << nile4_irq);
-}
-
-void nile4_clear_irq_mask(u32 mask)
-{
- nile4_out32(NILE4_INTCLR, mask);
-}
-
-u8 nile4_i8259_iack(void)
-{
- u8 irq;
-
- /* Set window 0 for interrupt acknowledge */
- nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0);
- irq = *(volatile u8 *) NILE4_PCI_IACK_BASE;
- /* Set window 0 for PCI I/O space */
- nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0);
- return irq;
-}
-
-#if 0
-void nile4_dump_irq_status(void)
-{
- printk("CPUSTAT = %p:%p\n", (void *) nile4_in32(NILE4_CPUSTAT + 4),
- (void *) nile4_in32(NILE4_CPUSTAT));
- printk("INTCTRL = %p:%p\n", (void *) nile4_in32(NILE4_INTCTRL + 4),
- (void *) nile4_in32(NILE4_INTCTRL));
- printk("INTSTAT0 = %p:%p\n",
- (void *) nile4_in32(NILE4_INTSTAT0 + 4),
- (void *) nile4_in32(NILE4_INTSTAT0));
- printk("INTSTAT1 = %p:%p\n",
- (void *) nile4_in32(NILE4_INTSTAT1 + 4),
- (void *) nile4_in32(NILE4_INTSTAT1));
- printk("INTCLR = %p:%p\n", (void *) nile4_in32(NILE4_INTCLR + 4),
- (void *) nile4_in32(NILE4_INTCLR));
- printk("INTPPES = %p:%p\n", (void *) nile4_in32(NILE4_INTPPES + 4),
- (void *) nile4_in32(NILE4_INTPPES));
-}
-#endif
diff -Nru a/arch/mips/ddb5476/pci.c b/arch/mips/ddb5476/pci.c
--- a/arch/mips/ddb5476/pci.c Wed Jun 4 07:34:33 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,430 +0,0 @@
-/*
- * arch/mips/ddb5476/pci.c -- NEC DDB Vrc-5074 PCI access routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Albert Dorofeev
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-static u32 nile4_pre_pci_access0(int slot_num)
-{
- u32 pci_addr = 0;
- u32 virt_addr = NILE4_PCI_CFG_BASE;
-
- /* work around the bug for Vrc5476 */
- if (slot_num == 13)
- return NILE4_BASE + NILE4_PCI_BASE;
-
- /* Set window 1 address 08000000 - 32 bit - 128 MB (PCI config space) */
- nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x08000000, 32, 0,
- 0);
-
- // [jsun] we start scanning from addr:10,
- // with 128M we can go up to addr:26 (slot 16)
- if (slot_num <= 16) {
- virt_addr += 0x00000400 << slot_num;
- } else {
- /* for high slot, we have to set higher PCI base addr */
- pci_addr = 0x00000400 << slot_num;
- }
- nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr);
- return virt_addr;
-}
-
-static void nile4_post_pci_access0(void)
-{
- /*
- * Set window 1 back to address 08000000 - 32 bit - 128 MB
- * (PCI IO space)
- */
- nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE),
- 0x08000000, 32, 1, 1);
- // nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0);
- nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000);
-}
-
-static int nile4_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 * val)
-{
- int status, slot_num, func_num;
- u32 result, base, addr;
-
- if(size == 4) {
- /* Do we need to generate type 1 configure transaction? */
- if (bus->number) {
- /* FIXME - not working yet */
- return PCIBIOS_FUNC_NOT_SUPPORTED;
- /*
- * the largest type 1 configuration addr is 16M,
- * < 256M config space
- */
- slot_num = 0;
- addr = (bus->number << 16) | (devfn < 8) | where | 1;
- } else {
- slot_num = PCI_SLOT(devfn);
- func_num = PCI_FUNC(devfn);
- addr = (func_num << 8) + where;
- }
- base = nile4_pre_pci_access0(slot_num);
- *val = *(volatile u32 *) (base + addr);
- nile4_post_pci_access0();
- return PCIBIOS_SUCCESSFUL;
- }
-
- status = nile4_pci_read(bus, devfn, where & ~3, 4, &result);
- if (status != PCIBIOS_SUCCESSFUL)
- return status;
- switch (size) {
- case 1:
- if (where & 1)
- result >>= 8;
- if (where & 2)
- result >>= 16;
- *val = (u8)(result & 0xff);
- break;
- case 2:
- if (where & 2)
- result >>= 16;
- *val = (u16)(result & 0xffff);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int nile4_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 val)
-{
- int status, slot_num, func_num, shift = 0;
- u32 result, base, addr;
-
- status = nile4_pci_read(bus, devfn, where & ~3, 4, &result);
- if (status != PCIBIOS_SUCCESSFUL)
- return status;
- switch (size) {
- case 1:
- if (where & 2)
- shift += 16;
- if (where & 1)
- shift += 8;
- result &= ~(0xff << shift);
- result |= val << shift;
- break;
- case 2:
- if (where & 2)
- shift += 16;
- result &= ~(0xffff << shift);
- result |= val << shift;
- break;
- case 4:
- /* Do we need to generate type 1 configure transaction? */
- if (bus->number) {
- /* FIXME - not working yet */
- return PCIBIOS_FUNC_NOT_SUPPORTED;
-
- /* the largest type 1 configuration addr is 16M,
- * < 256M config space */
- slot_num = 0;
- addr = (bus->number << 16) | (devfn < 8) |
- where | 1;
- } else {
- slot_num = PCI_SLOT(devfn);
- func_num = PCI_FUNC(devfn);
- addr = (func_num << 8) + where;
- }
-
- base = nile4_pre_pci_access0(slot_num);
- *(volatile u32 *) (base + addr) = val;
- nile4_post_pci_access0();
- return PCIBIOS_SUCCESSFUL;
- }
- return nile4_pci_write(bus, devfn, where & ~3, 4, result);
-}
-
-struct pci_ops nile4_pci_ops = {
- .read = nile4_pci_read,
- .write = nile4_pci_write,
-};
-
-struct {
- struct resource ram;
- struct resource flash;
- struct resource isa_io;
- struct resource pci_io;
- struct resource isa_mem;
- struct resource pci_mem;
- struct resource nile4;
- struct resource boot;
-} ddb5476_resources = {
- // { "RAM", 0x00000000, 0x03ffffff, IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64 },
- {
- "RAM", 0x00000000, 0x03ffffff, IORESOURCE_MEM}, {
- "Flash ROM", 0x04000000, 0x043fffff}, {
- "Nile4 ISA I/O", 0x06000000, 0x060fffff}, {
- "Nile4 PCI I/O", 0x06100000, 0x07ffffff}, {
- "Nile4 ISA mem", 0x08000000, 0x08ffffff, IORESOURCE_MEM}, {
- "Nile4 PCI mem", 0x09000000, 0x0fffffff, IORESOURCE_MEM},
- // { "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64 },
- {
- "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, IORESOURCE_MEM}, {
- "Boot ROM", 0x1fc00000, 0x1fffffff}
-};
-
-struct resource M5229_resources[5] = {
- {"M5229 BAR0", 0x1f0, 0x1f3, IORESOURCE_IO},
- {"M5229 BAR1", 0x3f4, 0x3f7, IORESOURCE_IO},
- {"M5229 BAR2", 0x170, 0x173, IORESOURCE_IO},
- {"M5229 BAR3", 0x374, 0x377, IORESOURCE_IO},
- {"M5229 BAR4", 0xf000, 0xf00f, IORESOURCE_IO}
-};
-
-static void __init ddb5476_pci_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- if (dev->vendor == PCI_VENDOR_ID_NEC &&
- dev->device == PCI_DEVICE_ID_NEC_VRC5476) {
- /*
- * The first 64-bit PCI base register should point to
- * the Nile4 control registers. Unfortunately this
- * isn't the case, so we fix it ourselves. This allows
- * the serial driver to find the UART.
- */
- dev->resource[0] = ddb5476_resources.nile4;
- request_resource(&iomem_resource,
- &dev->resource[0]);
- /*
- * The second 64-bit PCI base register points to the
- * first memory bank. Unfortunately the address is
- * wrong, so we fix it (again).
- */
-
- /* [jsun] We cannot request the resource anymore,
- * because kernel/setup.c has already reserved "System
- * RAM" resource at the same spot.
- * The fundamental problem here is that PCI host
- * controller should not put system RAM mapping in BAR
- * and make subject to PCI resource assignement.
- * Current fix is a total hack. We set parent to 1 so
- * so that PCI resource assignement code is fooled to
- * think the resource is assigned, and will not attempt
- * to mess with it.
- */
- dev->resource[2] = ddb5476_resources.ram;
- if (request_resource(&iomem_resource,
- &dev->resource[2]) ) {
- dev->resource[2].parent = 0x1;
- }
-
- } else if (dev->vendor == PCI_VENDOR_ID_AL
- && dev->device == PCI_DEVICE_ID_AL_M7101) {
- /*
- * It's nice to have the LEDs on the GPIO pins
- * available for debugging
- */
- extern struct pci_dev *pci_pmu;
- u8 t8;
-
- pci_pmu = dev; /* for LEDs D2 and D3 */
- /* Program the lines for LEDs D2 and D3 to output */
- nile4_pci_read(dev->bus, dev->devfn, 0x7d, 1, &t8);
- t8 |= 0xc0;
- nile4_pci_write(dev->bus, dev->devfn, 0x7d, 1, t8);
- /* Turn LEDs D2 and D3 off */
- nile4_pci_read(dev->bus, dev->devfn, 0x7e, 1, &t8);
- t8 |= 0xc0;
- nile4_pci_write(dev->bus, dev->devfn, 0x7e, 1, t8);
- } else if (dev->vendor == PCI_VENDOR_ID_AL &&
- dev->device == 0x5229) {
- int i;
- for (i = 0; i < 5; i++) {
- dev->resource[i] = M5229_resources[i];
- request_resource(&ioport_resource,
- &dev->resource[i]);
- }
- }
- }
-}
-
-static void __init pcibios_fixup_irqs(void)
-{
- struct pci_dev *dev = NULL;
- int slot_num;
-
- while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- slot_num = PCI_SLOT(dev->devfn);
- switch (slot_num) {
- case 3: /* re-programmed to USB */
- dev->irq = 9; /* hard-coded; see irq.c */
- break;
- case 4: /* re-programmed to PMU */
- dev->irq = 10; /* hard-coded; see irq.c */
- break;
- case 6: /* on-board pci-pci bridge */
- dev->irq = 0xff;
- break;
- case 7: /* on-board ether */
- dev->irq = nile4_to_irq(NILE4_INT_INTB);
- break;
- case 8: /* ISA-PCI bridge */
- dev->irq = nile4_to_irq(NILE4_INT_INTC);
- break;
- case 9: /* ext slot #3 */
- dev->irq = nile4_to_irq(NILE4_INT_INTD);
- break;
- case 10: /* ext slot #4 */
- dev->irq = nile4_to_irq(NILE4_INT_INTA);
- break;
- case 13: /* Vrc5476 */
- dev->irq = 0xff;
- break;
- case 14: /* HD controller, M5229 */
- dev->irq = 14;
- break;
- default:
- printk
- ("JSUN : in pcibios_fixup_irqs - unkown slot %d\n",
- slot_num);
- panic
- ("JSUN : in pcibios_fixup_irqs - unkown slot.\n");
- }
- }
-}
-
-void __init pcibios_init(void)
-{
- printk("PCI: Emulate bios initialization \n");
- /* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */
- *(long *) (NILE4_BASE + NILE4_BAR0) = 0x8;
-
- printk("PCI: Probing PCI hardware\n");
- ioport_resource.end = 0x1ffffff; /* 32 MB */
- iomem_resource.end = 0x1fffffff; /* 512 MB */
-
- /* `ram' and `nile4' are requested through the Nile4 pci_dev */
- request_resource(&iomem_resource, &ddb5476_resources.flash);
- request_resource(&iomem_resource, &ddb5476_resources.isa_io);
- request_resource(&iomem_resource, &ddb5476_resources.pci_io);
- request_resource(&iomem_resource, &ddb5476_resources.isa_mem);
- request_resource(&iomem_resource, &ddb5476_resources.pci_mem);
- request_resource(&iomem_resource, &ddb5476_resources.boot);
-
- pci_scan_bus(0, &nile4_pci_ops, NULL);
- ddb5476_pci_fixup();
- pci_assign_unassigned_resources();
- pcibios_fixup_irqs();
-}
-
-void __init pcibios_fixup_bus(struct pci_bus *bus)
-{
- /* [jsun] we don't know how to fix sub-buses yet */
- if (bus->number == 0) {
- bus->resource[1] = &ddb5476_resources.pci_mem;
- }
-}
-
-char *pcibios_setup(char *str)
-{
- return str;
-}
-
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
-{
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-}
-
-#if 0 /* original DDB5074 code */
-void __devinit
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
- struct resource *res)
-{
- /*
- * our caller figure out range by going through the dev structures.
- * I guess this is the place to fix things up if the bus is using a
- * different view of the addressing space.
- */
-
- if (bus->number == 0) {
- ranges->io_start -= bus->resource[0]->start;
- ranges->io_end -= bus->resource[0]->start;
- ranges->mem_start -= bus->resource[1]->start;
- ranges->mem_end -= bus->resource[1]->start;
- }
-}
-#endif
-
-int pcibios_enable_resources(struct pci_dev *dev)
-{
- u16 cmd, old_cmd;
- int idx;
- struct resource *r;
-
- /*
- * Don't touch the Nile 4
- */
- if (dev->vendor == PCI_VENDOR_ID_NEC &&
- dev->device == PCI_DEVICE_ID_NEC_VRC5476) return 0;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- old_cmd = cmd;
- for (idx = 0; idx < 6; idx++) {
- r = &dev->resource[idx];
- if (!r->start && r->end) {
- printk(KERN_ERR "PCI: Device %s not available because "
- "of resource collisions\n", dev->slot_name);
- return -EINVAL;
- }
- if (r->flags & IORESOURCE_IO)
- cmd |= PCI_COMMAND_IO;
- if (r->flags & IORESOURCE_MEM)
- cmd |= PCI_COMMAND_MEMORY;
- }
- if (cmd != old_cmd) {
- printk("PCI: Enabling device %s (%04x -> %04x)\n",
- dev->slot_name, old_cmd, cmd);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
- return 0;
-}
-
-int pcibios_enable_device(struct pci_dev *dev)
-{
- return pcibios_enable_resources(dev);
-}
-
-void pcibios_align_resource(void *data, struct resource *res,
- unsigned long size, unsigned long align)
-{
- struct pci_dev *dev = data;
-
- if (res->flags & IORESOURCE_IO) {
- unsigned long start = res->start;
-
- /* We need to avoid collisions with `mirrored' VGA ports
- and other strange ISA hardware, so we always want the
- addresses kilobyte aligned. */
- if (size > 0x100) {
- printk(KERN_ERR "PCI: I/O Region %s/%d too large"
- " (%ld bytes)\n", dev->slot_name,
- dev->resource - res, size);
- }
-
- start = (start + 1024 - 1) & ~(1024 - 1);
- res->start = start;
- }
-}
-
-unsigned __init int pcibios_assign_all_busses(void)
-{
- return 1;
-}
-
-struct pci_fixup pcibios_fixups[] = { {0} };
diff -Nru a/arch/mips/ddb5476/prom.c b/arch/mips/ddb5476/prom.c
--- a/arch/mips/ddb5476/prom.c Tue Feb 5 10:12:45 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,43 +0,0 @@
-/*
- * arch/mips/ddb5476/prom.c -- NEC DDB Vrc-5476 PROM routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- *
- * Jun Sun - modified for DDB5476.
- */
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-
-char arcs_cmdline[COMMAND_LINE_SIZE];
-
-/* [jsun@junsun.net] PMON passes arguments in C main() style */
-void __init prom_init(int argc, const char **arg)
-{
- int i;
-
- /* arg[0] is "g", the rest is boot parameters */
- arcs_cmdline[0] = '\0';
- for (i = 1; i < argc; i++) {
- if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
- >= sizeof(arcs_cmdline))
- break;
- strcat(arcs_cmdline, arg[i]);
- strcat(arcs_cmdline, " ");
- }
-
- mips_machgroup = MACH_GROUP_NEC_DDB;
- mips_machtype = MACH_NEC_DDB5476;
- /* 64 MB non-upgradable */
- add_memory_region(0, 64 << 20, BOOT_MEM_RAM);
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
diff -Nru a/arch/mips/ddb5476/setup.c b/arch/mips/ddb5476/setup.c
--- a/arch/mips/ddb5476/setup.c Mon Feb 4 23:45:04 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,393 +0,0 @@
-/*
- * arch/mips/ddb5476/setup.c -- NEC DDB Vrc-5476 setup routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-
-#ifdef CONFIG_REMOTE_DEBUG
-extern void rs_kgdb_hook(int);
-extern void breakpoint(void);
-#endif
-
-#if defined(CONFIG_SERIAL_CONSOLE)
-extern void console_setup(char *);
-#endif
-
-extern struct ide_ops std_ide_ops;
-extern struct rtc_ops ddb_rtc_ops;
-extern struct kbd_ops std_kbd_ops;
-
-static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000;
-
-static void ddb_machine_restart(char *command)
-{
- u32 t;
-
- /* PCI cold reset */
- t = nile4_in32(NILE4_PCICTRL + 4);
- t |= 0x40000000;
- nile4_out32(NILE4_PCICTRL + 4, t);
- /* CPU cold reset */
- t = nile4_in32(NILE4_CPUSTAT);
- t |= 1;
- nile4_out32(NILE4_CPUSTAT, t);
- /* Call the PROM */
- back_to_prom();
-}
-
-static void ddb_machine_halt(void)
-{
- printk("DDB Vrc-5476 halted.\n");
- while (1);
-}
-
-static void ddb_machine_power_off(void)
-{
- printk("DDB Vrc-5476 halted. Please turn off the power.\n");
- while (1);
-}
-
-extern void ddb_irq_setup(void);
-
-static void __init ddb_time_init(struct irqaction *irq)
-{
- printk("ddb_time_init invoked.\n");
- mips_counter_frequency = 83000000;
-}
-
-static void __init ddb_timer_setup(struct irqaction *irq)
-{
- unsigned int count;
-
- /* we are using the cpu counter for timer interrupts */
- i8259_setup_irq(0, irq);
- set_cp0_status(IE_IRQ5);
-
- /* to generate the first timer interrupt */
- count = read_32bit_cp0_register(CP0_COUNT);
- write_32bit_cp0_register(CP0_COMPARE, count + 1000);
-
-#if 0 /* the old way to do timer interrupt */
- /* set the clock to 100 Hz */
- nile4_out32(NILE4_T2CTRL, 830000);
- /* enable the General-Purpose Timer */
- nile4_out32(NILE4_T2CTRL + 4, 0x00000001);
- /* reset timer */
- nile4_out32(NILE4_T2CNTR, 0);
- /* enable interrupt */
- nile4_enable_irq(NILE4_INT_GPT);
- i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq);
-#endif
-}
-
-static struct {
- struct resource dma1;
- struct resource pic1;
- struct resource timer;
- struct resource rtc;
- struct resource dma_page_reg;
- struct resource pic2;
- struct resource dma2;
-} ddb5476_ioport = {
- {
- "dma1", 0x00, 0x1f, IORESOURCE_BUSY}, {
- "pic1", 0x20, 0x3f, IORESOURCE_BUSY}, {
- "timer", 0x40, 0x5f, IORESOURCE_BUSY}, {
- "rtc", 0x70, 0x7f, IORESOURCE_BUSY}, {
- "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, {
- "pic2", 0xa0, 0xbf, IORESOURCE_BUSY}, {
- "dma2", 0xc0, 0xdf, IORESOURCE_BUSY}
-};
-
-static struct {
- struct resource nile4;
-} ddb5476_iomem = {
- { "Nile 4", NILE4_BASE, NILE4_BASE + NILE4_SIZE - 1, IORESOURCE_BUSY}
-};
-
-void __init ddb_setup(void)
-{
- extern int panic_timeout;
-
- irq_setup = ddb_irq_setup;
- mips_io_port_base = NILE4_PCI_IO_BASE;
- isa_slot_offset = NILE4_PCI_MEM_BASE;
-
- board_time_init = ddb_time_init;
- board_timer_setup = ddb_timer_setup;
-
- _machine_restart = ddb_machine_restart;
- _machine_halt = ddb_machine_halt;
- _machine_power_off = ddb_machine_power_off;
-
- /* request io port/mem resources */
- if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) ||
- request_resource(&ioport_resource, &ddb5476_ioport.pic1) ||
- request_resource(&ioport_resource, &ddb5476_ioport.timer) ||
- request_resource(&ioport_resource, &ddb5476_ioport.rtc) ||
- request_resource(&ioport_resource,
- &ddb5476_ioport.dma_page_reg)
- || request_resource(&ioport_resource, &ddb5476_ioport.pic2)
- || request_resource(&ioport_resource, &ddb5476_ioport.dma2)
- || request_resource(&iomem_resource, &ddb5476_iomem.nile4)) {
- printk
- ("ddb_setup - requesting oo port resources failed.\n");
- for (;;);
- }
-#ifdef CONFIG_BLK_DEV_IDE
- ide_ops = &std_ide_ops;
-#endif
- rtc_ops = &ddb_rtc_ops;
-
-#ifdef CONFIG_PC_KEYB
- kbd_ops = &std_kbd_ops;
-#endif
-
- /* Reboot on panic */
- panic_timeout = 180;
-
- /* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */
- /* *(long*)0xbfa00218 = 0x8; */
-
-#ifdef CONFIG_FB
- conswitchp = &dummy_con;
-#endif
-
-
- /* board initialization stuff - non-fundamental, but need to be set
- * before kernel runs */
-
- /* setup I/O space */
- nile4_set_pdar(NILE4_PCIW0,
- PHYSADDR(NILE4_PCI_IO_BASE), 0x02000000, 32, 0, 0);
- nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0);
-
- /* map config space to 0xa8000000, 128MB */
- nile4_set_pdar(NILE4_PCIW1,
- PHYSADDR(NILE4_PCI_CFG_BASE), 0x08000000, 32, 0, 0);
- nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, 0x0);
-
- /* ----- M1543 PCI setup ------ */
-
- /* we know M1543 PCI-ISA controller is at addr:18 */
- /* xxxx1010 makes USB at addr:13 and PMU at addr:14 */
- *(volatile unsigned char *) 0xa8040072 &= 0xf0;
- *(volatile unsigned char *) 0xa8040072 |= 0xa;
-
- /* setup USB interrupt to IRQ 9, (bit 0:3 - 0001)
- * no IOCHRDY signal, (bit 7 - 1)
- * M1543C & M7101 VID and Subsys Device ID are read-only (bit 6 - 1)
- * Bypass USB Master INTAJ level to edge conversion (bit 4 - 0)
- */
- *(unsigned char *) 0xa8040074 = 0xc1;
-
- /* setup PMU(SCI to IRQ 10 (bit 0:3 - 0011)
- * SCI routing to IRQ 13 disabled (bit 7 - 1)
- * SCI interrupt level to edge conversion bypassed (bit 4 - 0)
- */
- *(unsigned char *) 0xa8040076 = 0x83;
-
- /* setup IDE controller
- * enable IDE controller (bit 6 - 1)
- * IDE IDSEL to be addr:24 (bit 4:5 - 11)
- * no IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0)
- * no IDE ATA Primary Bus Signal Pad Control (bit 2 - 0)
- * primary IRQ is 14, secondary is 15 (bit 1:0 - 01
- */
- // *(unsigned char*)0xa8040058 = 0x71;
- // *(unsigned char*)0xa8040058 = 0x79;
- // *(unsigned char*)0xa8040058 = 0x74; // use SIRQ, primary tri-state
- *(unsigned char *) 0xa8040058 = 0x75; // primary tri-state
-
-#if 0
- /* this is not necessary if M5229 does not use SIRQ */
- *(unsigned char *) 0xa8040044 = 0x0d; // primary to IRQ 14
- *(unsigned char *) 0xa8040075 = 0x0d; // secondary to IRQ 14
-#endif
-
- /* enable IDE in the M5229 config register 0x50 (bit 0 - 1) */
- /* M5229 IDSEL is addr:24; see above setting */
- *(unsigned char *) 0xa9000050 |= 0x1;
-
- /* enable bus master (bit 2) and IO decoding (bit 0) */
- *(unsigned char *) 0xa9000004 |= 0x5;
-
- /* enable native, copied from arch/ppc/k2boot/head.S */
- /* TODO - need volatile, need to be portable */
- *(unsigned char *) 0xa9000009 = 0xff;
-
- /* ----- end of M1543 PCI setup ------ */
-
- /* ----- reset on-board ether chip ------ */
- *((volatile u32 *) 0xa8020004) |= 1; /* decode I/O */
- *((volatile u32 *) 0xa8020010) = 0; /* set BAR address */
-
- /* send reset command */
- *((volatile u32 *) 0xa6000000) = 1; /* do a soft reset */
-
- /* disable ether chip */
- *((volatile u32 *) 0xa8020004) = 0; /* disable any decoding */
-
- /* put it into sleep */
- *((volatile u32 *) 0xa8020040) = 0x80000000;
-
- /* ----- end of reset on-board ether chip ------ */
-
- /* ----- set pci window 1 to pci memory space -------- */
- nile4_set_pdar(NILE4_PCIW1,
- PHYSADDR(NILE4_PCI_MEM_BASE), 0x08000000, 32, 0, 0);
- // nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0);
- nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000);
-
-}
-
-#define USE_NILE4_SERIAL 0
-
-#if USE_NILE4_SERIAL
-#define ns16550_in(reg) nile4_in8((reg)*8)
-#define ns16550_out(reg, val) nile4_out8((reg)*8, (val))
-#else
-#define NS16550_BASE (NILE4_PCI_IO_BASE+0x03f8)
-static inline u8 ns16550_in(u32 reg)
-{
- return *(volatile u8 *) (NS16550_BASE + reg);
-}
-
-static inline void ns16550_out(u32 reg, u8 val)
-{
- *(volatile u8 *) (NS16550_BASE + reg) = val;
-}
-#endif
-
-#define NS16550_RBR 0
-#define NS16550_THR 0
-#define NS16550_DLL 0
-#define NS16550_IER 1
-#define NS16550_DLM 1
-#define NS16550_FCR 2
-#define NS16550_IIR 2
-#define NS16550_LCR 3
-#define NS16550_MCR 4
-#define NS16550_LSR 5
-#define NS16550_MSR 6
-#define NS16550_SCR 7
-
-#define NS16550_LSR_DR 0x01 /* Data ready */
-#define NS16550_LSR_OE 0x02 /* Overrun */
-#define NS16550_LSR_PE 0x04 /* Parity error */
-#define NS16550_LSR_FE 0x08 /* Framing error */
-#define NS16550_LSR_BI 0x10 /* Break */
-#define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */
-#define NS16550_LSR_TEMT 0x40 /* Xmitter empty */
-#define NS16550_LSR_ERR 0x80 /* Error */
-
-
-void _serinit(void)
-{
-#if USE_NILE4_SERIAL
- ns16550_out(NS16550_LCR, 0x80);
- ns16550_out(NS16550_DLM, 0x00);
- ns16550_out(NS16550_DLL, 0x36); /* 9600 baud */
- ns16550_out(NS16550_LCR, 0x00);
- ns16550_out(NS16550_LCR, 0x03);
- ns16550_out(NS16550_FCR, 0x47);
-#else
- /* done by PMON */
-#endif
-}
-
-void _putc(char c)
-{
- while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
- ns16550_out(NS16550_THR, c);
- if (c == '\n') {
- while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE));
- ns16550_out(NS16550_THR, '\r');
- }
-}
-
-void _puts(const char *s)
-{
- char c;
-
- while ((c = *s++))
- _putc(c);
-}
-
-char _getc(void)
-{
- while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR));
-
- return ns16550_in(NS16550_RBR);
-}
-
-int _testc(void)
-{
- return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0;
-}
-
-
-/*
- * Hexadecimal 7-segment LED
- */
-void ddb5476_led_hex(int hex)
-{
- outb(hex, 0x80);
-}
-
-
-/*
- * LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543
- */
-struct pci_dev *pci_pmu = NULL;
-
-void ddb5476_led_d2(int on)
-{
- u8 t;
-
- if (pci_pmu) {
- pci_read_config_byte(pci_pmu, 0x7e, &t);
- if (on)
- t &= 0x7f;
- else
- t |= 0x80;
- pci_write_config_byte(pci_pmu, 0x7e, t);
- }
-}
-
-void ddb5476_led_d3(int on)
-{
- u8 t;
-
- if (pci_pmu) {
- pci_read_config_byte(pci_pmu, 0x7e, &t);
- if (on)
- t &= 0xbf;
- else
- t |= 0x40;
- pci_write_config_byte(pci_pmu, 0x7e, t);
- }
-}
diff -Nru a/arch/mips/ddb5476/time.c b/arch/mips/ddb5476/time.c
--- a/arch/mips/ddb5476/time.c Tue Feb 5 10:12:45 2002
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/*
- * arch/mips/ddb5074/time.c -- Timer routines
- *
- * Copyright (C) 2000 Geert Uytterhoeven
- * Sony Software Development Center Europe (SDCE), Brussels
- */
-#include
-
-#include
-
-static unsigned char ddb_rtc_read_data(unsigned long addr)
-{
- outb_p(addr, RTC_PORT(0));
- return inb_p(RTC_PORT(1));
-}
-
-static void ddb_rtc_write_data(unsigned char data, unsigned long addr)
-{
- outb_p(addr, RTC_PORT(0));
- outb_p(data, RTC_PORT(1));
-}
-
-static int ddb_rtc_bcd_mode(void)
-{
- return 1;
-}
-
-struct rtc_ops ddb_rtc_ops = {
- ddb_rtc_read_data,
- ddb_rtc_write_data,
- ddb_rtc_bcd_mode
-};
diff -Nru a/arch/mips/ddb5xxx/common/Makefile b/arch/mips/ddb5xxx/common/Makefile
--- a/arch/mips/ddb5xxx/common/Makefile Sat Dec 14 04:38:56 2002
+++ b/arch/mips/ddb5xxx/common/Makefile Mon Apr 14 20:10:12 2003
@@ -2,4 +2,4 @@
# Makefile for the common code of NEC DDB-Vrc5xxx board
#
-obj-y += irq.o irq_cpu.o nile4.o prom.o pci.o pci_auto.o rtc_ds1386.o
+obj-y += irq.o nile4.o prom.o rtc_ds1386.o
diff -Nru a/arch/mips/ddb5xxx/common/irq.c b/arch/mips/ddb5xxx/common/irq.c
--- a/arch/mips/ddb5xxx/common/irq.c Tue Feb 5 12:17:17 2002
+++ b/arch/mips/ddb5xxx/common/irq.c Mon Apr 14 20:10:12 2003
@@ -13,12 +13,13 @@
*/
#include
#include
+#include